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 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)63 virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
64 const String16& packageName) {
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 remote()->transact(START_OPERATION_TRANSACTION, data, &reply);
72 // fail on exception
73 if (reply.readExceptionCode() != 0) return MODE_ERRORED;
74 return reply.readInt32();
75 }
76
finishOperation(const sp<IBinder> & token,int32_t code,int32_t uid,const String16 & packageName)77 virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
78 const String16& packageName) {
79 Parcel data, reply;
80 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
81 data.writeStrongBinder(token);
82 data.writeInt32(code);
83 data.writeInt32(uid);
84 data.writeString16(packageName);
85 remote()->transact(FINISH_OPERATION_TRANSACTION, data, &reply);
86 }
87
startWatchingMode(int32_t op,const String16 & packageName,const sp<IAppOpsCallback> & callback)88 virtual void startWatchingMode(int32_t op, const String16& packageName,
89 const sp<IAppOpsCallback>& callback) {
90 Parcel data, reply;
91 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
92 data.writeInt32(op);
93 data.writeString16(packageName);
94 data.writeStrongBinder(callback->asBinder());
95 remote()->transact(START_WATCHING_MODE_TRANSACTION, data, &reply);
96 }
97
stopWatchingMode(const sp<IAppOpsCallback> & callback)98 virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) {
99 Parcel data, reply;
100 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
101 data.writeStrongBinder(callback->asBinder());
102 remote()->transact(STOP_WATCHING_MODE_TRANSACTION, data, &reply);
103 }
104
getToken(const sp<IBinder> & clientToken)105 virtual sp<IBinder> getToken(const sp<IBinder>& clientToken) {
106 Parcel data, reply;
107 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
108 data.writeStrongBinder(clientToken);
109 remote()->transact(GET_TOKEN_TRANSACTION, data, &reply);
110 // fail on exception
111 if (reply.readExceptionCode() != 0) return NULL;
112 return reply.readStrongBinder();
113 }
114 };
115
116 IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService");
117
118 // ----------------------------------------------------------------------
119
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)120 status_t BnAppOpsService::onTransact(
121 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
122 {
123 //printf("AppOpsService received: "); data.print();
124 switch(code) {
125 case CHECK_OPERATION_TRANSACTION: {
126 CHECK_INTERFACE(IAppOpsService, data, reply);
127 int32_t code = data.readInt32();
128 int32_t uid = data.readInt32();
129 String16 packageName = data.readString16();
130 int32_t res = checkOperation(code, uid, packageName);
131 reply->writeNoException();
132 reply->writeInt32(res);
133 return NO_ERROR;
134 } break;
135 case NOTE_OPERATION_TRANSACTION: {
136 CHECK_INTERFACE(IAppOpsService, data, reply);
137 int32_t code = data.readInt32();
138 int32_t uid = data.readInt32();
139 String16 packageName = data.readString16();
140 int32_t res = noteOperation(code, uid, packageName);
141 reply->writeNoException();
142 reply->writeInt32(res);
143 return NO_ERROR;
144 } break;
145 case START_OPERATION_TRANSACTION: {
146 CHECK_INTERFACE(IAppOpsService, data, reply);
147 sp<IBinder> token = data.readStrongBinder();
148 int32_t code = data.readInt32();
149 int32_t uid = data.readInt32();
150 String16 packageName = data.readString16();
151 int32_t res = startOperation(token, code, uid, packageName);
152 reply->writeNoException();
153 reply->writeInt32(res);
154 return NO_ERROR;
155 } break;
156 case FINISH_OPERATION_TRANSACTION: {
157 CHECK_INTERFACE(IAppOpsService, data, reply);
158 sp<IBinder> token = data.readStrongBinder();
159 int32_t code = data.readInt32();
160 int32_t uid = data.readInt32();
161 String16 packageName = data.readString16();
162 finishOperation(token, code, uid, packageName);
163 reply->writeNoException();
164 return NO_ERROR;
165 } break;
166 case START_WATCHING_MODE_TRANSACTION: {
167 CHECK_INTERFACE(IAppOpsService, data, reply);
168 int32_t op = data.readInt32();
169 String16 packageName = data.readString16();
170 sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
171 startWatchingMode(op, packageName, callback);
172 reply->writeNoException();
173 return NO_ERROR;
174 } break;
175 case STOP_WATCHING_MODE_TRANSACTION: {
176 CHECK_INTERFACE(IAppOpsService, data, reply);
177 sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
178 stopWatchingMode(callback);
179 reply->writeNoException();
180 return NO_ERROR;
181 } break;
182 case GET_TOKEN_TRANSACTION: {
183 CHECK_INTERFACE(IAppOpsService, data, reply);
184 sp<IBinder> clientToken = data.readStrongBinder();
185 sp<IBinder> token = getToken(clientToken);
186 reply->writeNoException();
187 reply->writeStrongBinder(token);
188 return NO_ERROR;
189 } break;
190 default:
191 return BBinder::onTransact(code, data, reply, flags);
192 }
193 }
194
195 }; // namespace android
196