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 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 38 AppOpsManager::AppOpsManager() 39 { 40 } 41 42 sp<IAppOpsService> AppOpsManager::getService() 43 { 44 int64_t startTime = 0; 45 mLock.lock(); 46 sp<IAppOpsService> service = mService; 47 while (service == NULL || !IInterface::asBinder(service)->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 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 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 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 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 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 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 int32_t AppOpsManager::permissionToOpCode(const String16& permission) { 108 sp<IAppOpsService> service = getService(); 109 if (service != NULL) { 110 return service->permissionToOpCode(permission); 111 } 112 return -1; 113 } 114 115 116 }; // namespace android 117