• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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