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 24 namespace android { 25 26 namespace { 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. 32 const int APP_OPS_MANAGER_UNAVAILABLE_MODE = AppOpsManager::MODE_ALLOWED; 33 #else 34 const int APP_OPS_MANAGER_UNAVAILABLE_MODE = AppOpsManager::MODE_IGNORED; 35 #endif // defined(__BRILLO__) 36 37 } // namespace 38 39 static String16 _appops("appops"); 40 static pthread_mutex_t gTokenMutex = PTHREAD_MUTEX_INITIALIZER; 41 static sp<IBinder> gToken; 42 43 static 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 52 AppOpsManager::AppOpsManager() 53 { 54 } 55 56 #if defined(__BRILLO__) 57 // There is no AppOpsService on Brillo 58 sp<IAppOpsService> AppOpsManager::getService() { return NULL; } 59 #else 60 sp<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 88 int32_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 96 int32_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 103 int32_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 110 void 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 117 void 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 125 void AppOpsManager::stopWatchingMode(const sp<IAppOpsCallback>& callback) { 126 sp<IAppOpsService> service = getService(); 127 if (service != NULL) { 128 service->stopWatchingMode(callback); 129 } 130 } 131 132 int32_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