|
|
|
@ -33,6 +33,7 @@
|
|
|
|
|
|
|
|
|
|
#include <android-base/macros.h>
|
|
|
|
|
#include <android-base/parseint.h>
|
|
|
|
|
#include <android-base/stringprintf.h>
|
|
|
|
|
#include <binder/ActivityManager.h>
|
|
|
|
|
#include <binder/AppOpsManager.h>
|
|
|
|
|
#include <binder/IPCThreadState.h>
|
|
|
|
@ -81,6 +82,7 @@ namespace {
|
|
|
|
|
|
|
|
|
|
namespace android {
|
|
|
|
|
|
|
|
|
|
using base::StringPrintf;
|
|
|
|
|
using binder::Status;
|
|
|
|
|
using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
|
|
|
|
|
using hardware::ICamera;
|
|
|
|
@ -2366,6 +2368,13 @@ CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
|
|
|
|
|
}
|
|
|
|
|
mClientPackageName = packages[0];
|
|
|
|
|
}
|
|
|
|
|
if (hardware::IPCThreadState::self()->isServingCall()) {
|
|
|
|
|
std::string vendorClient =
|
|
|
|
|
StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
|
|
|
|
|
mClientPackageName = String16(vendorClient.c_str());
|
|
|
|
|
} else {
|
|
|
|
|
mAppOpsManager = std::make_unique<AppOpsManager>();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CameraService::BasicClient::~BasicClient() {
|
|
|
|
@ -2381,8 +2390,7 @@ binder::Status CameraService::BasicClient::disconnect() {
|
|
|
|
|
mDisconnected = true;
|
|
|
|
|
|
|
|
|
|
sCameraService->removeByClient(this);
|
|
|
|
|
sCameraService->logDisconnected(mCameraIdStr, mClientPid,
|
|
|
|
|
String8(mClientPackageName));
|
|
|
|
|
sCameraService->logDisconnected(mCameraIdStr, mClientPid, String8(mClientPackageName));
|
|
|
|
|
sCameraService->mCameraProviderManager->removeRef(CameraProviderManager::DeviceMode::CAMERA,
|
|
|
|
|
mCameraIdStr.c_str());
|
|
|
|
|
|
|
|
|
@ -2432,31 +2440,31 @@ bool CameraService::BasicClient::canCastToApiClient(apiLevel level) const {
|
|
|
|
|
status_t CameraService::BasicClient::startCameraOps() {
|
|
|
|
|
ATRACE_CALL();
|
|
|
|
|
|
|
|
|
|
int32_t res;
|
|
|
|
|
// Notify app ops that the camera is not available
|
|
|
|
|
mOpsCallback = new OpsCallback(this);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
|
|
|
|
|
__FUNCTION__, String8(mClientPackageName).string(), mClientUid);
|
|
|
|
|
}
|
|
|
|
|
if (mAppOpsManager != nullptr) {
|
|
|
|
|
// Notify app ops that the camera is not available
|
|
|
|
|
mOpsCallback = new OpsCallback(this);
|
|
|
|
|
int32_t res;
|
|
|
|
|
mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA,
|
|
|
|
|
mClientPackageName, mOpsCallback);
|
|
|
|
|
res = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA,
|
|
|
|
|
mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
|
|
|
|
|
|
|
|
|
|
mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
|
|
|
|
|
mClientPackageName, mOpsCallback);
|
|
|
|
|
res = mAppOpsManager.startOpNoThrow(AppOpsManager::OP_CAMERA,
|
|
|
|
|
mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
|
|
|
|
|
|
|
|
|
|
if (res == AppOpsManager::MODE_ERRORED) {
|
|
|
|
|
ALOGI("Camera %s: Access for \"%s\" has been revoked",
|
|
|
|
|
mCameraIdStr.string(), String8(mClientPackageName).string());
|
|
|
|
|
return PERMISSION_DENIED;
|
|
|
|
|
}
|
|
|
|
|
if (res == AppOpsManager::MODE_ERRORED) {
|
|
|
|
|
ALOGI("Camera %s: Access for \"%s\" has been revoked",
|
|
|
|
|
mCameraIdStr.string(), String8(mClientPackageName).string());
|
|
|
|
|
return PERMISSION_DENIED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (res == AppOpsManager::MODE_IGNORED) {
|
|
|
|
|
ALOGI("Camera %s: Access for \"%s\" has been restricted",
|
|
|
|
|
mCameraIdStr.string(), String8(mClientPackageName).string());
|
|
|
|
|
// Return the same error as for device policy manager rejection
|
|
|
|
|
return -EACCES;
|
|
|
|
|
if (res == AppOpsManager::MODE_IGNORED) {
|
|
|
|
|
ALOGI("Camera %s: Access for \"%s\" has been restricted",
|
|
|
|
|
mCameraIdStr.string(), String8(mClientPackageName).string());
|
|
|
|
|
// Return the same error as for device policy manager rejection
|
|
|
|
|
return -EACCES;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mOpsActive = true;
|
|
|
|
@ -2483,10 +2491,11 @@ status_t CameraService::BasicClient::finishCameraOps() {
|
|
|
|
|
// Check if startCameraOps succeeded, and if so, finish the camera op
|
|
|
|
|
if (mOpsActive) {
|
|
|
|
|
// Notify app ops that the camera is available again
|
|
|
|
|
mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
|
|
|
|
|
mClientPackageName);
|
|
|
|
|
mOpsActive = false;
|
|
|
|
|
|
|
|
|
|
if (mAppOpsManager != nullptr) {
|
|
|
|
|
mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, mClientUid,
|
|
|
|
|
mClientPackageName);
|
|
|
|
|
mOpsActive = false;
|
|
|
|
|
}
|
|
|
|
|
// This function is called when a client disconnects. This should
|
|
|
|
|
// release the camera, but actually only if it was in a proper
|
|
|
|
|
// functional state, i.e. with status NOT_AVAILABLE
|
|
|
|
@ -2506,8 +2515,8 @@ status_t CameraService::BasicClient::finishCameraOps() {
|
|
|
|
|
mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
|
|
|
|
|
}
|
|
|
|
|
// Always stop watching, even if no camera op is active
|
|
|
|
|
if (mOpsCallback != NULL) {
|
|
|
|
|
mAppOpsManager.stopWatchingMode(mOpsCallback);
|
|
|
|
|
if (mOpsCallback != nullptr && mAppOpsManager != nullptr) {
|
|
|
|
|
mAppOpsManager->stopWatchingMode(mOpsCallback);
|
|
|
|
|
}
|
|
|
|
|
mOpsCallback.clear();
|
|
|
|
|
|
|
|
|
@ -2516,19 +2525,18 @@ status_t CameraService::BasicClient::finishCameraOps() {
|
|
|
|
|
return OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
|
|
|
|
|
void CameraService::BasicClient::opChanged(int32_t op, const String16&) {
|
|
|
|
|
ATRACE_CALL();
|
|
|
|
|
|
|
|
|
|
String8 name(packageName);
|
|
|
|
|
String8 myName(mClientPackageName);
|
|
|
|
|
|
|
|
|
|
if (mAppOpsManager == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (op != AppOpsManager::OP_CAMERA) {
|
|
|
|
|
ALOGW("Unexpected app ops notification received: %d", op);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t res;
|
|
|
|
|
res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
|
|
|
|
|
res = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA,
|
|
|
|
|
mClientUid, mClientPackageName);
|
|
|
|
|
ALOGV("checkOp returns: %d, %s ", res,
|
|
|
|
|
res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
|
|
|
|
@ -2538,7 +2546,7 @@ void CameraService::BasicClient::opChanged(int32_t op, const String16& packageNa
|
|
|
|
|
|
|
|
|
|
if (res != AppOpsManager::MODE_ALLOWED) {
|
|
|
|
|
ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.string(),
|
|
|
|
|
myName.string());
|
|
|
|
|
String8(mClientPackageName).string());
|
|
|
|
|
block();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|