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(callback->asBinder()); 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(callback->asBinder()); 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 IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService"); 117 118 // ---------------------------------------------------------------------- 119 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