• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <utils/Log.h>
22 #include <binder/Parcel.h>
23 #include <utils/String8.h>
24 
25 #include <private/binder/Static.h>
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)51     virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName) {
52         Parcel data, reply;
53         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
54         data.writeInt32(code);
55         data.writeInt32(uid);
56         data.writeString16(packageName);
57         remote()->transact(NOTE_OPERATION_TRANSACTION, data, &reply);
58         // fail on exception
59         if (reply.readExceptionCode() != 0) return MODE_ERRORED;
60         return reply.readInt32();
61     }
62 
startOperation(const sp<IBinder> & token,int32_t code,int32_t uid,const String16 & packageName,bool startIfModeDefault)63     virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
64                 const String16& packageName, bool startIfModeDefault) {
65         Parcel data, reply;
66         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
67         data.writeStrongBinder(token);
68         data.writeInt32(code);
69         data.writeInt32(uid);
70         data.writeString16(packageName);
71         data.writeInt32(startIfModeDefault ? 1 : 0);
72         remote()->transact(START_OPERATION_TRANSACTION, data, &reply);
73         // fail on exception
74         if (reply.readExceptionCode() != 0) return MODE_ERRORED;
75         return reply.readInt32();
76     }
77 
finishOperation(const sp<IBinder> & token,int32_t code,int32_t uid,const String16 & packageName)78     virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
79             const String16& packageName) {
80         Parcel data, reply;
81         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
82         data.writeStrongBinder(token);
83         data.writeInt32(code);
84         data.writeInt32(uid);
85         data.writeString16(packageName);
86         remote()->transact(FINISH_OPERATION_TRANSACTION, data, &reply);
87     }
88 
startWatchingMode(int32_t op,const String16 & packageName,const sp<IAppOpsCallback> & callback)89     virtual void startWatchingMode(int32_t op, const String16& packageName,
90             const sp<IAppOpsCallback>& callback) {
91         Parcel data, reply;
92         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
93         data.writeInt32(op);
94         data.writeString16(packageName);
95         data.writeStrongBinder(IInterface::asBinder(callback));
96         remote()->transact(START_WATCHING_MODE_TRANSACTION, data, &reply);
97     }
98 
stopWatchingMode(const sp<IAppOpsCallback> & callback)99     virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) {
100         Parcel data, reply;
101         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
102         data.writeStrongBinder(IInterface::asBinder(callback));
103         remote()->transact(STOP_WATCHING_MODE_TRANSACTION, data, &reply);
104     }
105 
getToken(const sp<IBinder> & clientToken)106     virtual sp<IBinder> getToken(const sp<IBinder>& clientToken) {
107         Parcel data, reply;
108         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
109         data.writeStrongBinder(clientToken);
110         remote()->transact(GET_TOKEN_TRANSACTION, data, &reply);
111         // fail on exception
112         if (reply.readExceptionCode() != 0) return nullptr;
113         return reply.readStrongBinder();
114     }
115 
116 
permissionToOpCode(const String16 & permission)117     virtual int32_t permissionToOpCode(const String16& permission) {
118         Parcel data, reply;
119         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
120         data.writeString16(permission);
121         remote()->transact(PERMISSION_TO_OP_CODE_TRANSACTION, data, &reply);
122         // fail on exception
123         if (reply.readExceptionCode() != 0) return -1;
124         return reply.readInt32();
125     }
126 
checkAudioOperation(int32_t code,int32_t usage,int32_t uid,const String16 & packageName)127     virtual int32_t checkAudioOperation(int32_t code, int32_t usage,
128             int32_t uid, const String16& packageName) {
129         Parcel data, reply;
130         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
131         data.writeInt32(code);
132         data.writeInt32(usage);
133         data.writeInt32(uid);
134         data.writeString16(packageName);
135         remote()->transact(CHECK_AUDIO_OPERATION_TRANSACTION, data, &reply);
136         // fail on exception
137         if (reply.readExceptionCode() != 0) {
138             return MODE_ERRORED;
139         }
140         return reply.readInt32();
141     }
142 };
143 
144 IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService");
145 
146 // ----------------------------------------------------------------------
147 
148 // NOLINTNEXTLINE(google-default-arguments)
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)149 status_t BnAppOpsService::onTransact(
150     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
151 {
152     //printf("AppOpsService received: "); data.print();
153     switch(code) {
154         case CHECK_OPERATION_TRANSACTION: {
155             CHECK_INTERFACE(IAppOpsService, data, reply);
156             int32_t code = data.readInt32();
157             int32_t uid = data.readInt32();
158             String16 packageName = data.readString16();
159             int32_t res = checkOperation(code, uid, packageName);
160             reply->writeNoException();
161             reply->writeInt32(res);
162             return NO_ERROR;
163         } break;
164         case NOTE_OPERATION_TRANSACTION: {
165             CHECK_INTERFACE(IAppOpsService, data, reply);
166             int32_t code = data.readInt32();
167             int32_t uid = data.readInt32();
168             String16 packageName = data.readString16();
169             int32_t res = noteOperation(code, uid, packageName);
170             reply->writeNoException();
171             reply->writeInt32(res);
172             return NO_ERROR;
173         } break;
174         case START_OPERATION_TRANSACTION: {
175             CHECK_INTERFACE(IAppOpsService, data, reply);
176             sp<IBinder> token = data.readStrongBinder();
177             int32_t code = data.readInt32();
178             int32_t uid = data.readInt32();
179             String16 packageName = data.readString16();
180             bool startIfModeDefault = data.readInt32() == 1;
181             int32_t res = startOperation(token, code, uid, packageName, startIfModeDefault);
182             reply->writeNoException();
183             reply->writeInt32(res);
184             return NO_ERROR;
185         } break;
186         case FINISH_OPERATION_TRANSACTION: {
187             CHECK_INTERFACE(IAppOpsService, data, reply);
188             sp<IBinder> token = data.readStrongBinder();
189             int32_t code = data.readInt32();
190             int32_t uid = data.readInt32();
191             String16 packageName = data.readString16();
192             finishOperation(token, code, uid, packageName);
193             reply->writeNoException();
194             return NO_ERROR;
195         } break;
196         case START_WATCHING_MODE_TRANSACTION: {
197             CHECK_INTERFACE(IAppOpsService, data, reply);
198             int32_t op = data.readInt32();
199             String16 packageName = data.readString16();
200             sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
201             startWatchingMode(op, packageName, callback);
202             reply->writeNoException();
203             return NO_ERROR;
204         } break;
205         case STOP_WATCHING_MODE_TRANSACTION: {
206             CHECK_INTERFACE(IAppOpsService, data, reply);
207             sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
208             stopWatchingMode(callback);
209             reply->writeNoException();
210             return NO_ERROR;
211         } break;
212         case GET_TOKEN_TRANSACTION: {
213             CHECK_INTERFACE(IAppOpsService, data, reply);
214             sp<IBinder> clientToken = data.readStrongBinder();
215             sp<IBinder> token = getToken(clientToken);
216             reply->writeNoException();
217             reply->writeStrongBinder(token);
218             return NO_ERROR;
219         } break;
220         case PERMISSION_TO_OP_CODE_TRANSACTION: {
221             CHECK_INTERFACE(IAppOpsService, data, reply);
222             String16 permission = data.readString16();
223             const int32_t opCode = permissionToOpCode(permission);
224             reply->writeNoException();
225             reply->writeInt32(opCode);
226             return NO_ERROR;
227         } break;
228         case CHECK_AUDIO_OPERATION_TRANSACTION: {
229             CHECK_INTERFACE(IAppOpsService, data, reply);
230             const int32_t code = data.readInt32();
231             const int32_t usage = data.readInt32();
232             const int32_t uid = data.readInt32();
233             const String16 packageName = data.readString16();
234             const int32_t res = checkAudioOperation(code, usage, uid, packageName);
235             reply->writeNoException();
236             reply->writeInt32(res);
237             return NO_ERROR;
238         } break;
239         default:
240             return BBinder::onTransact(code, data, reply, flags);
241     }
242 }
243 
244 }; // namespace android
245