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/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(int32_t code, int32_t uid, const String16& packageName) {
     65         Parcel data, reply;
     66         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
     67         data.writeInt32(code);
     68         data.writeInt32(uid);
     69         data.writeString16(packageName);
     70         remote()->transact(START_OPERATION_TRANSACTION, data, &reply);
     71         // fail on exception
     72         if (reply.readExceptionCode() != 0) return MODE_ERRORED;
     73         return reply.readInt32();
     74     }
     75 
     76     virtual void finishOperation(int32_t code, int32_t uid, const String16& packageName) {
     77         Parcel data, reply;
     78         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
     79         data.writeInt32(code);
     80         data.writeInt32(uid);
     81         data.writeString16(packageName);
     82         remote()->transact(FINISH_OPERATION_TRANSACTION, data, &reply);
     83     }
     84 
     85     virtual void startWatchingMode(int32_t op, const String16& packageName,
     86             const sp<IAppOpsCallback>& callback) {
     87         Parcel data, reply;
     88         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
     89         data.writeInt32(op);
     90         data.writeString16(packageName);
     91         data.writeStrongBinder(callback->asBinder());
     92         remote()->transact(START_WATCHING_MODE_TRANSACTION, data, &reply);
     93     }
     94 
     95     virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) {
     96         Parcel data, reply;
     97         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
     98         data.writeStrongBinder(callback->asBinder());
     99         remote()->transact(STOP_WATCHING_MODE_TRANSACTION, data, &reply);
    100     }
    101 };
    102 
    103 IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService");
    104 
    105 // ----------------------------------------------------------------------
    106 
    107 status_t BnAppOpsService::onTransact(
    108     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    109 {
    110     //printf("AppOpsService received: "); data.print();
    111     switch(code) {
    112         case CHECK_OPERATION_TRANSACTION: {
    113             CHECK_INTERFACE(IAppOpsService, data, reply);
    114             int32_t code = data.readInt32();
    115             int32_t uid = data.readInt32();
    116             String16 packageName = data.readString16();
    117             int32_t res = checkOperation(code, uid, packageName);
    118             reply->writeNoException();
    119             reply->writeInt32(res);
    120             return NO_ERROR;
    121         } break;
    122         case NOTE_OPERATION_TRANSACTION: {
    123             CHECK_INTERFACE(IAppOpsService, data, reply);
    124             int32_t code = data.readInt32();
    125             int32_t uid = data.readInt32();
    126             String16 packageName = data.readString16();
    127             int32_t res = noteOperation(code, uid, packageName);
    128             reply->writeNoException();
    129             reply->writeInt32(res);
    130             return NO_ERROR;
    131         } break;
    132         case START_OPERATION_TRANSACTION: {
    133             CHECK_INTERFACE(IAppOpsService, data, reply);
    134             int32_t code = data.readInt32();
    135             int32_t uid = data.readInt32();
    136             String16 packageName = data.readString16();
    137             int32_t res = startOperation(code, uid, packageName);
    138             reply->writeNoException();
    139             reply->writeInt32(res);
    140             return NO_ERROR;
    141         } break;
    142         case FINISH_OPERATION_TRANSACTION: {
    143             CHECK_INTERFACE(IAppOpsService, data, reply);
    144             int32_t code = data.readInt32();
    145             int32_t uid = data.readInt32();
    146             String16 packageName = data.readString16();
    147             finishOperation(code, uid, packageName);
    148             reply->writeNoException();
    149             return NO_ERROR;
    150         } break;
    151         case START_WATCHING_MODE_TRANSACTION: {
    152             CHECK_INTERFACE(IAppOpsService, data, reply);
    153             int32_t op = data.readInt32();
    154             String16 packageName = data.readString16();
    155             sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
    156             startWatchingMode(op, packageName, callback);
    157             reply->writeNoException();
    158             return NO_ERROR;
    159         } break;
    160         case STOP_WATCHING_MODE_TRANSACTION: {
    161             CHECK_INTERFACE(IAppOpsService, data, reply);
    162             sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder());
    163             stopWatchingMode(callback);
    164             reply->writeNoException();
    165             return NO_ERROR;
    166         } break;
    167         default:
    168             return BBinder::onTransact(code, data, reply, flags);
    169     }
    170 }
    171 
    172 }; // namespace android
    173