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     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 void getPackagesForUid(const uid_t uid, Vector<String16>& packages)
     53     {
     54         Parcel data, reply;
     55         data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
     56         data.writeInt32(uid);
     57         remote()->transact(GET_PACKAGES_FOR_UID_TRANSACTION, data, &reply);
     58         // fail on exception
     59         if (reply.readExceptionCode() != 0) {
     60             return;
     61         }
     62         const int32_t size = reply.readInt32();
     63         if (size <= 0) {
     64             return;
     65         }
     66         for (int i = 0; i < size; i++) {
     67             packages.push(reply.readString16());
     68         }
     69     }
     70 
     71     virtual bool isRuntimePermission(const String16& permission)
     72     {
     73         Parcel data, reply;
     74         data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
     75         data.writeString16(permission);
     76         remote()->transact(IS_RUNTIME_PERMISSION_TRANSACTION, data, &reply);
     77         // fail on exception
     78         if (reply.readExceptionCode() != 0) return false;
     79         return reply.readInt32() != 0;
     80     }
     81 };
     82 
     83 IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController");
     84 
     85 // ----------------------------------------------------------------------
     86 
     87 status_t BnPermissionController::onTransact(
     88     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
     89 {
     90     switch(code) {
     91         case CHECK_PERMISSION_TRANSACTION: {
     92             CHECK_INTERFACE(IPermissionController, data, reply);
     93             String16 permission = data.readString16();
     94             int32_t pid = data.readInt32();
     95             int32_t uid = data.readInt32();
     96             bool res = checkPermission(permission, pid, uid);
     97             reply->writeNoException();
     98             reply->writeInt32(res ? 1 : 0);
     99             return NO_ERROR;
    100         } break;
    101 
    102         case GET_PACKAGES_FOR_UID_TRANSACTION: {
    103             CHECK_INTERFACE(IPermissionController, data, reply);
    104             int32_t uid = data.readInt32();
    105             Vector<String16> packages;
    106             getPackagesForUid(uid, packages);
    107             reply->writeNoException();
    108             size_t size = packages.size();
    109             reply->writeInt32(size);
    110             for (size_t i = 0; i < size; i++) {
    111                 reply->writeString16(packages[i]);
    112             }
    113             return NO_ERROR;
    114         } break;
    115 
    116         case IS_RUNTIME_PERMISSION_TRANSACTION: {
    117             CHECK_INTERFACE(IPermissionController, data, reply);
    118             String16 permission = data.readString16();
    119             const bool res = isRuntimePermission(permission);
    120             reply->writeNoException();
    121             reply->writeInt32(res ? 1 : 0);
    122             return NO_ERROR;
    123         } break;
    124 
    125         default:
    126             return BBinder::onTransact(code, data, reply, flags);
    127     }
    128 }
    129 
    130 }; // namespace android
    131