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 };
170 
171 IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService")
172 
173 // ----------------------------------------------------------------------
174 
175 // NOLINTNEXTLINE(google-default-arguments)
176 status_t BnAppOpsService::onTransact(
177     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
178 {
179     //printf("AppOpsService received: "); data.print();
180     switch(code) {
181         case CHECK_OPERATION_TRANSACTION: {
182             CHECK_INTERFACE(IAppOpsService, data, reply);
183             int32_t code = data.readInt32();
184             int32_t uid = data.readInt32();
185             String16 packageName = data.readString16();
186             int32_t res = checkOperation(code, uid, packageName);
187             reply->writeNoException();
188             reply->writeInt32(res);
189             return NO_ERROR;
190         } break;
191         case NOTE_OPERATION_TRANSACTION: {
192             CHECK_INTERFACE(IAppOpsService, data, reply);
193             int32_t code = data.readInt32();
194             int32_t uid = data.readInt32();
195             String16 packageName = data.readString16();
196             std::optional<String16> attributionTag;
197             data.readString16(&attributionTag);
198             bool shouldCollectAsyncNotedOp = data.readBool();
199             String16 message = data.readString16();
200             bool shouldCollectMessage = data.readBool();
201             int32_t res = noteOperation(code, uid, packageName, attributionTag,
202                     shouldCollectAsyncNotedOp, message, shouldCollectMessage);
203             reply->writeNoException();
204             reply->writeInt32(res);
205             return NO_ERROR;
206         } break;
207         case START_OPERATION_TRANSACTION: {
208             CHECK_INTERFACE(IAppOpsService, data, reply);
209             sp<IBinder> token = data.readStrongBinder();
210             int32_t code = data.readInt32();
211             int32_t uid = data.readInt32();
212             String16 packageName = data.readString16();
213             std::optional<String16> attributionTag;
214             data.readString16(&attributionTag);
215             bool startIfModeDefault = data.readBool();
216             bool shouldCollectAsyncNotedOp = data.readBool();
217             String16 message = data.readString16();
218             bool shouldCollectMessage = data.readBool();
219             int32_t res = startOperation(token, code, uid, packageName, attributionTag,
220                     startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
221             reply->writeNoException();
222             reply->writeInt32(res);
223             return NO_ERROR;
224         } break;
225         case FINISH_OPERATION_TRANSACTION: {
226             CHECK_INTERFACE(IAppOpsService, data, reply);
227             sp<IBinder> token = data.readStrongBinder();
228             int32_t code = data.readInt32();
229             int32_t uid = data.readInt32();
230             String16 packageName = data.readString16();
231             std::optional<String16> attributionTag;
232             data.readString16(&attributionTag);
233             finishOperation(token, code, uid, packageName, attributionTag);
234             reply->writeNoException();
235             return NO_ERROR;
236         } break;
237         case START_WATCHING_MODE_TRANSACTION: {
238             CHECK_INTERFACE(IAppOpsService, data, reply);
239             int32_t op = data.readInt32();
240             String16 packageName = data.readString16();
241             sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
242             startWatchingMode(op, packageName, callback);
243             reply->writeNoException();
244             return NO_ERROR;
245         } break;
246         case STOP_WATCHING_MODE_TRANSACTION: {
247             CHECK_INTERFACE(IAppOpsService, data, reply);
248             sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
249             stopWatchingMode(callback);
250             reply->writeNoException();
251             return NO_ERROR;
252         } break;
253         case PERMISSION_TO_OP_CODE_TRANSACTION: {
254             CHECK_INTERFACE(IAppOpsService, data, reply);
255             String16 permission = data.readString16();
256             const int32_t opCode = permissionToOpCode(permission);
257             reply->writeNoException();
258             reply->writeInt32(opCode);
259             return NO_ERROR;
260         } break;
261         case CHECK_AUDIO_OPERATION_TRANSACTION: {
262             CHECK_INTERFACE(IAppOpsService, data, reply);
263             const int32_t code = data.readInt32();
264             const int32_t usage = data.readInt32();
265             const int32_t uid = data.readInt32();
266             const String16 packageName = data.readString16();
267             const int32_t res = checkAudioOperation(code, usage, uid, packageName);
268             reply->writeNoException();
269             reply->writeInt32(res);
270             return NO_ERROR;
271         } break;
272         case SET_CAMERA_AUDIO_RESTRICTION_TRANSACTION: {
273             CHECK_INTERFACE(IAppOpsService, data, reply);
274             const int32_t mode = data.readInt32();
275             setCameraAudioRestriction(mode);
276             reply->writeNoException();
277             return NO_ERROR;
278         } break;
279         case SHOULD_COLLECT_NOTES_TRANSACTION: {
280             CHECK_INTERFACE(IAppOpsService, data, reply);
281             int32_t opCode = data.readInt32();
282             bool shouldCollect = shouldCollectNotes(opCode);
283             reply->writeNoException();
284             reply->writeBool(shouldCollect);
285             return NO_ERROR;
286         } break;
287         default:
288             return BBinder::onTransact(code, data, reply, flags);
289     }
290 }
291 
292 } // namespace android
293