1 /*
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
21 #include <binder/Parcel.h>
22 #include <utils/Log.h>
23 #include <utils/String8.h>
24
25 #include <optional>
26
27 namespace android {
28
29 // ----------------------------------------------------------------------
30
31 class BpAppOpsService : public BpInterface<IAppOpsService>
32 {
33 public:
BpAppOpsService(const sp<IBinder> & impl)34 explicit BpAppOpsService(const sp<IBinder>& impl)
35 : BpInterface<IAppOpsService>(impl)
36 {
37 }
38
checkOperation(int32_t code,int32_t uid,const String16 & packageName)39 virtual int32_t checkOperation(int32_t code, int32_t uid, const String16& packageName) {
40 Parcel data, reply;
41 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
42 data.writeInt32(code);
43 data.writeInt32(uid);
44 data.writeString16(packageName);
45 remote()->transact(CHECK_OPERATION_TRANSACTION, data, &reply);
46 // fail on exception
47 if (reply.readExceptionCode() != 0) return MODE_ERRORED;
48 return reply.readInt32();
49 }
50
noteOperation(int32_t code,int32_t uid,const String16 & packageName,const std::optional<String16> & attributionTag,bool shouldCollectAsyncNotedOp,const String16 & message,bool shouldCollectMessage)51 virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName,
52 const std::optional<String16>& attributionTag, bool shouldCollectAsyncNotedOp,
53 const String16& message, bool shouldCollectMessage) {
54 Parcel data, reply;
55 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
56 data.writeInt32(code);
57 data.writeInt32(uid);
58 data.writeString16(packageName);
59 data.writeString16(attributionTag);
60 data.writeBool(shouldCollectAsyncNotedOp);
61 data.writeString16(message);
62 data.writeBool(shouldCollectMessage);
63 remote()->transact(NOTE_OPERATION_TRANSACTION, data, &reply);
64 // fail on exception
65 if (reply.readExceptionCode() != 0) return MODE_ERRORED;
66 // TODO b/184855056: extract to class
67 reply.readInt32();
68 reply.readByte();
69 return reply.readInt32();
70 }
71
startOperation(const sp<IBinder> & token,int32_t code,int32_t uid,const String16 & packageName,const std::optional<String16> & attributionTag,bool startIfModeDefault,bool shouldCollectAsyncNotedOp,const String16 & message,bool shouldCollectMessage)72 virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
73 const String16& packageName, const std::optional<String16>& attributionTag,
74 bool startIfModeDefault, bool shouldCollectAsyncNotedOp, const String16& message,
75 bool shouldCollectMessage) {
76 Parcel data, reply;
77 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
78 data.writeStrongBinder(token);
79 data.writeInt32(code);
80 data.writeInt32(uid);
81 data.writeString16(packageName);
82 data.writeString16(attributionTag);
83 data.writeBool(startIfModeDefault);
84 data.writeBool(shouldCollectAsyncNotedOp);
85 data.writeString16(message);
86 data.writeBool(shouldCollectMessage);
87 remote()->transact(START_OPERATION_TRANSACTION, data, &reply);
88 // fail on exception
89 if (reply.readExceptionCode() != 0) return MODE_ERRORED;
90 // TODO b/184855056: extract to class
91 reply.readInt32();
92 reply.readByte();
93 return reply.readInt32();
94 }
95
finishOperation(const sp<IBinder> & token,int32_t code,int32_t uid,const String16 & packageName,const std::optional<String16> & attributionTag)96 virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
97 const String16& packageName, const std::optional<String16>& attributionTag) {
98 Parcel data, reply;
99 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
100 data.writeStrongBinder(token);
101 data.writeInt32(code);
102 data.writeInt32(uid);
103 data.writeString16(packageName);
104 data.writeString16(attributionTag);
105 remote()->transact(FINISH_OPERATION_TRANSACTION, data, &reply);
106 }
107
startWatchingMode(int32_t op,const String16 & packageName,const sp<IAppOpsCallback> & callback)108 virtual void startWatchingMode(int32_t op, const String16& packageName,
109 const sp<IAppOpsCallback>& callback) {
110 Parcel data, reply;
111 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
112 data.writeInt32(op);
113 data.writeString16(packageName);
114 data.writeStrongBinder(IInterface::asBinder(callback));
115 remote()->transact(START_WATCHING_MODE_TRANSACTION, data, &reply);
116 }
117
stopWatchingMode(const sp<IAppOpsCallback> & callback)118 virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) {
119 Parcel data, reply;
120 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
121 data.writeStrongBinder(IInterface::asBinder(callback));
122 remote()->transact(STOP_WATCHING_MODE_TRANSACTION, data, &reply);
123 }
124
permissionToOpCode(const String16 & permission)125 virtual int32_t permissionToOpCode(const String16& permission) {
126 Parcel data, reply;
127 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
128 data.writeString16(permission);
129 remote()->transact(PERMISSION_TO_OP_CODE_TRANSACTION, data, &reply);
130 // fail on exception
131 if (reply.readExceptionCode() != 0) return -1;
132 return reply.readInt32();
133 }
134
checkAudioOperation(int32_t code,int32_t usage,int32_t uid,const String16 & packageName)135 virtual int32_t checkAudioOperation(int32_t code, int32_t usage,
136 int32_t uid, const String16& packageName) {
137 Parcel data, reply;
138 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
139 data.writeInt32(code);
140 data.writeInt32(usage);
141 data.writeInt32(uid);
142 data.writeString16(packageName);
143 remote()->transact(CHECK_AUDIO_OPERATION_TRANSACTION, data, &reply);
144 // fail on exception
145 if (reply.readExceptionCode() != 0) {
146 return MODE_ERRORED;
147 }
148 return reply.readInt32();
149 }
150
setCameraAudioRestriction(int32_t mode)151 virtual void setCameraAudioRestriction(int32_t mode) {
152 Parcel data, reply;
153 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
154 data.writeInt32(mode);
155 remote()->transact(SET_CAMERA_AUDIO_RESTRICTION_TRANSACTION, data, &reply);
156 }
157
shouldCollectNotes(int32_t opCode)158 virtual bool shouldCollectNotes(int32_t opCode) {
159 Parcel data, reply;
160 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
161 data.writeInt32(opCode);
162 remote()->transact(SHOULD_COLLECT_NOTES_TRANSACTION, data, &reply);
163 // fail on exception
164 if (reply.readExceptionCode() != 0) {
165 return false;
166 }
167 return reply.readBool();
168 }
169
startWatchingModeWithFlags(int32_t op,const String16 & packageName,int32_t flags,const sp<IAppOpsCallback> & callback)170 virtual void startWatchingModeWithFlags(int32_t op, const String16& packageName,
171 int32_t flags, const sp<IAppOpsCallback>& callback) {
172 Parcel data, reply;
173 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
174 data.writeInt32(op);
175 data.writeString16(packageName);
176 data.writeInt32(flags);
177 data.writeStrongBinder(IInterface::asBinder(callback));
178 remote()->transact(START_WATCHING_MODE_WITH_FLAGS_TRANSACTION, data, &reply);
179 }
180 };
181
182 IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService")
183
184 // ----------------------------------------------------------------------
185
186 // NOLINTNEXTLINE(google-default-arguments)
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)187 status_t BnAppOpsService::onTransact(
188 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
189 {
190 //printf("AppOpsService received: "); data.print();
191 switch(code) {
192 case CHECK_OPERATION_TRANSACTION: {
193 CHECK_INTERFACE(IAppOpsService, data, reply);
194 int32_t code = data.readInt32();
195 int32_t uid = data.readInt32();
196 String16 packageName = data.readString16();
197 int32_t res = checkOperation(code, uid, packageName);
198 reply->writeNoException();
199 reply->writeInt32(res);
200 return NO_ERROR;
201 } break;
202 case NOTE_OPERATION_TRANSACTION: {
203 CHECK_INTERFACE(IAppOpsService, data, reply);
204 int32_t code = data.readInt32();
205 int32_t uid = data.readInt32();
206 String16 packageName = data.readString16();
207 std::optional<String16> attributionTag;
208 data.readString16(&attributionTag);
209 bool shouldCollectAsyncNotedOp = data.readBool();
210 String16 message = data.readString16();
211 bool shouldCollectMessage = data.readBool();
212 int32_t res = noteOperation(code, uid, packageName, attributionTag,
213 shouldCollectAsyncNotedOp, message, shouldCollectMessage);
214 reply->writeNoException();
215 reply->writeInt32(res);
216 return NO_ERROR;
217 } break;
218 case START_OPERATION_TRANSACTION: {
219 CHECK_INTERFACE(IAppOpsService, data, reply);
220 sp<IBinder> token = data.readStrongBinder();
221 int32_t code = data.readInt32();
222 int32_t uid = data.readInt32();
223 String16 packageName = data.readString16();
224 std::optional<String16> attributionTag;
225 data.readString16(&attributionTag);
226 bool startIfModeDefault = data.readBool();
227 bool shouldCollectAsyncNotedOp = data.readBool();
228 String16 message = data.readString16();
229 bool shouldCollectMessage = data.readBool();
230 int32_t res = startOperation(token, code, uid, packageName, attributionTag,
231 startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
232 reply->writeNoException();
233 reply->writeInt32(res);
234 return NO_ERROR;
235 } break;
236 case FINISH_OPERATION_TRANSACTION: {
237 CHECK_INTERFACE(IAppOpsService, data, reply);
238 sp<IBinder> token = data.readStrongBinder();
239 int32_t code = data.readInt32();
240 int32_t uid = data.readInt32();
241 String16 packageName = data.readString16();
242 std::optional<String16> attributionTag;
243 data.readString16(&attributionTag);
244 finishOperation(token, code, uid, packageName, attributionTag);
245 reply->writeNoException();
246 return NO_ERROR;
247 } break;
248 case START_WATCHING_MODE_TRANSACTION: {
249 CHECK_INTERFACE(IAppOpsService, data, reply);
250 int32_t op = data.readInt32();
251 String16 packageName = data.readString16();
252 sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
253 startWatchingMode(op, packageName, callback);
254 reply->writeNoException();
255 return NO_ERROR;
256 } break;
257 case STOP_WATCHING_MODE_TRANSACTION: {
258 CHECK_INTERFACE(IAppOpsService, data, reply);
259 sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
260 stopWatchingMode(callback);
261 reply->writeNoException();
262 return NO_ERROR;
263 } break;
264 case PERMISSION_TO_OP_CODE_TRANSACTION: {
265 CHECK_INTERFACE(IAppOpsService, data, reply);
266 String16 permission = data.readString16();
267 const int32_t opCode = permissionToOpCode(permission);
268 reply->writeNoException();
269 reply->writeInt32(opCode);
270 return NO_ERROR;
271 } break;
272 case CHECK_AUDIO_OPERATION_TRANSACTION: {
273 CHECK_INTERFACE(IAppOpsService, data, reply);
274 const int32_t code = data.readInt32();
275 const int32_t usage = data.readInt32();
276 const int32_t uid = data.readInt32();
277 const String16 packageName = data.readString16();
278 const int32_t res = checkAudioOperation(code, usage, uid, packageName);
279 reply->writeNoException();
280 reply->writeInt32(res);
281 return NO_ERROR;
282 } break;
283 case SET_CAMERA_AUDIO_RESTRICTION_TRANSACTION: {
284 CHECK_INTERFACE(IAppOpsService, data, reply);
285 const int32_t mode = data.readInt32();
286 setCameraAudioRestriction(mode);
287 reply->writeNoException();
288 return NO_ERROR;
289 } break;
290 case SHOULD_COLLECT_NOTES_TRANSACTION: {
291 CHECK_INTERFACE(IAppOpsService, data, reply);
292 int32_t opCode = data.readInt32();
293 bool shouldCollect = shouldCollectNotes(opCode);
294 reply->writeNoException();
295 reply->writeBool(shouldCollect);
296 return NO_ERROR;
297 } break;
298 default:
299 return BBinder::onTransact(code, data, reply, flags);
300 }
301 }
302
303 } // namespace android
304