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