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