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/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 28 namespace android { 29 30 // ---------------------------------------------------------------------- 31 32 class BpAppOpsService : public BpInterface<IAppOpsService> 33 { 34 public: 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 48 if (reply.readExceptionCode() != 0) return MODE_ERRORED; 49 return reply.readInt32(); 50 } 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 60 if (reply.readExceptionCode() != 0) return MODE_ERRORED; 61 return reply.readInt32(); 62 } 63 64 virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid, 65 const String16& packageName) { 66 Parcel data, reply; 67 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); 68 data.writeStrongBinder(token); 69 data.writeInt32(code); 70 data.writeInt32(uid); 71 data.writeString16(packageName); 72 remote()->transact(START_OPERATION_TRANSACTION, data, &reply); 73 // fail on exception 74 if (reply.readExceptionCode() != 0) return MODE_ERRORED; 75 return reply.readInt32(); 76 } 77 78 virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid, 79 const String16& packageName) { 80 Parcel data, reply; 81 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); 82 data.writeStrongBinder(token); 83 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 } 105 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 } 115 }; 116 117 IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService"); 118 119 // ---------------------------------------------------------------------- 120 121 status_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); 148 sp<IBinder> token = data.readStrongBinder(); 149 int32_t code = data.readInt32(); 150 int32_t uid = data.readInt32(); 151 String16 packageName = data.readString16(); 152 int32_t res = startOperation(token, code, uid, packageName); 153 reply->writeNoException(); 154 reply->writeInt32(res); 155 return NO_ERROR; 156 } break; 157 case FINISH_OPERATION_TRANSACTION: { 158 CHECK_INTERFACE(IAppOpsService, data, reply); 159 sp<IBinder> token = data.readStrongBinder(); 160 int32_t code = data.readInt32(); 161 int32_t uid = data.readInt32(); 162 String16 packageName = data.readString16(); 163 finishOperation(token, code, uid, packageName); 164 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; 183 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; 191 default: 192 return BBinder::onTransact(code, data, reply, flags); 193 } 194 } 195 196 }; // namespace android 197