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: 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 47 if (reply.readExceptionCode() != 0) return MODE_ERRORED; 48 return reply.readInt32(); 49 } 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 59 if (reply.readExceptionCode() != 0) return MODE_ERRORED; 60 return reply.readInt32(); 61 } 62 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 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 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(IInterface::asBinder(callback)); 95 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()); 101 data.writeStrongBinder(IInterface::asBinder(callback)); 102 remote()->transact(STOP_WATCHING_MODE_TRANSACTION, data, &reply); 103 } 104 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 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 } 125 }; 126 127 IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService"); 128 129 // ---------------------------------------------------------------------- 130 131 status_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); 158 sp<IBinder> token = data.readStrongBinder(); 159 int32_t code = data.readInt32(); 160 int32_t uid = data.readInt32(); 161 String16 packageName = data.readString16(); 162 int32_t res = startOperation(token, code, uid, packageName); 163 reply->writeNoException(); 164 reply->writeInt32(res); 165 return NO_ERROR; 166 } break; 167 case FINISH_OPERATION_TRANSACTION: { 168 CHECK_INTERFACE(IAppOpsService, data, reply); 169 sp<IBinder> token = data.readStrongBinder(); 170 int32_t code = data.readInt32(); 171 int32_t uid = data.readInt32(); 172 String16 packageName = data.readString16(); 173 finishOperation(token, code, uid, packageName); 174 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; 193 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; 201 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; 209 default: 210 return BBinder::onTransact(code, data, reply, flags); 211 } 212 } 213 214 }; // namespace android 215