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 <mutex> 18#include <binder/AppOpsManager.h> 19#include <binder/Binder.h> 20#include <binder/IServiceManager.h> 21 22#include <utils/SystemClock.h> 23 24namespace android { 25 26namespace { 27 28#if defined(__BRILLO__) 29// Because Brillo has no application model, security policy is managed 30// statically (at build time) with SELinux controls. 31// As a consequence, it also never runs the AppOpsManager service. 32const int APP_OPS_MANAGER_UNAVAILABLE_MODE = AppOpsManager::MODE_ALLOWED; 33#else 34const int APP_OPS_MANAGER_UNAVAILABLE_MODE = AppOpsManager::MODE_IGNORED; 35#endif // defined(__BRILLO__) 36 37} // namespace 38 39static String16 _appops("appops"); 40static pthread_mutex_t gTokenMutex = PTHREAD_MUTEX_INITIALIZER; 41static sp<IBinder> gToken; 42 43static const sp<IBinder>& getToken(const sp<IAppOpsService>& service) { 44 pthread_mutex_lock(&gTokenMutex); 45 if (gToken == NULL || gToken->pingBinder() != NO_ERROR) { 46 gToken = service->getToken(new BBinder()); 47 } 48 pthread_mutex_unlock(&gTokenMutex); 49 return gToken; 50} 51 52AppOpsManager::AppOpsManager() 53{ 54} 55 56#if defined(__BRILLO__) 57// There is no AppOpsService on Brillo 58sp<IAppOpsService> AppOpsManager::getService() { return NULL; } 59#else 60sp<IAppOpsService> AppOpsManager::getService() 61{ 62 63 std::lock_guard<Mutex> scoped_lock(mLock); 64 int64_t startTime = 0; 65 sp<IAppOpsService> service = mService; 66 while (service == NULL || !IInterface::asBinder(service)->isBinderAlive()) { 67 sp<IBinder> binder = defaultServiceManager()->checkService(_appops); 68 if (binder == NULL) { 69 // Wait for the app ops service to come back... 70 if (startTime == 0) { 71 startTime = uptimeMillis(); 72 ALOGI("Waiting for app ops service"); 73 } else if ((uptimeMillis()-startTime) > 10000) { 74 ALOGW("Waiting too long for app ops service, giving up"); 75 service = NULL; 76 break; 77 } 78 sleep(1); 79 } else { 80 service = interface_cast<IAppOpsService>(binder); 81 mService = service; 82 } 83 } 84 return service; 85} 86#endif // defined(__BRILLO__) 87 88int32_t AppOpsManager::checkOp(int32_t op, int32_t uid, const String16& callingPackage) 89{ 90 sp<IAppOpsService> service = getService(); 91 return service != NULL 92 ? service->checkOperation(op, uid, callingPackage) 93 : APP_OPS_MANAGER_UNAVAILABLE_MODE; 94} 95 96int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage) { 97 sp<IAppOpsService> service = getService(); 98 return service != NULL 99 ? service->noteOperation(op, uid, callingPackage) 100 : APP_OPS_MANAGER_UNAVAILABLE_MODE; 101} 102 103int32_t AppOpsManager::startOp(int32_t op, int32_t uid, const String16& callingPackage) { 104 sp<IAppOpsService> service = getService(); 105 return service != NULL 106 ? service->startOperation(getToken(service), op, uid, callingPackage) 107 : APP_OPS_MANAGER_UNAVAILABLE_MODE; 108} 109 110void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage) { 111 sp<IAppOpsService> service = getService(); 112 if (service != NULL) { 113 service->finishOperation(getToken(service), op, uid, callingPackage); 114 } 115} 116 117void AppOpsManager::startWatchingMode(int32_t op, const String16& packageName, 118 const sp<IAppOpsCallback>& callback) { 119 sp<IAppOpsService> service = getService(); 120 if (service != NULL) { 121 service->startWatchingMode(op, packageName, callback); 122 } 123} 124 125void AppOpsManager::stopWatchingMode(const sp<IAppOpsCallback>& callback) { 126 sp<IAppOpsService> service = getService(); 127 if (service != NULL) { 128 service->stopWatchingMode(callback); 129 } 130} 131 132int32_t AppOpsManager::permissionToOpCode(const String16& permission) { 133 sp<IAppOpsService> service = getService(); 134 if (service != NULL) { 135 return service->permissionToOpCode(permission); 136 } 137 return -1; 138} 139 140 141}; // namespace android 142