Home | History | Annotate | Download | only in binder
      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     explicit 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, bool startIfModeDefault) {
     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         data.writeInt32(startIfModeDefault ? 1 : 0);
     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(IInterface::asBinder(callback));
     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(IInterface::asBinder(callback));
    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 nullptr;
    113         return reply.readStrongBinder();
    114     }
    115 
    116 
    117     virtual int32_t permissionToOpCode(const String16& permission) {
    118         Parcel data, reply;
    119         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
    120         data.writeString16(permission);
    121         remote()->transact(PERMISSION_TO_OP_CODE_TRANSACTION, data, &reply);
    122         // fail on exception
    123         if (reply.readExceptionCode() != 0) return -1;
    124         return reply.readInt32();
    125     }
    126 
    127     virtual int32_t checkAudioOperation(int32_t code, int32_t usage,
    128             int32_t uid, const String16& packageName) {
    129         Parcel data, reply;
    130         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
    131         data.writeInt32(code);
    132         data.writeInt32(usage);
    133         data.writeInt32(uid);
    134         data.writeString16(packageName);
    135         remote()->transact(CHECK_AUDIO_OPERATION_TRANSACTION, data, &reply);
    136         // fail on exception
    137         if (reply.readExceptionCode() != 0) {
    138             return MODE_ERRORED;
    139         }
    140         return reply.readInt32();
    141     }
    142 };
    143 
    144 IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService");
    145 
    146 // ----------------------------------------------------------------------
    147 
    148 // NOLINTNEXTLINE(google-default-arguments)
    149 status_t BnAppOpsService::onTransact(
    150     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    151 {
    152     //printf("AppOpsService received: "); data.print();
    153     switch(code) {
    154         case CHECK_OPERATION_TRANSACTION: {
    155             CHECK_INTERFACE(IAppOpsService, data, reply);
    156             int32_t code = data.readInt32();
    157             int32_t uid = data.readInt32();
    158             String16 packageName = data.readString16();
    159             int32_t res = checkOperation(code, uid, packageName);
    160             reply->writeNoException();
    161             reply->writeInt32(res);
    162             return NO_ERROR;
    163         } break;
    164         case NOTE_OPERATION_TRANSACTION: {
    165             CHECK_INTERFACE(IAppOpsService, data, reply);
    166             int32_t code = data.readInt32();
    167             int32_t uid = data.readInt32();
    168             String16 packageName = data.readString16();
    169             int32_t res = noteOperation(code, uid, packageName);
    170             reply->writeNoException();
    171             reply->writeInt32(res);
    172             return NO_ERROR;
    173         } break;
    174         case START_OPERATION_TRANSACTION: {
    175             CHECK_INTERFACE(IAppOpsService, data, reply);
    176             sp<IBinder> token = data.readStrongBinder();
    177             int32_t code = data.readInt32();
    178             int32_t uid = data.readInt32();
    179             String16 packageName = data.readString16();
    180             bool startIfModeDefault = data.readInt32() == 1;
    181             int32_t res = startOperation(token, code, uid, packageName, startIfModeDefault);
    182             reply->writeNoException();
    183             reply->writeInt32(res);
    184             return NO_ERROR;
    185         } break;
    186         case FINISH_OPERATION_TRANSACTION: {
    187             CHECK_INTERFACE(IAppOpsService, data, reply);
    188             sp<IBinder> token = data.readStrongBinder();
    189             int32_t code = data.readInt32();
    190             int32_t uid = data.readInt32();
    191             String16 packageName = data.readString16();
    192             finishOperation(token, code, uid, packageName);
    193             reply->writeNoException();
    194             return NO_ERROR;
    195         } break;
    196         case START_WATCHING_MODE_TRANSACTION: {
    197             CHECK_INTERFACE(IAppOpsService, data, reply);
    198             int32_t op = data.readInt32();
    199             String16 packageName = data.readString16();
    200             sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
    201             startWatchingMode(op, packageName, callback);
    202             reply->writeNoException();
    203             return NO_ERROR;
    204         } break;
    205         case STOP_WATCHING_MODE_TRANSACTION: {
    206             CHECK_INTERFACE(IAppOpsService, data, reply);
    207             sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
    208             stopWatchingMode(callback);
    209             reply->writeNoException();
    210             return NO_ERROR;
    211         } break;
    212         case GET_TOKEN_TRANSACTION: {
    213             CHECK_INTERFACE(IAppOpsService, data, reply);
    214             sp<IBinder> clientToken = data.readStrongBinder();
    215             sp<IBinder> token = getToken(clientToken);
    216             reply->writeNoException();
    217             reply->writeStrongBinder(token);
    218             return NO_ERROR;
    219         } break;
    220         case PERMISSION_TO_OP_CODE_TRANSACTION: {
    221             CHECK_INTERFACE(IAppOpsService, data, reply);
    222             String16 permission = data.readString16();
    223             const int32_t opCode = permissionToOpCode(permission);
    224             reply->writeNoException();
    225             reply->writeInt32(opCode);
    226             return NO_ERROR;
    227         } break;
    228         case CHECK_AUDIO_OPERATION_TRANSACTION: {
    229             CHECK_INTERFACE(IAppOpsService, data, reply);
    230             const int32_t code = data.readInt32();
    231             const int32_t usage = data.readInt32();
    232             const int32_t uid = data.readInt32();
    233             const String16 packageName = data.readString16();
    234             const int32_t res = checkAudioOperation(code, usage, uid, packageName);
    235             reply->writeNoException();
    236             reply->writeInt32(res);
    237             return NO_ERROR;
    238         } break;
    239         default:
    240             return BBinder::onTransact(code, data, reply, flags);
    241     }
    242 }
    243 
    244 }; // namespace android
    245