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