blob: 471e3e993e028535decb4ed0f4eb0d790a8e20e4 [file] [log] [blame]
Dianne Hackborn5da5ca52013-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
21#include <utils/Debug.h>
22#include <utils/Log.h>
23#include <binder/Parcel.h>
24#include <utils/String8.h>
25
26#include <private/binder/Static.h>
27
28namespace android {
29
30// ----------------------------------------------------------------------
31
32class BpAppOpsService : public BpInterface<IAppOpsService>
33{
34public:
35 BpAppOpsService(const sp<IBinder>& impl)
36 : BpInterface<IAppOpsService>(impl)
37 {
38 }
39
40 virtual int32_t checkOperation(int32_t code, int32_t uid, const String16& packageName) {
41 Parcel data, reply;
42 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
43 data.writeInt32(code);
44 data.writeInt32(uid);
45 data.writeString16(packageName);
46 remote()->transact(CHECK_OPERATION_TRANSACTION, data, &reply);
47 // fail on exception
Eino-Ville Talvalae88a85e2013-02-19 12:54:57 -080048 if (reply.readExceptionCode() != 0) return MODE_ERRORED;
49 return reply.readInt32();
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080050 }
51
52 virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName) {
53 Parcel data, reply;
54 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
55 data.writeInt32(code);
56 data.writeInt32(uid);
57 data.writeString16(packageName);
58 remote()->transact(NOTE_OPERATION_TRANSACTION, data, &reply);
59 // fail on exception
Eino-Ville Talvalae88a85e2013-02-19 12:54:57 -080060 if (reply.readExceptionCode() != 0) return MODE_ERRORED;
61 return reply.readInt32();
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080062 }
63
Dianne Hackborn913b63d2013-07-17 17:26:15 -070064 virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
65 const String16& packageName) {
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080066 Parcel data, reply;
67 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
Dianne Hackborn913b63d2013-07-17 17:26:15 -070068 data.writeStrongBinder(token);
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080069 data.writeInt32(code);
70 data.writeInt32(uid);
71 data.writeString16(packageName);
72 remote()->transact(START_OPERATION_TRANSACTION, data, &reply);
73 // fail on exception
Eino-Ville Talvalae88a85e2013-02-19 12:54:57 -080074 if (reply.readExceptionCode() != 0) return MODE_ERRORED;
75 return reply.readInt32();
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080076 }
77
Dianne Hackborn913b63d2013-07-17 17:26:15 -070078 virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
79 const String16& packageName) {
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080080 Parcel data, reply;
81 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
Dianne Hackborn913b63d2013-07-17 17:26:15 -070082 data.writeStrongBinder(token);
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080083 data.writeInt32(code);
84 data.writeInt32(uid);
85 data.writeString16(packageName);
86 remote()->transact(FINISH_OPERATION_TRANSACTION, data, &reply);
87 }
88
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(callback->asBinder());
96 remote()->transact(START_WATCHING_MODE_TRANSACTION, data, &reply);
97 }
98
99 virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) {
100 Parcel data, reply;
101 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
102 data.writeStrongBinder(callback->asBinder());
103 remote()->transact(STOP_WATCHING_MODE_TRANSACTION, data, &reply);
104 }
Dianne Hackborn913b63d2013-07-17 17:26:15 -0700105
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 NULL;
113 return reply.readStrongBinder();
114 }
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800115};
116
117IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService");
118
119// ----------------------------------------------------------------------
120
121status_t BnAppOpsService::onTransact(
122 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
123{
124 //printf("AppOpsService received: "); data.print();
125 switch(code) {
126 case CHECK_OPERATION_TRANSACTION: {
127 CHECK_INTERFACE(IAppOpsService, data, reply);
128 int32_t code = data.readInt32();
129 int32_t uid = data.readInt32();
130 String16 packageName = data.readString16();
131 int32_t res = checkOperation(code, uid, packageName);
132 reply->writeNoException();
133 reply->writeInt32(res);
134 return NO_ERROR;
135 } break;
136 case NOTE_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 = noteOperation(code, uid, packageName);
142 reply->writeNoException();
143 reply->writeInt32(res);
144 return NO_ERROR;
145 } break;
146 case START_OPERATION_TRANSACTION: {
147 CHECK_INTERFACE(IAppOpsService, data, reply);
Dianne Hackborn913b63d2013-07-17 17:26:15 -0700148 sp<IBinder> token = data.readStrongBinder();
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800149 int32_t code = data.readInt32();
150 int32_t uid = data.readInt32();
151 String16 packageName = data.readString16();
Dianne Hackborn913b63d2013-07-17 17:26:15 -0700152 int32_t res = startOperation(token, code, uid, packageName);
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800153 reply->writeNoException();
154 reply->writeInt32(res);
155 return NO_ERROR;
156 } break;
157 case FINISH_OPERATION_TRANSACTION: {
158 CHECK_INTERFACE(IAppOpsService, data, reply);
Dianne Hackborn913b63d2013-07-17 17:26:15 -0700159 sp<IBinder> token = data.readStrongBinder();
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800160 int32_t code = data.readInt32();
161 int32_t uid = data.readInt32();
162 String16 packageName = data.readString16();
Dianne Hackborn913b63d2013-07-17 17:26:15 -0700163 finishOperation(token, code, uid, packageName);
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800164 reply->writeNoException();
165 return NO_ERROR;
166 } break;
167 case START_WATCHING_MODE_TRANSACTION: {
168 CHECK_INTERFACE(IAppOpsService, data, reply);
169 int32_t op = data.readInt32();
170 String16 packageName = data.readString16();
171 sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
172 startWatchingMode(op, packageName, callback);
173 reply->writeNoException();
174 return NO_ERROR;
175 } break;
176 case STOP_WATCHING_MODE_TRANSACTION: {
177 CHECK_INTERFACE(IAppOpsService, data, reply);
178 sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
179 stopWatchingMode(callback);
180 reply->writeNoException();
181 return NO_ERROR;
182 } break;
Dianne Hackborn913b63d2013-07-17 17:26:15 -0700183 case GET_TOKEN_TRANSACTION: {
184 CHECK_INTERFACE(IAppOpsService, data, reply);
185 sp<IBinder> clientToken = data.readStrongBinder();
186 sp<IBinder> token = getToken(clientToken);
187 reply->writeNoException();
188 reply->writeStrongBinder(token);
189 return NO_ERROR;
190 } break;
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800191 default:
192 return BBinder::onTransact(code, data, reply, flags);
193 }
194}
195
196}; // namespace android