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