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 <binder/Parcel.h> 22 #include <utils/Log.h> 23 #include <utils/String8.h> 24 25 #include <optional> 26 27 namespace android { 28 29 // ---------------------------------------------------------------------- 30 31 class BpAppOpsService : public BpInterface<IAppOpsService> 32 { 33 public: BpAppOpsService(const sp<IBinder> & impl)34 explicit BpAppOpsService(const sp<IBinder>& impl) 35 : BpInterface<IAppOpsService>(impl) 36 { 37 } 38 checkOperation(int32_t code,int32_t uid,const String16 & packageName)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 noteOperation(int32_t code,int32_t uid,const String16 & packageName,const std::optional<String16> & attributionTag,bool shouldCollectAsyncNotedOp,const String16 & message,bool shouldCollectMessage)51 virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName, 52 const std::optional<String16>& attributionTag, bool shouldCollectAsyncNotedOp, 53 const String16& message, bool shouldCollectMessage) { 54 Parcel data, reply; 55 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); 56 data.writeInt32(code); 57 data.writeInt32(uid); 58 data.writeString16(packageName); 59 data.writeString16(attributionTag); 60 data.writeBool(shouldCollectAsyncNotedOp); 61 data.writeString16(message); 62 data.writeBool(shouldCollectMessage); 63 remote()->transact(NOTE_OPERATION_TRANSACTION, data, &reply); 64 // fail on exception 65 if (reply.readExceptionCode() != 0) return MODE_ERRORED; 66 // TODO b/184855056: extract to class 67 reply.readInt32(); 68 reply.readByte(); 69 return reply.readInt32(); 70 } 71 startOperation(const sp<IBinder> & token,int32_t code,int32_t uid,const String16 & packageName,const std::optional<String16> & attributionTag,bool startIfModeDefault,bool shouldCollectAsyncNotedOp,const String16 & message,bool shouldCollectMessage)72 virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid, 73 const String16& packageName, const std::optional<String16>& attributionTag, 74 bool startIfModeDefault, bool shouldCollectAsyncNotedOp, const String16& message, 75 bool shouldCollectMessage) { 76 Parcel data, reply; 77 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); 78 data.writeStrongBinder(token); 79 data.writeInt32(code); 80 data.writeInt32(uid); 81 data.writeString16(packageName); 82 data.writeString16(attributionTag); 83 data.writeBool(startIfModeDefault); 84 data.writeBool(shouldCollectAsyncNotedOp); 85 data.writeString16(message); 86 data.writeBool(shouldCollectMessage); 87 remote()->transact(START_OPERATION_TRANSACTION, data, &reply); 88 // fail on exception 89 if (reply.readExceptionCode() != 0) return MODE_ERRORED; 90 // TODO b/184855056: extract to class 91 reply.readInt32(); 92 reply.readByte(); 93 return reply.readInt32(); 94 } 95 finishOperation(const sp<IBinder> & token,int32_t code,int32_t uid,const String16 & packageName,const std::optional<String16> & attributionTag)96 virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid, 97 const String16& packageName, const std::optional<String16>& attributionTag) { 98 Parcel data, reply; 99 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); 100 data.writeStrongBinder(token); 101 data.writeInt32(code); 102 data.writeInt32(uid); 103 data.writeString16(packageName); 104 data.writeString16(attributionTag); 105 remote()->transact(FINISH_OPERATION_TRANSACTION, data, &reply); 106 } 107 startWatchingMode(int32_t op,const String16 & packageName,const sp<IAppOpsCallback> & callback)108 virtual void startWatchingMode(int32_t op, const String16& packageName, 109 const sp<IAppOpsCallback>& callback) { 110 Parcel data, reply; 111 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); 112 data.writeInt32(op); 113 data.writeString16(packageName); 114 data.writeStrongBinder(IInterface::asBinder(callback)); 115 remote()->transact(START_WATCHING_MODE_TRANSACTION, data, &reply); 116 } 117 stopWatchingMode(const sp<IAppOpsCallback> & callback)118 virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) { 119 Parcel data, reply; 120 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); 121 data.writeStrongBinder(IInterface::asBinder(callback)); 122 remote()->transact(STOP_WATCHING_MODE_TRANSACTION, data, &reply); 123 } 124 permissionToOpCode(const String16 & permission)125 virtual int32_t permissionToOpCode(const String16& permission) { 126 Parcel data, reply; 127 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); 128 data.writeString16(permission); 129 remote()->transact(PERMISSION_TO_OP_CODE_TRANSACTION, data, &reply); 130 // fail on exception 131 if (reply.readExceptionCode() != 0) return -1; 132 return reply.readInt32(); 133 } 134 checkAudioOperation(int32_t code,int32_t usage,int32_t uid,const String16 & packageName)135 virtual int32_t checkAudioOperation(int32_t code, int32_t usage, 136 int32_t uid, const String16& packageName) { 137 Parcel data, reply; 138 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); 139 data.writeInt32(code); 140 data.writeInt32(usage); 141 data.writeInt32(uid); 142 data.writeString16(packageName); 143 remote()->transact(CHECK_AUDIO_OPERATION_TRANSACTION, data, &reply); 144 // fail on exception 145 if (reply.readExceptionCode() != 0) { 146 return MODE_ERRORED; 147 } 148 return reply.readInt32(); 149 } 150 setCameraAudioRestriction(int32_t mode)151 virtual void setCameraAudioRestriction(int32_t mode) { 152 Parcel data, reply; 153 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); 154 data.writeInt32(mode); 155 remote()->transact(SET_CAMERA_AUDIO_RESTRICTION_TRANSACTION, data, &reply); 156 } 157 shouldCollectNotes(int32_t opCode)158 virtual bool shouldCollectNotes(int32_t opCode) { 159 Parcel data, reply; 160 data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); 161 data.writeInt32(opCode); 162 remote()->transact(SHOULD_COLLECT_NOTES_TRANSACTION, data, &reply); 163 // fail on exception 164 if (reply.readExceptionCode() != 0) { 165 return false; 166 } 167 return reply.readBool(); 168 } 169 }; 170 171 IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService") 172 173 // ---------------------------------------------------------------------- 174 175 // NOLINTNEXTLINE(google-default-arguments) 176 status_t BnAppOpsService::onTransact( 177 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 178 { 179 //printf("AppOpsService received: "); data.print(); 180 switch(code) { 181 case CHECK_OPERATION_TRANSACTION: { 182 CHECK_INTERFACE(IAppOpsService, data, reply); 183 int32_t code = data.readInt32(); 184 int32_t uid = data.readInt32(); 185 String16 packageName = data.readString16(); 186 int32_t res = checkOperation(code, uid, packageName); 187 reply->writeNoException(); 188 reply->writeInt32(res); 189 return NO_ERROR; 190 } break; 191 case NOTE_OPERATION_TRANSACTION: { 192 CHECK_INTERFACE(IAppOpsService, data, reply); 193 int32_t code = data.readInt32(); 194 int32_t uid = data.readInt32(); 195 String16 packageName = data.readString16(); 196 std::optional<String16> attributionTag; 197 data.readString16(&attributionTag); 198 bool shouldCollectAsyncNotedOp = data.readBool(); 199 String16 message = data.readString16(); 200 bool shouldCollectMessage = data.readBool(); 201 int32_t res = noteOperation(code, uid, packageName, attributionTag, 202 shouldCollectAsyncNotedOp, message, shouldCollectMessage); 203 reply->writeNoException(); 204 reply->writeInt32(res); 205 return NO_ERROR; 206 } break; 207 case START_OPERATION_TRANSACTION: { 208 CHECK_INTERFACE(IAppOpsService, data, reply); 209 sp<IBinder> token = data.readStrongBinder(); 210 int32_t code = data.readInt32(); 211 int32_t uid = data.readInt32(); 212 String16 packageName = data.readString16(); 213 std::optional<String16> attributionTag; 214 data.readString16(&attributionTag); 215 bool startIfModeDefault = data.readBool(); 216 bool shouldCollectAsyncNotedOp = data.readBool(); 217 String16 message = data.readString16(); 218 bool shouldCollectMessage = data.readBool(); 219 int32_t res = startOperation(token, code, uid, packageName, attributionTag, 220 startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage); 221 reply->writeNoException(); 222 reply->writeInt32(res); 223 return NO_ERROR; 224 } break; 225 case FINISH_OPERATION_TRANSACTION: { 226 CHECK_INTERFACE(IAppOpsService, data, reply); 227 sp<IBinder> token = data.readStrongBinder(); 228 int32_t code = data.readInt32(); 229 int32_t uid = data.readInt32(); 230 String16 packageName = data.readString16(); 231 std::optional<String16> attributionTag; 232 data.readString16(&attributionTag); 233 finishOperation(token, code, uid, packageName, attributionTag); 234 reply->writeNoException(); 235 return NO_ERROR; 236 } break; 237 case START_WATCHING_MODE_TRANSACTION: { 238 CHECK_INTERFACE(IAppOpsService, data, reply); 239 int32_t op = data.readInt32(); 240 String16 packageName = data.readString16(); 241 sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder()); 242 startWatchingMode(op, packageName, callback); 243 reply->writeNoException(); 244 return NO_ERROR; 245 } break; 246 case STOP_WATCHING_MODE_TRANSACTION: { 247 CHECK_INTERFACE(IAppOpsService, data, reply); 248 sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder()); 249 stopWatchingMode(callback); 250 reply->writeNoException(); 251 return NO_ERROR; 252 } break; 253 case PERMISSION_TO_OP_CODE_TRANSACTION: { 254 CHECK_INTERFACE(IAppOpsService, data, reply); 255 String16 permission = data.readString16(); 256 const int32_t opCode = permissionToOpCode(permission); 257 reply->writeNoException(); 258 reply->writeInt32(opCode); 259 return NO_ERROR; 260 } break; 261 case CHECK_AUDIO_OPERATION_TRANSACTION: { 262 CHECK_INTERFACE(IAppOpsService, data, reply); 263 const int32_t code = data.readInt32(); 264 const int32_t usage = data.readInt32(); 265 const int32_t uid = data.readInt32(); 266 const String16 packageName = data.readString16(); 267 const int32_t res = checkAudioOperation(code, usage, uid, packageName); 268 reply->writeNoException(); 269 reply->writeInt32(res); 270 return NO_ERROR; 271 } break; 272 case SET_CAMERA_AUDIO_RESTRICTION_TRANSACTION: { 273 CHECK_INTERFACE(IAppOpsService, data, reply); 274 const int32_t mode = data.readInt32(); 275 setCameraAudioRestriction(mode); 276 reply->writeNoException(); 277 return NO_ERROR; 278 } break; 279 case SHOULD_COLLECT_NOTES_TRANSACTION: { 280 CHECK_INTERFACE(IAppOpsService, data, reply); 281 int32_t opCode = data.readInt32(); 282 bool shouldCollect = shouldCollectNotes(opCode); 283 reply->writeNoException(); 284 reply->writeBool(shouldCollect); 285 return NO_ERROR; 286 } break; 287 default: 288 return BBinder::onTransact(code, data, reply, flags); 289 } 290 } 291 292 } // namespace android 293