blob: 9558376dbfe770ea318a477a5d9707be9e2bece5 [file] [log] [blame]
Dianne Hackborn2b4eff12013-02-12 15:12:21 -08001/*
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
Dianne Hackborn2b4eff12013-02-12 15:12:21 -080021#include <utils/Log.h>
22#include <binder/Parcel.h>
23#include <utils/String8.h>
24
25#include <private/binder/Static.h>
26
27namespace android {
28
29// ----------------------------------------------------------------------
30
31class BpAppOpsService : public BpInterface<IAppOpsService>
32{
33public:
34 BpAppOpsService(const sp<IBinder>& impl)
35 : BpInterface<IAppOpsService>(impl)
36 {
37 }
38
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
Eino-Ville Talvalacc1a24d2013-02-19 12:54:57 -080047 if (reply.readExceptionCode() != 0) return MODE_ERRORED;
48 return reply.readInt32();
Dianne Hackborn2b4eff12013-02-12 15:12:21 -080049 }
50
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
Eino-Ville Talvalacc1a24d2013-02-19 12:54:57 -080059 if (reply.readExceptionCode() != 0) return MODE_ERRORED;
60 return reply.readInt32();
Dianne Hackborn2b4eff12013-02-12 15:12:21 -080061 }
62
Dianne Hackbornd93278e2013-07-17 17:26:15 -070063 virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
64 const String16& packageName) {
Dianne Hackborn2b4eff12013-02-12 15:12:21 -080065 Parcel data, reply;
66 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
Dianne Hackbornd93278e2013-07-17 17:26:15 -070067 data.writeStrongBinder(token);
Dianne Hackborn2b4eff12013-02-12 15:12:21 -080068 data.writeInt32(code);
69 data.writeInt32(uid);
70 data.writeString16(packageName);
71 remote()->transact(START_OPERATION_TRANSACTION, data, &reply);
72 // fail on exception
Eino-Ville Talvalacc1a24d2013-02-19 12:54:57 -080073 if (reply.readExceptionCode() != 0) return MODE_ERRORED;
74 return reply.readInt32();
Dianne Hackborn2b4eff12013-02-12 15:12:21 -080075 }
76
Dianne Hackbornd93278e2013-07-17 17:26:15 -070077 virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
78 const String16& packageName) {
Dianne Hackborn2b4eff12013-02-12 15:12:21 -080079 Parcel data, reply;
80 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
Dianne Hackbornd93278e2013-07-17 17:26:15 -070081 data.writeStrongBinder(token);
Dianne Hackborn2b4eff12013-02-12 15:12:21 -080082 data.writeInt32(code);
83 data.writeInt32(uid);
84 data.writeString16(packageName);
85 remote()->transact(FINISH_OPERATION_TRANSACTION, data, &reply);
86 }
87
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);
Marco Nelissen461a6722014-11-14 08:01:01 -080094 data.writeStrongBinder(IInterface::asBinder(callback));
Dianne Hackborn2b4eff12013-02-12 15:12:21 -080095 remote()->transact(START_WATCHING_MODE_TRANSACTION, data, &reply);
96 }
97
98 virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) {
99 Parcel data, reply;
100 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
Marco Nelissen461a6722014-11-14 08:01:01 -0800101 data.writeStrongBinder(IInterface::asBinder(callback));
Dianne Hackborn2b4eff12013-02-12 15:12:21 -0800102 remote()->transact(STOP_WATCHING_MODE_TRANSACTION, data, &reply);
103 }
Dianne Hackbornd93278e2013-07-17 17:26:15 -0700104
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 }
Svetoslav99a6ab62015-04-29 16:50:41 -0700114
115
116 virtual int32_t permissionToOpCode(const String16& permission) {
117 Parcel data, reply;
118 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
119 data.writeString16(permission);
120 remote()->transact(PERMISSION_TO_OP_CODE_TRANSACTION, data, &reply);
121 // fail on exception
122 if (reply.readExceptionCode() != 0) return -1;
123 return reply.readInt32();
124 }
Dianne Hackborn2b4eff12013-02-12 15:12:21 -0800125};
126
127IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService");
128
129// ----------------------------------------------------------------------
130
131status_t BnAppOpsService::onTransact(
132 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
133{
134 //printf("AppOpsService received: "); data.print();
135 switch(code) {
136 case CHECK_OPERATION_TRANSACTION: {
137 CHECK_INTERFACE(IAppOpsService, data, reply);
138 int32_t code = data.readInt32();
139 int32_t uid = data.readInt32();
140 String16 packageName = data.readString16();
141 int32_t res = checkOperation(code, uid, packageName);
142 reply->writeNoException();
143 reply->writeInt32(res);
144 return NO_ERROR;
145 } break;
146 case NOTE_OPERATION_TRANSACTION: {
147 CHECK_INTERFACE(IAppOpsService, data, reply);
148 int32_t code = data.readInt32();
149 int32_t uid = data.readInt32();
150 String16 packageName = data.readString16();
151 int32_t res = noteOperation(code, uid, packageName);
152 reply->writeNoException();
153 reply->writeInt32(res);
154 return NO_ERROR;
155 } break;
156 case START_OPERATION_TRANSACTION: {
157 CHECK_INTERFACE(IAppOpsService, data, reply);
Dianne Hackbornd93278e2013-07-17 17:26:15 -0700158 sp<IBinder> token = data.readStrongBinder();
Dianne Hackborn2b4eff12013-02-12 15:12:21 -0800159 int32_t code = data.readInt32();
160 int32_t uid = data.readInt32();
161 String16 packageName = data.readString16();
Dianne Hackbornd93278e2013-07-17 17:26:15 -0700162 int32_t res = startOperation(token, code, uid, packageName);
Dianne Hackborn2b4eff12013-02-12 15:12:21 -0800163 reply->writeNoException();
164 reply->writeInt32(res);
165 return NO_ERROR;
166 } break;
167 case FINISH_OPERATION_TRANSACTION: {
168 CHECK_INTERFACE(IAppOpsService, data, reply);
Dianne Hackbornd93278e2013-07-17 17:26:15 -0700169 sp<IBinder> token = data.readStrongBinder();
Dianne Hackborn2b4eff12013-02-12 15:12:21 -0800170 int32_t code = data.readInt32();
171 int32_t uid = data.readInt32();
172 String16 packageName = data.readString16();
Dianne Hackbornd93278e2013-07-17 17:26:15 -0700173 finishOperation(token, code, uid, packageName);
Dianne Hackborn2b4eff12013-02-12 15:12:21 -0800174 reply->writeNoException();
175 return NO_ERROR;
176 } break;
177 case START_WATCHING_MODE_TRANSACTION: {
178 CHECK_INTERFACE(IAppOpsService, data, reply);
179 int32_t op = data.readInt32();
180 String16 packageName = data.readString16();
181 sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
182 startWatchingMode(op, packageName, callback);
183 reply->writeNoException();
184 return NO_ERROR;
185 } break;
186 case STOP_WATCHING_MODE_TRANSACTION: {
187 CHECK_INTERFACE(IAppOpsService, data, reply);
188 sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
189 stopWatchingMode(callback);
190 reply->writeNoException();
191 return NO_ERROR;
192 } break;
Dianne Hackbornd93278e2013-07-17 17:26:15 -0700193 case GET_TOKEN_TRANSACTION: {
194 CHECK_INTERFACE(IAppOpsService, data, reply);
195 sp<IBinder> clientToken = data.readStrongBinder();
196 sp<IBinder> token = getToken(clientToken);
197 reply->writeNoException();
198 reply->writeStrongBinder(token);
199 return NO_ERROR;
200 } break;
Svetoslav99a6ab62015-04-29 16:50:41 -0700201 case PERMISSION_TO_OP_CODE_TRANSACTION: {
202 CHECK_INTERFACE(IAppOpsService, data, reply);
203 String16 permission = data.readString16();
204 const int32_t opCode = permissionToOpCode(permission);
205 reply->writeNoException();
206 reply->writeInt32(opCode);
207 return NO_ERROR;
208 } break;
Dianne Hackborn2b4eff12013-02-12 15:12:21 -0800209 default:
210 return BBinder::onTransact(code, data, reply, flags);
211 }
212}
213
214}; // namespace android