AppOpsManager.cpp revision 913b63d235a982174b66acad95ca2f87ac8a1982
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#include <binder/AppOpsManager.h>
18#include <binder/Binder.h>
19#include <binder/IServiceManager.h>
20
21#include <utils/SystemClock.h>
22
23namespace android {
24
25static String16 _appops("appops");
26static pthread_mutex_t gTokenMutex = PTHREAD_MUTEX_INITIALIZER;
27static sp<IBinder> gToken;
28
29static const sp<IBinder>& getToken(const sp<IAppOpsService>& service) {
30    pthread_mutex_lock(&gTokenMutex);
31    if (gToken == NULL) {
32        gToken = service->getToken(new BBinder());
33    }
34    return gToken;
35}
36
37AppOpsManager::AppOpsManager()
38{
39}
40
41sp<IAppOpsService> AppOpsManager::getService()
42{
43    int64_t startTime = 0;
44    mLock.lock();
45    sp<IAppOpsService> service = mService;
46    while (service == NULL || !service->asBinder()->isBinderAlive()) {
47        sp<IBinder> binder = defaultServiceManager()->checkService(_appops);
48        if (binder == NULL) {
49            // Wait for the app ops service to come back...
50            if (startTime == 0) {
51                startTime = uptimeMillis();
52                ALOGI("Waiting for app ops service");
53            } else if ((uptimeMillis()-startTime) > 10000) {
54                ALOGW("Waiting too long for app ops service, giving up");
55                return NULL;
56            }
57            sleep(1);
58        } else {
59            service = interface_cast<IAppOpsService>(binder);
60            mService = service;
61        }
62    }
63    mLock.unlock();
64    return service;
65}
66
67int32_t AppOpsManager::checkOp(int32_t op, int32_t uid, const String16& callingPackage)
68{
69    sp<IAppOpsService> service = getService();
70    return service != NULL ? service->checkOperation(op, uid, callingPackage) : MODE_IGNORED;
71}
72
73int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage) {
74    sp<IAppOpsService> service = getService();
75    return service != NULL ? service->noteOperation(op, uid, callingPackage) : MODE_IGNORED;
76}
77
78int32_t AppOpsManager::startOp(int32_t op, int32_t uid, const String16& callingPackage) {
79    sp<IAppOpsService> service = getService();
80    return service != NULL ? service->startOperation(getToken(service), op, uid, callingPackage)
81            : MODE_IGNORED;
82}
83
84void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage) {
85    sp<IAppOpsService> service = getService();
86    if (service != NULL) {
87        service->finishOperation(getToken(service), op, uid, callingPackage);
88    }
89}
90
91void AppOpsManager::startWatchingMode(int32_t op, const String16& packageName,
92        const sp<IAppOpsCallback>& callback) {
93    sp<IAppOpsService> service = getService();
94    if (service != NULL) {
95        service->startWatchingMode(op, packageName, callback);
96    }
97}
98
99void AppOpsManager::stopWatchingMode(const sp<IAppOpsCallback>& callback) {
100    sp<IAppOpsService> service = getService();
101    if (service != NULL) {
102        service->stopWatchingMode(callback);
103    }
104}
105
106}; // namespace android
107