Home | History | Annotate | Download | only in binder
      1 /*
      2  * Copyright (C) 2005 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 "PermissionController"
     18 
     19 #include <binder/IPermissionController.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 BpPermissionController : public BpInterface<IPermissionController>
     32 {
     33 public:
     34     explicit BpPermissionController(const sp<IBinder>& impl)
     35         : BpInterface<IPermissionController>(impl)
     36     {
     37     }
     38 
     39     virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid)
     40     {
     41         Parcel data, reply;
     42         data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
     43         data.writeString16(permission);
     44         data.writeInt32(pid);
     45         data.writeInt32(uid);
     46         remote()->transact(CHECK_PERMISSION_TRANSACTION, data, &reply);
     47         // fail on exception
     48         if (reply.readExceptionCode() != 0) return 0;
     49         return reply.readInt32() != 0;
     50     }
     51 
     52     virtual int32_t noteOp(const String16& op, int32_t uid, const String16& packageName)
     53     {
     54         Parcel data, reply;
     55         data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
     56         data.writeString16(op);
     57         data.writeInt32(uid);
     58         data.writeString16(packageName);
     59         remote()->transact(NOTE_OP_TRANSACTION, data, &reply);
     60         // fail on exception
     61         if (reply.readExceptionCode() != 0) return 2; // MODE_ERRORED
     62         return reply.readInt32();
     63     }
     64 
     65     virtual void getPackagesForUid(const uid_t uid, Vector<String16>& packages)
     66     {
     67         Parcel data, reply;
     68         data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
     69         data.writeInt32(uid);
     70         remote()->transact(GET_PACKAGES_FOR_UID_TRANSACTION, data, &reply);
     71         // fail on exception
     72         if (reply.readExceptionCode() != 0) {
     73             return;
     74         }
     75         const int32_t size = reply.readInt32();
     76         if (size <= 0) {
     77             return;
     78         }
     79         for (int i = 0; i < size; i++) {
     80             packages.push(reply.readString16());
     81         }
     82     }
     83 
     84     virtual bool isRuntimePermission(const String16& permission)
     85     {
     86         Parcel data, reply;
     87         data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
     88         data.writeString16(permission);
     89         remote()->transact(IS_RUNTIME_PERMISSION_TRANSACTION, data, &reply);
     90         // fail on exception
     91         if (reply.readExceptionCode() != 0) return false;
     92         return reply.readInt32() != 0;
     93     }
     94 
     95     virtual int getPackageUid(const String16& package, int flags)
     96     {
     97         Parcel data, reply;
     98         data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
     99         data.writeString16(package);
    100         data.writeInt32(flags);
    101         remote()->transact(GET_PACKAGE_UID_TRANSACTION, data, &reply);
    102         // fail on exception
    103         if (reply.readExceptionCode() != 0) return false;
    104         return reply.readInt32();
    105     }
    106 };
    107 
    108 IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController");
    109 
    110 // ----------------------------------------------------------------------
    111 
    112 // NOLINTNEXTLINE(google-default-arguments)
    113 status_t BnPermissionController::onTransact(
    114     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    115 {
    116     switch(code) {
    117         case CHECK_PERMISSION_TRANSACTION: {
    118             CHECK_INTERFACE(IPermissionController, data, reply);
    119             String16 permission = data.readString16();
    120             int32_t pid = data.readInt32();
    121             int32_t uid = data.readInt32();
    122             bool res = checkPermission(permission, pid, uid);
    123             reply->writeNoException();
    124             reply->writeInt32(res ? 1 : 0);
    125             return NO_ERROR;
    126         } break;
    127 
    128         case NOTE_OP_TRANSACTION: {
    129             CHECK_INTERFACE(IPermissionController, data, reply);
    130             String16 op = data.readString16();
    131             int32_t uid = data.readInt32();
    132             String16 packageName = data.readString16();
    133             int32_t res = noteOp(op, uid, packageName);
    134             reply->writeNoException();
    135             reply->writeInt32(res);
    136             return NO_ERROR;
    137         } break;
    138 
    139         case GET_PACKAGES_FOR_UID_TRANSACTION: {
    140             CHECK_INTERFACE(IPermissionController, data, reply);
    141             int32_t uid = data.readInt32();
    142             Vector<String16> packages;
    143             getPackagesForUid(uid, packages);
    144             reply->writeNoException();
    145             size_t size = packages.size();
    146             reply->writeInt32(size);
    147             for (size_t i = 0; i < size; i++) {
    148                 reply->writeString16(packages[i]);
    149             }
    150             return NO_ERROR;
    151         } break;
    152 
    153         case IS_RUNTIME_PERMISSION_TRANSACTION: {
    154             CHECK_INTERFACE(IPermissionController, data, reply);
    155             String16 permission = data.readString16();
    156             const bool res = isRuntimePermission(permission);
    157             reply->writeNoException();
    158             reply->writeInt32(res ? 1 : 0);
    159             return NO_ERROR;
    160         } break;
    161 
    162         case GET_PACKAGE_UID_TRANSACTION: {
    163             CHECK_INTERFACE(IPermissionController, data, reply);
    164             String16 package = data.readString16();
    165             int flags = data.readInt32();
    166             const int uid = getPackageUid(package, flags);
    167             reply->writeNoException();
    168             reply->writeInt32(uid);
    169             return NO_ERROR;
    170         } break;
    171 
    172         default:
    173             return BBinder::onTransact(code, data, reply, flags);
    174     }
    175 }
    176 
    177 }; // namespace android
    178