blob: b6360cbffddfd396f0d82710dae644b32502eb2e [file] [log] [blame]
Dianne Hackborn5da5ca52013-02-12 15:12:21 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "AppOpsService"
18
19#include <binder/IAppOpsService.h>
20
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080021#include <utils/Log.h>
22#include <binder/Parcel.h>
23#include <utils/String8.h>
24
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080025namespace android {
26
27// ----------------------------------------------------------------------
28
29class BpAppOpsService : public BpInterface<IAppOpsService>
30{
31public:
Chih-Hung Hsiehe2347b72016-04-25 15:41:05 -070032 explicit BpAppOpsService(const sp<IBinder>& impl)
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080033 : BpInterface<IAppOpsService>(impl)
34 {
35 }
36
Philip P. Moltmann66a87772019-06-24 16:30:00 -070037#ifndef __ANDROID_VNDK__
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080038 virtual int32_t checkOperation(int32_t code, int32_t uid, const String16& packageName) {
39 Parcel data, reply;
40 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
41 data.writeInt32(code);
42 data.writeInt32(uid);
43 data.writeString16(packageName);
44 remote()->transact(CHECK_OPERATION_TRANSACTION, data, &reply);
45 // fail on exception
Eino-Ville Talvalae88a85e2013-02-19 12:54:57 -080046 if (reply.readExceptionCode() != 0) return MODE_ERRORED;
47 return reply.readInt32();
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080048 }
49
50 virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName) {
51 Parcel data, reply;
52 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
53 data.writeInt32(code);
54 data.writeInt32(uid);
55 data.writeString16(packageName);
56 remote()->transact(NOTE_OPERATION_TRANSACTION, data, &reply);
57 // fail on exception
Eino-Ville Talvalae88a85e2013-02-19 12:54:57 -080058 if (reply.readExceptionCode() != 0) return MODE_ERRORED;
59 return reply.readInt32();
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080060 }
61
Dianne Hackborn913b63d2013-07-17 17:26:15 -070062 virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
Svet Ganov616554c2018-02-26 13:27:26 -080063 const String16& packageName, bool startIfModeDefault) {
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080064 Parcel data, reply;
65 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
Dianne Hackborn913b63d2013-07-17 17:26:15 -070066 data.writeStrongBinder(token);
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080067 data.writeInt32(code);
68 data.writeInt32(uid);
69 data.writeString16(packageName);
Svet Ganov616554c2018-02-26 13:27:26 -080070 data.writeInt32(startIfModeDefault ? 1 : 0);
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080071 remote()->transact(START_OPERATION_TRANSACTION, data, &reply);
72 // fail on exception
Eino-Ville Talvalae88a85e2013-02-19 12:54:57 -080073 if (reply.readExceptionCode() != 0) return MODE_ERRORED;
74 return reply.readInt32();
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080075 }
76
Dianne Hackborn913b63d2013-07-17 17:26:15 -070077 virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
78 const String16& packageName) {
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080079 Parcel data, reply;
80 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
Dianne Hackborn913b63d2013-07-17 17:26:15 -070081 data.writeStrongBinder(token);
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080082 data.writeInt32(code);
83 data.writeInt32(uid);
84 data.writeString16(packageName);
85 remote()->transact(FINISH_OPERATION_TRANSACTION, data, &reply);
86 }
87
88 virtual void startWatchingMode(int32_t op, const String16& packageName,
89 const sp<IAppOpsCallback>& callback) {
90 Parcel data, reply;
91 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
92 data.writeInt32(op);
93 data.writeString16(packageName);
Marco Nelissen2ea926b2014-11-14 08:01:01 -080094 data.writeStrongBinder(IInterface::asBinder(callback));
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080095 remote()->transact(START_WATCHING_MODE_TRANSACTION, data, &reply);
96 }
97
98 virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) {
99 Parcel data, reply;
100 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
Marco Nelissen2ea926b2014-11-14 08:01:01 -0800101 data.writeStrongBinder(IInterface::asBinder(callback));
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800102 remote()->transact(STOP_WATCHING_MODE_TRANSACTION, data, &reply);
103 }
Dianne Hackborn913b63d2013-07-17 17:26:15 -0700104
105 virtual sp<IBinder> getToken(const sp<IBinder>& clientToken) {
106 Parcel data, reply;
107 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
108 data.writeStrongBinder(clientToken);
109 remote()->transact(GET_TOKEN_TRANSACTION, data, &reply);
110 // fail on exception
Yi Kongfdd8da92018-06-07 17:52:27 -0700111 if (reply.readExceptionCode() != 0) return nullptr;
Dianne Hackborn913b63d2013-07-17 17:26:15 -0700112 return reply.readStrongBinder();
113 }
Svetoslavb412f6e2015-04-29 16:50:41 -0700114
Svetoslavb412f6e2015-04-29 16:50:41 -0700115 virtual int32_t permissionToOpCode(const String16& permission) {
116 Parcel data, reply;
117 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
118 data.writeString16(permission);
119 remote()->transact(PERMISSION_TO_OP_CODE_TRANSACTION, data, &reply);
120 // fail on exception
121 if (reply.readExceptionCode() != 0) return -1;
122 return reply.readInt32();
123 }
Jean-Michel Trivi94a566d2019-02-25 12:16:02 -0800124
125 virtual int32_t checkAudioOperation(int32_t code, int32_t usage,
126 int32_t uid, const String16& packageName) {
127 Parcel data, reply;
128 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
129 data.writeInt32(code);
130 data.writeInt32(usage);
131 data.writeInt32(uid);
132 data.writeString16(packageName);
133 remote()->transact(CHECK_AUDIO_OPERATION_TRANSACTION, data, &reply);
134 // fail on exception
135 if (reply.readExceptionCode() != 0) {
136 return MODE_ERRORED;
137 }
138 return reply.readInt32();
139 }
Philip P. Moltmann66a87772019-06-24 16:30:00 -0700140
Yin-Chia Yeh8e95ee82019-08-13 12:24:25 -0700141 virtual void setCameraAudioRestriction(int32_t mode) {
142 Parcel data, reply;
143 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
144 data.writeInt32(mode);
145 remote()->transact(SET_CAMERA_AUDIO_RESTRICTION_TRANSACTION, data, &reply);
146 }
147
Philip P. Moltmann66a87772019-06-24 16:30:00 -0700148#endif
149 virtual void noteAsyncOp(const String16& callingPackageName, int32_t uid,
150 const String16& packageName, int32_t opCode, const String16& message) {
151 Parcel data, reply;
152 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
153
154 // Convert empty callingPackage into null string
155 if (callingPackageName.size() != 0) {
156 data.writeString16(callingPackageName);
157 } else {
158 data.writeString16(nullptr, 0);
159 }
160
161 data.writeInt32(uid);
162
163 // Convert empty packageName into null string
164 if (packageName.size() != 0) {
165 data.writeString16(packageName);
166 } else {
167 data.writeString16(nullptr, 0);
168 }
169
170 data.writeInt32(opCode);
171 data.writeString16(message);
172 remote()->transact(NOTE_ASYNC_OP_TRANSACTION, data, &reply);
173 }
174
175 virtual bool shouldCollectNotes(int32_t opCode) {
176 Parcel data, reply;
177 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
178 data.writeInt32(opCode);
179 remote()->transact(SHOULD_COLLECT_NOTES_TRANSACTION, data, &reply);
180 // fail on exception
181 if (reply.readExceptionCode() != 0) {
182 return false;
183 }
184 return reply.readBool();
185 }
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800186};
187
188IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService");
189
190// ----------------------------------------------------------------------
191
Jiyong Parkb86c8662018-10-29 23:01:57 +0900192// NOLINTNEXTLINE(google-default-arguments)
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800193status_t BnAppOpsService::onTransact(
194 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
195{
196 //printf("AppOpsService received: "); data.print();
197 switch(code) {
Philip P. Moltmann66a87772019-06-24 16:30:00 -0700198#ifndef __ANDROID_VNDK__
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800199 case CHECK_OPERATION_TRANSACTION: {
200 CHECK_INTERFACE(IAppOpsService, data, reply);
201 int32_t code = data.readInt32();
202 int32_t uid = data.readInt32();
203 String16 packageName = data.readString16();
204 int32_t res = checkOperation(code, uid, packageName);
205 reply->writeNoException();
206 reply->writeInt32(res);
207 return NO_ERROR;
208 } break;
209 case NOTE_OPERATION_TRANSACTION: {
210 CHECK_INTERFACE(IAppOpsService, data, reply);
211 int32_t code = data.readInt32();
212 int32_t uid = data.readInt32();
213 String16 packageName = data.readString16();
214 int32_t res = noteOperation(code, uid, packageName);
215 reply->writeNoException();
216 reply->writeInt32(res);
217 return NO_ERROR;
218 } break;
219 case START_OPERATION_TRANSACTION: {
220 CHECK_INTERFACE(IAppOpsService, data, reply);
Dianne Hackborn913b63d2013-07-17 17:26:15 -0700221 sp<IBinder> token = data.readStrongBinder();
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800222 int32_t code = data.readInt32();
223 int32_t uid = data.readInt32();
224 String16 packageName = data.readString16();
Svet Ganov616554c2018-02-26 13:27:26 -0800225 bool startIfModeDefault = data.readInt32() == 1;
226 int32_t res = startOperation(token, code, uid, packageName, startIfModeDefault);
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800227 reply->writeNoException();
228 reply->writeInt32(res);
229 return NO_ERROR;
230 } break;
231 case FINISH_OPERATION_TRANSACTION: {
232 CHECK_INTERFACE(IAppOpsService, data, reply);
Dianne Hackborn913b63d2013-07-17 17:26:15 -0700233 sp<IBinder> token = data.readStrongBinder();
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800234 int32_t code = data.readInt32();
235 int32_t uid = data.readInt32();
236 String16 packageName = data.readString16();
Dianne Hackborn913b63d2013-07-17 17:26:15 -0700237 finishOperation(token, code, uid, packageName);
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800238 reply->writeNoException();
239 return NO_ERROR;
240 } break;
241 case START_WATCHING_MODE_TRANSACTION: {
242 CHECK_INTERFACE(IAppOpsService, data, reply);
243 int32_t op = data.readInt32();
244 String16 packageName = data.readString16();
245 sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
246 startWatchingMode(op, packageName, callback);
247 reply->writeNoException();
248 return NO_ERROR;
249 } break;
250 case STOP_WATCHING_MODE_TRANSACTION: {
251 CHECK_INTERFACE(IAppOpsService, data, reply);
252 sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
253 stopWatchingMode(callback);
254 reply->writeNoException();
255 return NO_ERROR;
256 } break;
Dianne Hackborn913b63d2013-07-17 17:26:15 -0700257 case GET_TOKEN_TRANSACTION: {
258 CHECK_INTERFACE(IAppOpsService, data, reply);
259 sp<IBinder> clientToken = data.readStrongBinder();
260 sp<IBinder> token = getToken(clientToken);
261 reply->writeNoException();
262 reply->writeStrongBinder(token);
263 return NO_ERROR;
264 } break;
Svetoslavb412f6e2015-04-29 16:50:41 -0700265 case PERMISSION_TO_OP_CODE_TRANSACTION: {
266 CHECK_INTERFACE(IAppOpsService, data, reply);
267 String16 permission = data.readString16();
268 const int32_t opCode = permissionToOpCode(permission);
269 reply->writeNoException();
270 reply->writeInt32(opCode);
271 return NO_ERROR;
272 } break;
Jean-Michel Trivi94a566d2019-02-25 12:16:02 -0800273 case CHECK_AUDIO_OPERATION_TRANSACTION: {
274 CHECK_INTERFACE(IAppOpsService, data, reply);
275 const int32_t code = data.readInt32();
276 const int32_t usage = data.readInt32();
277 const int32_t uid = data.readInt32();
278 const String16 packageName = data.readString16();
279 const int32_t res = checkAudioOperation(code, usage, uid, packageName);
280 reply->writeNoException();
281 reply->writeInt32(res);
282 return NO_ERROR;
283 } break;
Yin-Chia Yeh8e95ee82019-08-13 12:24:25 -0700284 case SET_CAMERA_AUDIO_RESTRICTION_TRANSACTION: {
285 CHECK_INTERFACE(IAppOpsService, data, reply);
286 const int32_t mode = data.readInt32();
287 setCameraAudioRestriction(mode);
288 reply->writeNoException();
289 return NO_ERROR;
290 } break;
Philip P. Moltmann66a87772019-06-24 16:30:00 -0700291#endif // __ANDROID_VNDK__
292 case NOTE_ASYNC_OP_TRANSACTION: {
293 CHECK_INTERFACE(IAppOpsService, data, reply);
294 String16 callingPackageName = data.readString16();
295 int32_t uid = data.readInt32();
296 String16 packageName = data.readString16();
297 int32_t opCode = data.readInt32();
298 String16 message = data.readString16();
299 noteAsyncOp(callingPackageName, uid, packageName, opCode, message);
300 reply->writeNoException();
301 return NO_ERROR;
302 } break;
303 case SHOULD_COLLECT_NOTES_TRANSACTION: {
304 CHECK_INTERFACE(IAppOpsService, data, reply);
305 int32_t opCode = data.readInt32();
306 bool shouldCollect = shouldCollectNotes(opCode);
307 reply->writeNoException();
308 reply->writeBool(shouldCollect);
309 return NO_ERROR;
310 } break;
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800311 default:
312 return BBinder::onTransact(code, data, reply, flags);
313 }
314}
315
316}; // namespace android