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 "ServiceManager"
     18 
     19 #include <binder/IServiceManager.h>
     20 
     21 #include <utils/Debug.h>
     22 #include <utils/Log.h>
     23 #include <binder/IPCThreadState.h>
     24 #include <binder/Parcel.h>
     25 #include <utils/String8.h>
     26 #include <utils/SystemClock.h>
     27 
     28 #include <private/binder/Static.h>
     29 
     30 #include <unistd.h>
     31 
     32 namespace android {
     33 
     34 sp<IServiceManager> defaultServiceManager()
     35 {
     36     if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
     37 
     38     {
     39         AutoMutex _l(gDefaultServiceManagerLock);
     40         if (gDefaultServiceManager == NULL) {
     41             gDefaultServiceManager = interface_cast<IServiceManager>(
     42                 ProcessState::self()->getContextObject(NULL));
     43         }
     44     }
     45 
     46     return gDefaultServiceManager;
     47 }
     48 
     49 bool checkCallingPermission(const String16& permission)
     50 {
     51     return checkCallingPermission(permission, NULL, NULL);
     52 }
     53 
     54 static String16 _permission("permission");
     55 
     56 
     57 bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid)
     58 {
     59     IPCThreadState* ipcState = IPCThreadState::self();
     60     pid_t pid = ipcState->getCallingPid();
     61     uid_t uid = ipcState->getCallingUid();
     62     if (outPid) *outPid = pid;
     63     if (outUid) *outUid = uid;
     64     return checkPermission(permission, pid, uid);
     65 }
     66 
     67 bool checkPermission(const String16& permission, pid_t pid, uid_t uid)
     68 {
     69     sp<IPermissionController> pc;
     70     gDefaultServiceManagerLock.lock();
     71     pc = gPermissionController;
     72     gDefaultServiceManagerLock.unlock();
     73 
     74     int64_t startTime = 0;
     75 
     76     while (true) {
     77         if (pc != NULL) {
     78             bool res = pc->checkPermission(permission, pid, uid);
     79             if (res) {
     80                 if (startTime != 0) {
     81                     LOGI("Check passed after %d seconds for %s from uid=%d pid=%d",
     82                             (int)((uptimeMillis()-startTime)/1000),
     83                             String8(permission).string(), uid, pid);
     84                 }
     85                 return res;
     86             }
     87 
     88             // Is this a permission failure, or did the controller go away?
     89             if (pc->asBinder()->isBinderAlive()) {
     90                 LOGW("Permission failure: %s from uid=%d pid=%d",
     91                         String8(permission).string(), uid, pid);
     92                 return false;
     93             }
     94 
     95             // Object is dead!
     96             gDefaultServiceManagerLock.lock();
     97             if (gPermissionController == pc) {
     98                 gPermissionController = NULL;
     99             }
    100             gDefaultServiceManagerLock.unlock();
    101         }
    102 
    103         // Need to retrieve the permission controller.
    104         sp<IBinder> binder = defaultServiceManager()->checkService(_permission);
    105         if (binder == NULL) {
    106             // Wait for the permission controller to come back...
    107             if (startTime == 0) {
    108                 startTime = uptimeMillis();
    109                 LOGI("Waiting to check permission %s from uid=%d pid=%d",
    110                         String8(permission).string(), uid, pid);
    111             }
    112             sleep(1);
    113         } else {
    114             pc = interface_cast<IPermissionController>(binder);
    115             // Install the new permission controller, and try again.
    116             gDefaultServiceManagerLock.lock();
    117             gPermissionController = pc;
    118             gDefaultServiceManagerLock.unlock();
    119         }
    120     }
    121 }
    122 
    123 // ----------------------------------------------------------------------
    124 
    125 class BpServiceManager : public BpInterface<IServiceManager>
    126 {
    127 public:
    128     BpServiceManager(const sp<IBinder>& impl)
    129         : BpInterface<IServiceManager>(impl)
    130     {
    131     }
    132 
    133     virtual sp<IBinder> getService(const String16& name) const
    134     {
    135         unsigned n;
    136         for (n = 0; n < 5; n++){
    137             sp<IBinder> svc = checkService(name);
    138             if (svc != NULL) return svc;
    139             LOGI("Waiting for service %s...\n", String8(name).string());
    140             sleep(1);
    141         }
    142         return NULL;
    143     }
    144 
    145     virtual sp<IBinder> checkService( const String16& name) const
    146     {
    147         Parcel data, reply;
    148         data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    149         data.writeString16(name);
    150         remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
    151         return reply.readStrongBinder();
    152     }
    153 
    154     virtual status_t addService(const String16& name, const sp<IBinder>& service)
    155     {
    156         Parcel data, reply;
    157         data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    158         data.writeString16(name);
    159         data.writeStrongBinder(service);
    160         status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
    161         return err == NO_ERROR ? reply.readExceptionCode() : err;
    162     }
    163 
    164     virtual Vector<String16> listServices()
    165     {
    166         Vector<String16> res;
    167         int n = 0;
    168 
    169         for (;;) {
    170             Parcel data, reply;
    171             data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    172             data.writeInt32(n++);
    173             status_t err = remote()->transact(LIST_SERVICES_TRANSACTION, data, &reply);
    174             if (err != NO_ERROR)
    175                 break;
    176             res.add(reply.readString16());
    177         }
    178         return res;
    179     }
    180 };
    181 
    182 IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
    183 
    184 // ----------------------------------------------------------------------
    185 
    186 status_t BnServiceManager::onTransact(
    187     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    188 {
    189     //printf("ServiceManager received: "); data.print();
    190     switch(code) {
    191         case GET_SERVICE_TRANSACTION: {
    192             CHECK_INTERFACE(IServiceManager, data, reply);
    193             String16 which = data.readString16();
    194             sp<IBinder> b = const_cast<BnServiceManager*>(this)->getService(which);
    195             reply->writeStrongBinder(b);
    196             return NO_ERROR;
    197         } break;
    198         case CHECK_SERVICE_TRANSACTION: {
    199             CHECK_INTERFACE(IServiceManager, data, reply);
    200             String16 which = data.readString16();
    201             sp<IBinder> b = const_cast<BnServiceManager*>(this)->checkService(which);
    202             reply->writeStrongBinder(b);
    203             return NO_ERROR;
    204         } break;
    205         case ADD_SERVICE_TRANSACTION: {
    206             CHECK_INTERFACE(IServiceManager, data, reply);
    207             String16 which = data.readString16();
    208             sp<IBinder> b = data.readStrongBinder();
    209             status_t err = addService(which, b);
    210             reply->writeInt32(err);
    211             return NO_ERROR;
    212         } break;
    213         case LIST_SERVICES_TRANSACTION: {
    214             CHECK_INTERFACE(IServiceManager, data, reply);
    215             Vector<String16> list = listServices();
    216             const size_t N = list.size();
    217             reply->writeInt32(N);
    218             for (size_t i=0; i<N; i++) {
    219                 reply->writeString16(list[i]);
    220             }
    221             return NO_ERROR;
    222         } break;
    223         default:
    224             return BBinder::onTransact(code, data, reply, flags);
    225     }
    226 }
    227 
    228 }; // namespace android
    229