* Copyright (c) 2023-2023 Huawei Device Co., Ltd.
* 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.
*/
#ifndef OHOS_CAMERA_H_CAMERA_DEVICE_MANAGER_H
#define OHOS_CAMERA_H_CAMERA_DEVICE_MANAGER_H
#include <refbase.h>
#include <set>
#include "hcamera_device.h"
#include "camera_privacy.h"
#include "camera_util.h"
#include "safe_map.h"
namespace OHOS {
namespace CameraStandard {
class CameraProcessPriority : public RefBase {
public:
CameraProcessPriority(int32_t uid, int32_t state, int32_t focusState) : processUid_(uid),
processState_(state), focusState_(focusState) {}
inline bool operator == (const CameraProcessPriority& rhs) const
{
return (this->processState_ == rhs.processState_) && (this->focusState_ == rhs.focusState_);
}
inline bool operator < (const CameraProcessPriority& rhs) const
{
if (this->processUid_ < maxSysUid_) {
MEDIA_DEBUG_LOG("this->processUid_ :%{public}d", this->processUid_);
return true;
} else if (this->processUid_ >= maxSysUid_ && rhs.processUid_ < maxSysUid_) {
MEDIA_DEBUG_LOG("this->processUid_ :%{public}d, rhs.processUid_ :%{public}d",
this->processUid_, rhs.processUid_);
return false;
}
if (this->processState_ == rhs.processState_) {
MEDIA_DEBUG_LOG("this->processState_ :%{public}d == rhs.processState_: %{public}d",
this->processState_, rhs.processState_);
return this->focusState_ < rhs.focusState_;
} else {
MEDIA_DEBUG_LOG("this->processState:%{public}d, rhs.processState_:%{public}d",
this->processState_, rhs.processState_);
return this->processState_ > rhs.processState_;
}
}
inline bool operator > (const CameraProcessPriority& rhs) const
{
return rhs < *this;
}
inline bool operator <= (const CameraProcessPriority& rhs) const
{
if (this->processUid_ < maxSysUid_ && rhs.processUid_ < maxSysUid_) {
return true;
}
return !(*this > rhs);
}
inline bool operator >= (const CameraProcessPriority& rhs) const
{
if (this->processUid_ < maxSysUid_ && rhs.processUid_ < maxSysUid_) {
return false;
}
return !(*this < rhs);
}
inline void SetProcessState(int32_t state)
{
processState_ = state;
}
inline void SetProcessFocusState(int32_t focusState)
{
focusState_ = focusState;
}
inline void SetProcessUid(int32_t uid)
{
processUid_ = uid;
}
inline int32_t GetUid() const{ return processUid_; }
inline int32_t GetState() const { return processState_; }
inline int32_t GetFocusState() const { return focusState_; }
private:
const int32_t maxSysUid_ = 10000;
int32_t processUid_;
int32_t processState_;
int32_t focusState_;
};
class HCameraDeviceHolder : public RefBase {
public:
HCameraDeviceHolder(int32_t pid, int32_t uid, int32_t state, int32_t focusState,
sptr<HCameraDevice> device, uint32_t accessTokenId, int32_t cost, const std::set<std::string> &conflicting,
uint32_t firstTokenId)
:pid_(pid), uid_(uid), accessTokenId_(accessTokenId), device_(device), cost_(cost), conflicting_(conflicting),
firstTokenId_(firstTokenId)
{
processPriority_ = new CameraProcessPriority(uid, state, focusState);
}
inline void SetPid(int32_t pid) { pid_ = pid; }
inline void SetUid(int32_t uid) { uid_ = uid; }
inline void SetState(int32_t state)
{
processPriority_->SetProcessState(state);
}
inline void SetFocusState(int32_t focusState)
{
processPriority_->SetProcessFocusState(focusState);
}
inline void SetPriorityUid(int32_t uid)
{
processPriority_->SetProcessUid(uid);
}
inline int32_t GetPid() const {return pid_;}
inline int32_t GetUid() const{ return uid_; }
inline int32_t GetState() const { return processPriority_->GetState(); }
inline int32_t GetFocusState() const { return processPriority_->GetFocusState(); }
inline uint32_t GetAccessTokenId() const { return accessTokenId_; }
inline sptr<HCameraDevice> GetDevice() const { return device_; }
inline sptr<CameraProcessPriority> GetPriority() const {return processPriority_;}
int32_t GetCost() const{ return cost_; }
bool IsConflicting(const std::string &cameraId) const
{
std::string curCameraId = device_->GetCameraId();
if (cameraId == curCameraId) {
return true;
}
for (const auto &x : conflicting_) {
if (cameraId == x) {
return true;
}
}
return false;
}
inline uint32_t GetFirstTokenID() const { return firstTokenId_; }
std::set<std::string> GetConflicting() const { return conflicting_; }
private:
int32_t pid_;
int32_t uid_;
uint32_t accessTokenId_;
sptr<CameraProcessPriority> processPriority_;
sptr<HCameraDevice> device_;
int32_t cost_;
std::set<std::string> conflicting_;
uint32_t firstTokenId_;
};
class CameraConcurrentSelector : public RefBase {
public:
CameraConcurrentSelector() = default;
~CameraConcurrentSelector() = default;
* @brief Setting up a baseline camera and producing a table of concurrent cameras
*/
void SetRequestCameraId(sptr<HCameraDeviceHolder> requestCameraHolder);
* @brief Check and save whether the camera can be retained.
*/
bool SaveConcurrentCameras(std::vector<sptr<HCameraDeviceHolder>> holdersSortedByProprity,
sptr<HCameraDeviceHolder> holderWaitToConfirm);
* @brief Return to cameras that must be retained.
*
* @return Return to cameras that must be retained.
*/
inline std::vector<sptr<HCameraDeviceHolder>> GetCamerasRetainable()
{
return listOfCameraRetainable_;
}
* @brief Return the Concurrent List.
*
* @return Return the Concurrent List.
*/
inline std::vector<std::vector<std::int32_t>> GetConcurrentCameraTable()
{
return concurrentCameraTable_;
}
bool CanOpenCameraconcurrently(std::vector<sptr<HCameraDeviceHolder>> reservedCameras,
std::vector<std::vector<std::int32_t>> concurrentCameraTable);
private:
sptr<HCameraDeviceHolder> requestCameraHolder_;
std::vector<sptr<HCameraDeviceHolder>> listOfCameraRetainable_ = {};
std::vector<std::vector<std::int32_t>> concurrentCameraTable_ = {};
int32_t GetCameraIdNumber(std::string);
bool ConcurrentWithRetainedDevicesOrNot(sptr<HCameraDeviceHolder> cameraIdNeedConfirm);
};
class HCameraDeviceManager : public RefBase {
public:
* @brief the default maxinum "cost" allowed before evicting.
*
*/
static constexpr int32_t DEFAULT_MAX_COST = 100;
~HCameraDeviceManager();
* @brief Get camera device manager instance.
*
* @return Returns pointer to camera device manager instance.
*/
static sptr<HCameraDeviceManager> &GetInstance();
* @brief Add opened device in camera device manager.
*
* @param device Device that have been turned on.
* @param pid Pid for opening the device.
*/
void AddDevice(pid_t pid, sptr<HCameraDevice> device);
* @brief remove camera in camera device manager.
*
* @param device Device that have been turned off.
*/
void RemoveDevice(const std::string &cameraId);
* @brief Get cameraHolder by active process pid.
*
* @param pid Pid of active process.
*/
std::vector<sptr<HCameraDeviceHolder>> GetCameraHolderByPid(pid_t pid);
* @brief Get cameras by active process pid.
*
* @param pid Pid of active process.
*/
std::vector<sptr<HCameraDevice>> GetCamerasByPid(pid_t pidRequest);
* @brief Get process pid device manager instance.
*
* @return Returns pointer to camera device manager instance.
*/
std::vector<pid_t> GetActiveClient();
* @brief Get the existing holder object.
*
* @return Returns the list of existing holders.
*/
std::vector<sptr<HCameraDeviceHolder>> GetActiveCameraHolders();
void SetStateOfACamera(std::string cameraId, int32_t state);
bool IsMultiCameraActive(int32_t pid);
void SetPeerCallback(const sptr<ICameraBroker>& callback);
void UnsetPeerCallback();
size_t GetActiveCamerasCount();
SafeMap<std::string, int32_t> &GetCameraStateOfASide();
* @brief remove camera in camera device manager.
*
* @param camerasNeedEvict Devices that need to be shut down.
* @param cameraIdRequestOpen device is requested to turn on.
*/
bool GetConflictDevices(std::vector<sptr<HCameraDevice>> &cameraNeedEvict, sptr<HCameraDevice> cameraIdRequestOpen,
int32_t concurrentTypeOfRequest);
* @brief handle active camera evictions in camera device manager.
*
* @param evictedClients Devices that need to be shut down.
* @param cameraRequestOpen device is requested to turn on.
*/
bool HandleCameraEvictions(std::vector<sptr<HCameraDeviceHolder>> &evictedClients,
sptr<HCameraDeviceHolder> &cameraRequestOpen);
bool IsProcessHasConcurrentDevice(pid_t pid);
bool PermDisableSA();
bool GetDisablePolicy();
bool RegisterPermDisablePolicyCallback();
void UnRegisterPermDisablePolicyCallback();
int32_t SetMdmCheck(bool mdmCheck);
bool GetMdmCheck();
#ifdef CAMERA_LIVE_SCENE_RECOGNITION
void SetLiveScene(bool isLiveScene);
bool IsLiveScene();
#endif
void SetScanSceneBundle(const std::string& bundleName);
std::string GetScanSceneBundle();
bool IsScanScene();
private:
SafeMap<string, unordered_set<int>> unsupportedMultiCameraCombinationsMap_;
HCameraDeviceManager();
static sptr<HCameraDeviceManager> cameraDeviceManager_;
static std::mutex instanceMutex_;
std::map<pid_t, std::vector<sptr<HCameraDeviceHolder>>> pidToCameras_;
SafeMap<std::string, int32_t> stateOfRgmCamera_;
std::vector<sptr<HCameraDeviceHolder>> activeCameras_;
std::vector<sptr<HCameraDeviceHolder>> holderSortedByProprity_;
sptr<ICameraBroker> peerCallback_;
std::mutex peerCbMutex_;
sptr<CameraConcurrentSelector> concurrentSelector_;
bool mdmCheck_ = true;
std::mutex mapMutex_;
std::mutex policyMutex_;
std::mutex mdmMutex_;
std::shared_ptr<DisablePolicyChangeCb> policyCallbackPtr_;
std::string GetACameraId();
bool IsAllowOpen(pid_t activeClient);
int32_t GetCurrentCost();
std::vector<sptr<HCameraDeviceHolder>> WouldEvict(sptr<HCameraDeviceHolder> &cameraRequestOpen);
void GenerateEachProcessCameraState(int32_t& processState, uint32_t processTokenId);
void PrintClientInfo(sptr<HCameraDeviceHolder> activeCameraHolder, sptr<HCameraDeviceHolder> requestCameraHolder);
sptr<HCameraDeviceHolder> GenerateCameraHolder(sptr<HCameraDevice> device, pid_t pid, int32_t uid,
uint32_t accessTokenId, uint32_t firstTokenId);
std::vector<sptr<HCameraDeviceHolder>> SortDeviceByPriority();
void RefreshCameraDeviceHolderState(sptr<HCameraDeviceHolder> requestCameraHolder);
#ifdef CAMERA_LIVE_SCENE_RECOGNITION
std::atomic<bool> isLiveScene_ = false;
#endif
std::string scanSceneBundleName_ = "";
};
}
}
#endif