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 pthread_mutex_unlock(&gTokenMutex); 35 return gToken; 36} 37 38AppOpsManager::AppOpsManager() 39{ 40} 41 42sp<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 68int32_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 74int32_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 79int32_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 85void 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 92void 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 100void 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