Loading camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ interface ICameraDeviceCallbacks const int ERROR_CAMERA_REQUEST = 3; const int ERROR_CAMERA_RESULT = 4; const int ERROR_CAMERA_BUFFER = 5; const int ERROR_CAMERA_DISABLED = 6; oneway void onDeviceError(int errorCode, in CaptureResultExtras resultExtras); oneway void onDeviceIdle(); Loading services/camera/libcameraservice/CameraService.cpp +235 −6 Original line number Diff line number Diff line Loading @@ -33,14 +33,18 @@ #include <android-base/macros.h> #include <android-base/parseint.h> #include <binder/ActivityManager.h> #include <binder/AppOpsManager.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> #include <binder/MemoryBase.h> #include <binder/MemoryHeapBase.h> #include <binder/PermissionController.h> #include <binder/ProcessInfoService.h> #include <binder/IResultReceiver.h> #include <cutils/atomic.h> #include <cutils/properties.h> #include <cutils/misc.h> #include <gui/Surface.h> #include <hardware/hardware.h> #include <memunreachable/memunreachable.h> Loading Loading @@ -165,6 +169,8 @@ static void torch_mode_status_change( // ---------------------------------------------------------------------------- static const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA"); CameraService::CameraService() : mEventLog(DEFAULT_EVENT_LOG_LENGTH), mNumberOfCameras(0), mNumberOfNormalCameras(0), Loading Loading @@ -196,6 +202,9 @@ void CameraService::onFirstRef() } CameraService::pingCameraServiceProxy(); mUidPolicy = new UidPolicy(this); mUidPolicy->registerSelf(); } status_t CameraService::enumerateProviders() { Loading Loading @@ -275,6 +284,7 @@ void CameraService::pingCameraServiceProxy() { CameraService::~CameraService() { VendorTagDescriptor::clearGlobalVendorTagDescriptor(); mUidPolicy->unregisterSelf(); } void CameraService::onNewProviderRegistered() { Loading Loading @@ -933,6 +943,15 @@ Status CameraService::validateClientPermissionsLocked(const String8& cameraId, clientName8.string(), clientUid, clientPid, cameraId.string()); } // Make sure the UID is in an active state to use the camera if (!mUidPolicy->isUidActive(callingUid)) { ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d", clientPid, clientUid); return STATUS_ERROR_FMT(ERROR_DISABLED, "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" from background", clientName8.string(), clientUid, clientPid, cameraId.string()); } // Only use passed in clientPid to check permission. Use calling PID as the client PID that's // connected to camera service directly. originalClientPid = clientPid; Loading Loading @@ -1969,6 +1988,30 @@ status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* re // Permission checks switch (code) { case SHELL_COMMAND_TRANSACTION: { int in = data.readFileDescriptor(); int out = data.readFileDescriptor(); int err = data.readFileDescriptor(); int argc = data.readInt32(); Vector<String16> args; for (int i = 0; i < argc && data.dataAvail() > 0; i++) { args.add(data.readString16()); } sp<IBinder> unusedCallback; sp<IResultReceiver> resultReceiver; status_t status; if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) { return status; } if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) { return status; } status = shellCommand(in, out, err, args); if (resultReceiver != nullptr) { resultReceiver->send(status); } return NO_ERROR; } case BnCameraService::NOTIFYSYSTEMEVENT: { if (pid != selfPid) { // Ensure we're being called by system_server, or similar process with Loading Loading @@ -2286,14 +2329,20 @@ 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()); block(); } } void CameraService::BasicClient::block() { ATRACE_CALL(); // Reset the client PID to allow server-initiated disconnect, // and to prevent further calls by client. mClientPid = getCallingPid(); CaptureResultExtras resultExtras; // a dummy result (invalid) notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras); notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED, resultExtras); disconnect(); } } // ---------------------------------------------------------------------------- Loading Loading @@ -2330,6 +2379,98 @@ void CameraService::Client::OpsCallback::opChanged(int32_t op, } } // ---------------------------------------------------------------------------- // UidPolicy // ---------------------------------------------------------------------------- void CameraService::UidPolicy::registerSelf() { ActivityManager am; am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE | ActivityManager::UID_OBSERVER_IDLE | ActivityManager::UID_OBSERVER_ACTIVE, ActivityManager::PROCESS_STATE_UNKNOWN, String16("cameraserver")); } void CameraService::UidPolicy::unregisterSelf() { ActivityManager am; am.unregisterUidObserver(this); } void CameraService::UidPolicy::onUidGone(uid_t uid, bool disabled) { onUidIdle(uid, disabled); } void CameraService::UidPolicy::onUidActive(uid_t uid) { Mutex::Autolock _l(mUidLock); mActiveUids.insert(uid); } void CameraService::UidPolicy::onUidIdle(uid_t uid, bool /* disabled */) { bool deleted = false; { Mutex::Autolock _l(mUidLock); if (mActiveUids.erase(uid) > 0) { deleted = true; } } if (deleted) { sp<CameraService> service = mService.promote(); if (service != nullptr) { service->blockClientsForUid(uid); } } } bool CameraService::UidPolicy::isUidActive(uid_t uid) { // Non-app UIDs are considered always active if (uid < FIRST_APPLICATION_UID) { return true; } Mutex::Autolock _l(mUidLock); return isUidActiveLocked(uid); } bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid) { // Non-app UIDs are considered always active if (uid < FIRST_APPLICATION_UID) { return true; } auto it = mOverrideUids.find(uid); if (it != mOverrideUids.end()) { return it->second; } return mActiveUids.find(uid) != mActiveUids.end(); } void CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid, bool active) { updateOverrideUid(uid, active, true); } void CameraService::UidPolicy::removeOverrideUid(uid_t uid) { updateOverrideUid(uid, false, false); } void CameraService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) { bool wasActive = false; bool isActive = false; { Mutex::Autolock _l(mUidLock); wasActive = isUidActiveLocked(uid); mOverrideUids.erase(uid); if (insert) { mOverrideUids.insert(std::pair<uid_t, bool>(uid, active)); } isActive = isUidActiveLocked(uid); } if (wasActive != isActive && !isActive) { sp<CameraService> service = mService.promote(); if (service != nullptr) { service->blockClientsForUid(uid); } } } // ---------------------------------------------------------------------------- // CameraState // ---------------------------------------------------------------------------- Loading Loading @@ -2791,4 +2932,92 @@ status_t CameraService::setTorchStatusLocked(const String8& cameraId, return OK; } void CameraService::blockClientsForUid(uid_t uid) { const auto clients = mActiveClientManager.getAll(); for (auto& current : clients) { if (current != nullptr) { const auto basicClient = current->getValue(); if (basicClient.get() != nullptr && basicClient->getClientUid() == uid) { basicClient->block(); } } } } // NOTE: This is a remote API - make sure all args are validated status_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) { if (!checkCallingPermission(sManageCameraPermission, nullptr, nullptr)) { return PERMISSION_DENIED; } if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) { return BAD_VALUE; } if (args.size() == 3 && args[0] == String16("set-uid-state")) { return handleSetUidState(args, err); } else if (args.size() == 2 && args[0] == String16("reset-uid-state")) { return handleResetUidState(args, err); } else if (args.size() == 2 && args[0] == String16("get-uid-state")) { return handleGetUidState(args, out, err); } else if (args.size() == 1 && args[0] == String16("help")) { printHelp(out); return NO_ERROR; } printHelp(err); return BAD_VALUE; } status_t CameraService::handleSetUidState(const Vector<String16>& args, int err) { PermissionController pc; int uid = pc.getPackageUid(args[1], 0); if (uid <= 0) { ALOGE("Unknown package: '%s'", String8(args[1]).string()); dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string()); return BAD_VALUE; } bool active = false; if (args[2] == String16("active")) { active = true; } else if ((args[2] != String16("idle"))) { ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string()); return BAD_VALUE; } mUidPolicy->addOverrideUid(uid, active); return NO_ERROR; } status_t CameraService::handleResetUidState(const Vector<String16>& args, int err) { PermissionController pc; int uid = pc.getPackageUid(args[1], 0); if (uid < 0) { ALOGE("Unknown package: '%s'", String8(args[1]).string()); dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string()); return BAD_VALUE; } mUidPolicy->removeOverrideUid(uid); return NO_ERROR; } status_t CameraService::handleGetUidState(const Vector<String16>& args, int out, int err) { PermissionController pc; int uid = pc.getPackageUid(args[1], 0); if (uid <= 0) { ALOGE("Unknown package: '%s'", String8(args[1]).string()); dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string()); return BAD_VALUE; } if (mUidPolicy->isUidActive(uid)) { return dprintf(out, "active\n"); } else { return dprintf(out, "idle\n"); } } status_t CameraService::printHelp(int out) { return dprintf(out, "Camera service commands:\n" " get-uid-state <PACKAGE> gets the uid state\n" " set-uid-state <PACKAGE> <active|idle> overrides the uid state\n" " reset-uid-state <PACKAGE> clears the uid state override\n" " help print this message\n"); } }; // namespace android services/camera/libcameraservice/CameraService.h +54 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <binder/AppOpsManager.h> #include <binder/BinderService.h> #include <binder/IAppOpsCallback.h> #include <binder/IUidObserver.h> #include <hardware/camera.h> #include <android/hardware/camera/common/1.0/types.h> Loading @@ -47,6 +48,8 @@ #include <map> #include <memory> #include <utility> #include <unordered_map> #include <unordered_set> namespace android { Loading Loading @@ -163,6 +166,8 @@ public: virtual status_t dump(int fd, const Vector<String16>& args); virtual status_t shellCommand(int in, int out, int err, const Vector<String16>& args); ///////////////////////////////////////////////////////////////////// // Client functionality Loading Loading @@ -233,6 +238,9 @@ public: // Check what API level is used for this client. This is used to determine which // superclass this can be cast to. virtual bool canCastToApiClient(apiLevel level) const; // Block the client form using the camera virtual void block(); protected: BasicClient(const sp<CameraService>& cameraService, const sp<IBinder>& remoteCallback, Loading Loading @@ -506,6 +514,37 @@ private: CameraParameters mShimParams; }; // class CameraState // Observer for UID lifecycle enforcing that UIDs in idle // state cannot use the camera to protect user privacy. class UidPolicy : public BnUidObserver { public: explicit UidPolicy(sp<CameraService> service) : mService(service) {} void registerSelf(); void unregisterSelf(); bool isUidActive(uid_t uid); void onUidGone(uid_t uid, bool disabled); void onUidActive(uid_t uid); void onUidIdle(uid_t uid, bool disabled); void addOverrideUid(uid_t uid, bool active); void removeOverrideUid(uid_t uid); private: bool isUidActiveLocked(uid_t uid); void updateOverrideUid(uid_t uid, bool active, bool insert); Mutex mUidLock; wp<CameraService> mService; std::unordered_set<uid_t> mActiveUids; std::unordered_map<uid_t, bool> mOverrideUids; }; // class UidPolicy sp<UidPolicy> mUidPolicy; // Delay-load the Camera HAL module virtual void onFirstRef(); Loading Loading @@ -755,6 +794,21 @@ private: */ binder::Status getLegacyParametersLazy(int cameraId, /*out*/CameraParameters* parameters); // Blocks all clients from the UID void blockClientsForUid(uid_t uid); // Overrides the UID state as if it is idle status_t handleSetUidState(const Vector<String16>& args, int err); // Clears the override for the UID state status_t handleResetUidState(const Vector<String16>& args, int err); // Gets the UID state status_t handleGetUidState(const Vector<String16>& args, int out, int err); // Prints the shell command help status_t printHelp(int out); static int getCallingPid(); static int getCallingUid(); Loading Loading
camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ interface ICameraDeviceCallbacks const int ERROR_CAMERA_REQUEST = 3; const int ERROR_CAMERA_RESULT = 4; const int ERROR_CAMERA_BUFFER = 5; const int ERROR_CAMERA_DISABLED = 6; oneway void onDeviceError(int errorCode, in CaptureResultExtras resultExtras); oneway void onDeviceIdle(); Loading
services/camera/libcameraservice/CameraService.cpp +235 −6 Original line number Diff line number Diff line Loading @@ -33,14 +33,18 @@ #include <android-base/macros.h> #include <android-base/parseint.h> #include <binder/ActivityManager.h> #include <binder/AppOpsManager.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> #include <binder/MemoryBase.h> #include <binder/MemoryHeapBase.h> #include <binder/PermissionController.h> #include <binder/ProcessInfoService.h> #include <binder/IResultReceiver.h> #include <cutils/atomic.h> #include <cutils/properties.h> #include <cutils/misc.h> #include <gui/Surface.h> #include <hardware/hardware.h> #include <memunreachable/memunreachable.h> Loading Loading @@ -165,6 +169,8 @@ static void torch_mode_status_change( // ---------------------------------------------------------------------------- static const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA"); CameraService::CameraService() : mEventLog(DEFAULT_EVENT_LOG_LENGTH), mNumberOfCameras(0), mNumberOfNormalCameras(0), Loading Loading @@ -196,6 +202,9 @@ void CameraService::onFirstRef() } CameraService::pingCameraServiceProxy(); mUidPolicy = new UidPolicy(this); mUidPolicy->registerSelf(); } status_t CameraService::enumerateProviders() { Loading Loading @@ -275,6 +284,7 @@ void CameraService::pingCameraServiceProxy() { CameraService::~CameraService() { VendorTagDescriptor::clearGlobalVendorTagDescriptor(); mUidPolicy->unregisterSelf(); } void CameraService::onNewProviderRegistered() { Loading Loading @@ -933,6 +943,15 @@ Status CameraService::validateClientPermissionsLocked(const String8& cameraId, clientName8.string(), clientUid, clientPid, cameraId.string()); } // Make sure the UID is in an active state to use the camera if (!mUidPolicy->isUidActive(callingUid)) { ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d", clientPid, clientUid); return STATUS_ERROR_FMT(ERROR_DISABLED, "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" from background", clientName8.string(), clientUid, clientPid, cameraId.string()); } // Only use passed in clientPid to check permission. Use calling PID as the client PID that's // connected to camera service directly. originalClientPid = clientPid; Loading Loading @@ -1969,6 +1988,30 @@ status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* re // Permission checks switch (code) { case SHELL_COMMAND_TRANSACTION: { int in = data.readFileDescriptor(); int out = data.readFileDescriptor(); int err = data.readFileDescriptor(); int argc = data.readInt32(); Vector<String16> args; for (int i = 0; i < argc && data.dataAvail() > 0; i++) { args.add(data.readString16()); } sp<IBinder> unusedCallback; sp<IResultReceiver> resultReceiver; status_t status; if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) { return status; } if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) { return status; } status = shellCommand(in, out, err, args); if (resultReceiver != nullptr) { resultReceiver->send(status); } return NO_ERROR; } case BnCameraService::NOTIFYSYSTEMEVENT: { if (pid != selfPid) { // Ensure we're being called by system_server, or similar process with Loading Loading @@ -2286,14 +2329,20 @@ 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()); block(); } } void CameraService::BasicClient::block() { ATRACE_CALL(); // Reset the client PID to allow server-initiated disconnect, // and to prevent further calls by client. mClientPid = getCallingPid(); CaptureResultExtras resultExtras; // a dummy result (invalid) notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras); notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED, resultExtras); disconnect(); } } // ---------------------------------------------------------------------------- Loading Loading @@ -2330,6 +2379,98 @@ void CameraService::Client::OpsCallback::opChanged(int32_t op, } } // ---------------------------------------------------------------------------- // UidPolicy // ---------------------------------------------------------------------------- void CameraService::UidPolicy::registerSelf() { ActivityManager am; am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE | ActivityManager::UID_OBSERVER_IDLE | ActivityManager::UID_OBSERVER_ACTIVE, ActivityManager::PROCESS_STATE_UNKNOWN, String16("cameraserver")); } void CameraService::UidPolicy::unregisterSelf() { ActivityManager am; am.unregisterUidObserver(this); } void CameraService::UidPolicy::onUidGone(uid_t uid, bool disabled) { onUidIdle(uid, disabled); } void CameraService::UidPolicy::onUidActive(uid_t uid) { Mutex::Autolock _l(mUidLock); mActiveUids.insert(uid); } void CameraService::UidPolicy::onUidIdle(uid_t uid, bool /* disabled */) { bool deleted = false; { Mutex::Autolock _l(mUidLock); if (mActiveUids.erase(uid) > 0) { deleted = true; } } if (deleted) { sp<CameraService> service = mService.promote(); if (service != nullptr) { service->blockClientsForUid(uid); } } } bool CameraService::UidPolicy::isUidActive(uid_t uid) { // Non-app UIDs are considered always active if (uid < FIRST_APPLICATION_UID) { return true; } Mutex::Autolock _l(mUidLock); return isUidActiveLocked(uid); } bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid) { // Non-app UIDs are considered always active if (uid < FIRST_APPLICATION_UID) { return true; } auto it = mOverrideUids.find(uid); if (it != mOverrideUids.end()) { return it->second; } return mActiveUids.find(uid) != mActiveUids.end(); } void CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid, bool active) { updateOverrideUid(uid, active, true); } void CameraService::UidPolicy::removeOverrideUid(uid_t uid) { updateOverrideUid(uid, false, false); } void CameraService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) { bool wasActive = false; bool isActive = false; { Mutex::Autolock _l(mUidLock); wasActive = isUidActiveLocked(uid); mOverrideUids.erase(uid); if (insert) { mOverrideUids.insert(std::pair<uid_t, bool>(uid, active)); } isActive = isUidActiveLocked(uid); } if (wasActive != isActive && !isActive) { sp<CameraService> service = mService.promote(); if (service != nullptr) { service->blockClientsForUid(uid); } } } // ---------------------------------------------------------------------------- // CameraState // ---------------------------------------------------------------------------- Loading Loading @@ -2791,4 +2932,92 @@ status_t CameraService::setTorchStatusLocked(const String8& cameraId, return OK; } void CameraService::blockClientsForUid(uid_t uid) { const auto clients = mActiveClientManager.getAll(); for (auto& current : clients) { if (current != nullptr) { const auto basicClient = current->getValue(); if (basicClient.get() != nullptr && basicClient->getClientUid() == uid) { basicClient->block(); } } } } // NOTE: This is a remote API - make sure all args are validated status_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) { if (!checkCallingPermission(sManageCameraPermission, nullptr, nullptr)) { return PERMISSION_DENIED; } if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) { return BAD_VALUE; } if (args.size() == 3 && args[0] == String16("set-uid-state")) { return handleSetUidState(args, err); } else if (args.size() == 2 && args[0] == String16("reset-uid-state")) { return handleResetUidState(args, err); } else if (args.size() == 2 && args[0] == String16("get-uid-state")) { return handleGetUidState(args, out, err); } else if (args.size() == 1 && args[0] == String16("help")) { printHelp(out); return NO_ERROR; } printHelp(err); return BAD_VALUE; } status_t CameraService::handleSetUidState(const Vector<String16>& args, int err) { PermissionController pc; int uid = pc.getPackageUid(args[1], 0); if (uid <= 0) { ALOGE("Unknown package: '%s'", String8(args[1]).string()); dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string()); return BAD_VALUE; } bool active = false; if (args[2] == String16("active")) { active = true; } else if ((args[2] != String16("idle"))) { ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string()); return BAD_VALUE; } mUidPolicy->addOverrideUid(uid, active); return NO_ERROR; } status_t CameraService::handleResetUidState(const Vector<String16>& args, int err) { PermissionController pc; int uid = pc.getPackageUid(args[1], 0); if (uid < 0) { ALOGE("Unknown package: '%s'", String8(args[1]).string()); dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string()); return BAD_VALUE; } mUidPolicy->removeOverrideUid(uid); return NO_ERROR; } status_t CameraService::handleGetUidState(const Vector<String16>& args, int out, int err) { PermissionController pc; int uid = pc.getPackageUid(args[1], 0); if (uid <= 0) { ALOGE("Unknown package: '%s'", String8(args[1]).string()); dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string()); return BAD_VALUE; } if (mUidPolicy->isUidActive(uid)) { return dprintf(out, "active\n"); } else { return dprintf(out, "idle\n"); } } status_t CameraService::printHelp(int out) { return dprintf(out, "Camera service commands:\n" " get-uid-state <PACKAGE> gets the uid state\n" " set-uid-state <PACKAGE> <active|idle> overrides the uid state\n" " reset-uid-state <PACKAGE> clears the uid state override\n" " help print this message\n"); } }; // namespace android
services/camera/libcameraservice/CameraService.h +54 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <binder/AppOpsManager.h> #include <binder/BinderService.h> #include <binder/IAppOpsCallback.h> #include <binder/IUidObserver.h> #include <hardware/camera.h> #include <android/hardware/camera/common/1.0/types.h> Loading @@ -47,6 +48,8 @@ #include <map> #include <memory> #include <utility> #include <unordered_map> #include <unordered_set> namespace android { Loading Loading @@ -163,6 +166,8 @@ public: virtual status_t dump(int fd, const Vector<String16>& args); virtual status_t shellCommand(int in, int out, int err, const Vector<String16>& args); ///////////////////////////////////////////////////////////////////// // Client functionality Loading Loading @@ -233,6 +238,9 @@ public: // Check what API level is used for this client. This is used to determine which // superclass this can be cast to. virtual bool canCastToApiClient(apiLevel level) const; // Block the client form using the camera virtual void block(); protected: BasicClient(const sp<CameraService>& cameraService, const sp<IBinder>& remoteCallback, Loading Loading @@ -506,6 +514,37 @@ private: CameraParameters mShimParams; }; // class CameraState // Observer for UID lifecycle enforcing that UIDs in idle // state cannot use the camera to protect user privacy. class UidPolicy : public BnUidObserver { public: explicit UidPolicy(sp<CameraService> service) : mService(service) {} void registerSelf(); void unregisterSelf(); bool isUidActive(uid_t uid); void onUidGone(uid_t uid, bool disabled); void onUidActive(uid_t uid); void onUidIdle(uid_t uid, bool disabled); void addOverrideUid(uid_t uid, bool active); void removeOverrideUid(uid_t uid); private: bool isUidActiveLocked(uid_t uid); void updateOverrideUid(uid_t uid, bool active, bool insert); Mutex mUidLock; wp<CameraService> mService; std::unordered_set<uid_t> mActiveUids; std::unordered_map<uid_t, bool> mOverrideUids; }; // class UidPolicy sp<UidPolicy> mUidPolicy; // Delay-load the Camera HAL module virtual void onFirstRef(); Loading Loading @@ -755,6 +794,21 @@ private: */ binder::Status getLegacyParametersLazy(int cameraId, /*out*/CameraParameters* parameters); // Blocks all clients from the UID void blockClientsForUid(uid_t uid); // Overrides the UID state as if it is idle status_t handleSetUidState(const Vector<String16>& args, int err); // Clears the override for the UID state status_t handleResetUidState(const Vector<String16>& args, int err); // Gets the UID state status_t handleGetUidState(const Vector<String16>& args, int out, int err); // Prints the shell command help status_t printHelp(int out); static int getCallingPid(); static int getCallingUid(); Loading