/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #ifdef LOG_TAG #undef LOG_TAG #endif #define LOG_TAG "AppOpsManager" namespace android { static const sp& getClientId() { static pthread_mutex_t gClientIdMutex = PTHREAD_MUTEX_INITIALIZER; static sp gClientId; pthread_mutex_lock(&gClientIdMutex); if (gClientId == nullptr) { gClientId = sp::make(); } pthread_mutex_unlock(&gClientIdMutex); return gClientId; } AppOpsManager::AppOpsManager() { } sp AppOpsManager::getService() { static String16 _appops("appops"); std::lock_guard scoped_lock(mLock); int64_t startTime = 0; sp service = mService; while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) { sp binder = defaultServiceManager()->checkService(_appops); if (binder == nullptr) { // Wait for the app ops service to come back... if (startTime == 0) { startTime = uptimeMillis(); ALOGI("Waiting for app ops service"); } else if ((uptimeMillis()-startTime) > 10000) { ALOGW("Waiting too long for app ops service, giving up"); service = nullptr; break; } sleep(1); } else { service = interface_cast(binder); mService = service; } } return service; } int32_t AppOpsManager::checkOp(int32_t op, int32_t uid, const String16& callingPackage) { sp service = getService(); return service != nullptr ? service->checkOperation(op, uid, callingPackage) : AppOpsManager::MODE_IGNORED; } int32_t AppOpsManager::checkAudioOpNoThrow(int32_t op, int32_t usage, int32_t uid, const String16& callingPackage) { sp service = getService(); return service != nullptr ? service->checkAudioOperation(op, usage, uid, callingPackage) : AppOpsManager::MODE_IGNORED; } int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage) { return noteOp(op, uid, callingPackage, {}, String16("Legacy AppOpsManager.noteOp call")); } int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage, const std::optional& attributionTag, const String16& message) { sp service = getService(); int32_t mode = service != nullptr ? service->noteOperation(op, uid, callingPackage, attributionTag, shouldCollectNotes(op), message, uid == AID_SYSTEM) : AppOpsManager::MODE_IGNORED; return mode; } int32_t AppOpsManager::startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage, bool startIfModeDefault) { return startOpNoThrow(op, uid, callingPackage, startIfModeDefault, {}, String16("Legacy AppOpsManager.startOpNoThrow call")); } int32_t AppOpsManager::startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage, bool startIfModeDefault, const std::optional& attributionTag, const String16& message) { sp service = getService(); int32_t mode = service != nullptr ? service->startOperation(getClientId(), op, uid, callingPackage, attributionTag, startIfModeDefault, shouldCollectNotes(op), message, uid == AID_SYSTEM) : AppOpsManager::MODE_IGNORED; return mode; } void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage) { finishOp(op, uid, callingPackage, {}); } void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage, const std::optional& attributionTag) { sp service = getService(); if (service != nullptr) { service->finishOperation(getClientId(), op, uid, callingPackage, attributionTag); } } void AppOpsManager::startWatchingMode(int32_t op, const String16& packageName, const sp& callback) { sp service = getService(); if (service != nullptr) { service->startWatchingMode(op, packageName, callback); } } void AppOpsManager::startWatchingMode(int32_t op, const String16& packageName, int32_t flags, const sp& callback) { sp service = getService(); if (service != nullptr) { service->startWatchingModeWithFlags(op, packageName, flags, callback); } } void AppOpsManager::stopWatchingMode(const sp& callback) { sp service = getService(); if (service != nullptr) { service->stopWatchingMode(callback); } } int32_t AppOpsManager::permissionToOpCode(const String16& permission) { sp service = getService(); if (service != nullptr) { return service->permissionToOpCode(permission); } return -1; } void AppOpsManager::setCameraAudioRestriction(int32_t mode) { sp service = getService(); if (service != nullptr) { service->setCameraAudioRestriction(mode); } } // check it the appops needs to be collected and cache result bool AppOpsManager::shouldCollectNotes(int32_t opcode) { // Whether an appop should be collected: 0 == not initialized, 1 == don't note, 2 == note static uint8_t appOpsToNote[AppOpsManager::_NUM_OP] = {0}; if (appOpsToNote[opcode] == 0) { if (getService()->shouldCollectNotes(opcode)) { appOpsToNote[opcode] = 2; } else { appOpsToNote[opcode] = 1; } } return appOpsToNote[opcode] == 2; } } // namespace android