diff --git a/frameworks/native/camera/test/unittest/camera_service/BUILD.gn b/frameworks/native/camera/test/unittest/camera_service/BUILD.gn index f49f905b70bbb496d15072dca556f746664f1510..3cdcdeec1ebb9b8925e4125cadadb79e830e5c1c 100644 --- a/frameworks/native/camera/test/unittest/camera_service/BUILD.gn +++ b/frameworks/native/camera/test/unittest/camera_service/BUILD.gn @@ -35,6 +35,7 @@ ohos_unittest("camera_service_unittest") { "${multimedia_camera_framework_path}/services/camera_service/include/media_library", "${multimedia_camera_framework_path}/services/camera_service/include/param_update", "${multimedia_camera_framework_path}/services/camera_service/include/dfx", + "${multimedia_camera_framework_path}/services/camera_service/include/rss", "${multimedia_camera_framework_path}/services/camera_service/include/smooth_zoom", "${multimedia_camera_framework_path}/services/camera_service/binder/base/include", "${multimedia_camera_framework_path}/services/camera_service/binder/client/include", diff --git a/frameworks/native/camera/test/unittest/camera_service/hdi_camera_test/src/hcamera_service_unittest.cpp b/frameworks/native/camera/test/unittest/camera_service/hdi_camera_test/src/hcamera_service_unittest.cpp index e991797f517b3f5d0a7b903e30a3106ad34f20b1..5c2fa82965b178ad4876c14891eca2e063c722bb 100644 --- a/frameworks/native/camera/test/unittest/camera_service/hdi_camera_test/src/hcamera_service_unittest.cpp +++ b/frameworks/native/camera/test/unittest/camera_service/hdi_camera_test/src/hcamera_service_unittest.cpp @@ -1457,9 +1457,18 @@ HWTEST_F(HCameraServiceUnit, HCamera_service_unittest_040, TestSize.Level1) std::set pidList = {}; bool isProxy = false; - EXPECT_EQ(cameraService_->ProxyForFreeze(pidList, isProxy), CAMERA_OK); + EXPECT_EQ(cameraService_->ProxyForFreeze(pidList, isProxy), CAMERA_OPERATION_NOT_ALLOWED); + EXPECT_EQ(cameraService_->ResetAllFreezeStatus(), CAMERA_OPERATION_NOT_ALLOWED); device->Release(); device->Close(); + + cameraService_->OnAddSystemAbility(RES_SCHED_SYS_ABILITY_ID, ""); + auto suspendStateObserver = cameraService_->suspendStateObserver_; + ASSERT_NE(suspendStateObserver, nullptr); + suspendStateObserver->OnActive(std::vector{0, 1, 2, 3, 4}, 0); + suspendStateObserver->OnDoze(std::vector{0, 1, 2, 3, 4}, 0); + suspendStateObserver->OnFrozen(std::vector{0, 1, 2, 3, 4}, 0); + cameraService_->OnRemoveSystemAbility(RES_SCHED_SYS_ABILITY_ID, ""); } /* diff --git a/frameworks/native/camera/test/unittest/framework_native/BUILD.gn b/frameworks/native/camera/test/unittest/framework_native/BUILD.gn index e40d06bad73807cd575bc59835098e2089673e14..66f240a61cbf3323122c162fa7fd3471fd8f0ca3 100644 --- a/frameworks/native/camera/test/unittest/framework_native/BUILD.gn +++ b/frameworks/native/camera/test/unittest/framework_native/BUILD.gn @@ -27,6 +27,7 @@ ohos_unittest("camera_framework_native_unittest") { "./session/include", "./ability/include", "${multimedia_camera_framework_path}/services/camera_service/include", + "${multimedia_camera_framework_path}/services/camera_service/include/rss", "${multimedia_camera_framework_path}/dynamic_libs/moving_photo/include/avcodec", "${multimedia_camera_framework_path}/dynamic_libs/moving_photo/include/common", "${multimedia_camera_framework_path}/services/camera_service/include/dfx", diff --git a/services/camera_service/BUILD.gn b/services/camera_service/BUILD.gn index 4824a0c1b26d50b3c26aec85bf12a571c88db529..48c89571d9ffe7d88affc78daa4866461db6dd3a 100644 --- a/services/camera_service/BUILD.gn +++ b/services/camera_service/BUILD.gn @@ -68,6 +68,7 @@ ohos_shared_library("camera_service") { "src/param_update/camera_rotate_param_manager.cpp", "src/param_update/camera_rotate_param_reader.cpp", "src/param_update/camera_rotate_param_sign_tools.cpp", + "src/rss/suspend_state_observer.cpp", "src/smooth_zoom/cubic_bezier.cpp", "src/smooth_zoom/smooth_zoom.cpp", "src/window_manager_utils/camera_window_manager_agent.cpp", @@ -121,6 +122,7 @@ ohos_shared_library("camera_service") { "${multimedia_camera_framework_path}/services/camera_service/include/app_manager_utils", "${multimedia_camera_framework_path}/services/camera_service/include/camera_buffer_manager", "${multimedia_camera_framework_path}/services/camera_service/include/dfx", + "${multimedia_camera_framework_path}/services/camera_service/include/rss", "${multimedia_camera_framework_path}/services/camera_service/include/smooth_zoom", "${multimedia_camera_framework_path}/services/camera_service/include/param_update", "${multimedia_camera_framework_path}/services/camera_service/include/window_manager_utils", diff --git a/services/camera_service/include/hcamera_service.h b/services/camera_service/include/hcamera_service.h index ae7155232321dbe1ed69501f4576f0fff01ed60c..04a7e7ccf73807304b48cd498e8ab83224f6ce12 100644 --- a/services/camera_service/include/hcamera_service.h +++ b/services/camera_service/include/hcamera_service.h @@ -57,6 +57,7 @@ #include "ideferred_photo_processing_session_callback.h" #include "ideferred_photo_processing_session.h" #include "input/i_standard_camera_listener.h" +#include "suspend_state_observer.h" namespace OHOS { namespace CameraStandard { @@ -189,8 +190,12 @@ public: void OnFlashlightStatus(const string& cameraId, FlashStatus status) override; void OnTorchStatus(TorchStatus status) override; // for resource proxy - int32_t ProxyForFreeze(const std::set& pidList, bool isProxy) override; - int32_t ResetAllFreezeStatus() override; + [[deprecated]] int32_t ProxyForFreeze(const std::set& pidList, bool isProxy) override; + [[deprecated]] int32_t ResetAllFreezeStatus() override; + void InsertFrozenPidList(const std::vector& pidList); + void EraseActivePidList(const std::vector& pidList); + void ExecuteDelayCallbackTask(const std::vector& pidList); + int32_t GetDmDeviceInfo(std::vector &deviceInfos) override; int32_t GetCameraOutputStatus(int32_t pid, int32_t &status) override; bool ShouldSkipStatusUpdates(pid_t pid); @@ -215,6 +220,10 @@ protected: void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override; private: + void RegisterSuspendObserver(); + void UnregisterSuspendObserver(); + void ClearFreezedPidList(); + int32_t GetMuteModeFromDataShareHelper(bool &muteMode); bool SetMuteModeFromDataShareHelper(); void OnReceiveEvent(const EventFwk::CommonEventData &data); @@ -274,6 +283,7 @@ private: wptr cameraService_; }; + void ReportRssCameraStatus(const std::string& cameraId, int32_t status, const std::string& bundleName); void FillCameras(vector>& cameraInfos, vector& cameraIds, vector>& cameraAbilityList); shared_ptrGetCameraMetaInfo(std::string &cameraId, @@ -370,6 +380,9 @@ private: std::set freezedPidList_; std::map>> delayCbtaskMap_; std::map> delayFoldStatusCbTaskMap; + + std::mutex observerMutex_; + sptr suspendStateObserver_ {nullptr}; }; } // namespace CameraStandard } // namespace OHOS diff --git a/services/camera_service/include/rss/suspend_state_observer.h b/services/camera_service/include/rss/suspend_state_observer.h new file mode 100644 index 0000000000000000000000000000000000000000..caa5292c560792814cb8c7555356aa7ee81f364b --- /dev/null +++ b/services/camera_service/include/rss/suspend_state_observer.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025-2025 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_SUSPEND_STATE_OBSERVER_H +#define OHOS_CAMERA_SUSPEND_STATE_OBSERVER_H + +#include "suspend_state_observer_base_stub.h" + +namespace OHOS::CameraStandard { +class HCameraService; +class SuspendStateObserver : public ResourceSchedule::SuspendStateObserverBaseStub { +public: + explicit SuspendStateObserver(wptr service) : service_(service) {} + + virtual ErrCode OnActive(const std::vector &pidList, int32_t uid); + virtual ErrCode OnDoze(const std::vector &pidList, int32_t uid); + virtual ErrCode OnFrozen(const std::vector &pidList, int32_t uid); +private: + wptr service_; +}; +} // namespace OHOS::CameraStandard +#endif // OHOS_CAMERA_SUSPEND_STATE_OBSERVER_H \ No newline at end of file diff --git a/services/camera_service/src/hcamera_service.cpp b/services/camera_service/src/hcamera_service.cpp index 995505379ba0e93244e7442fcd95c6a1fa6736c4..e836fb7a8161ffe8a642b8e159aded401d7668e2 100644 --- a/services/camera_service/src/hcamera_service.cpp +++ b/services/camera_service/src/hcamera_service.cpp @@ -66,6 +66,7 @@ #include "camera_xcollie.h" #include "res_type.h" #include "res_sched_client.h" +#include "suspend_manager_base_client.h" #ifdef HOOK_CAMERA_OPERATOR #include "camera_rotate_plugin.h" #endif @@ -153,6 +154,7 @@ void HCameraService::OnStart() #ifdef NOTIFICATION_ENABLE AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID); #endif + AddSystemAbilityListener(RES_SCHED_SYS_ABILITY_ID); if (Publish(this)) { MEDIA_INFO_LOG("HCameraService publish OnStart sucess"); } else { @@ -163,6 +165,27 @@ void HCameraService::OnStart() MEDIA_INFO_LOG("HCameraService OnStart end"); } +void HCameraService::RegisterSuspendObserver() +{ + CAMERA_SYNC_TRACE; + MEDIA_INFO_LOG("HCameraService::RegisterSuspendObserver"); + std::lock_guard lock(observerMutex_); + if (suspendStateObserver_ == nullptr) { + suspendStateObserver_ = sptr::MakeSptr(this); + } + CHECK_RETURN_ELOG(suspendStateObserver_ == nullptr, "suspendStateObserver is null"); + ResourceSchedule::SuspendManagerBaseClient::GetInstance().RegisterSuspendObserver(suspendStateObserver_); +} + +void HCameraService::UnregisterSuspendObserver() +{ + CAMERA_SYNC_TRACE; + MEDIA_INFO_LOG("HCameraService::UnregisterSuspendObserver"); + std::lock_guard lock(observerMutex_); + ResourceSchedule::SuspendManagerBaseClient::GetInstance().UnregisterSuspendObserver(suspendStateObserver_); + suspendStateObserver_ = nullptr; +} + void HCameraService::OnDump() { MEDIA_INFO_LOG("HCameraService::OnDump called"); @@ -469,7 +492,10 @@ void HCameraService::OnAddSystemAbility(int32_t systemAbilityId, const std::stri CameraCommonEventManager::GetInstance()->SubscribeCommonEvent(COMMON_EVENT_RSS_MULTI_WINDOW_TYPE, std::bind(&HCameraService::OnReceiveEvent, this, std::placeholders::_1)); break; - + case RES_SCHED_SYS_ABILITY_ID: + MEDIA_INFO_LOG("OnAddSystemAbility RES_SCHED_SYS_ABILITY_ID"); + RegisterSuspendObserver(); + break; default: MEDIA_INFO_LOG("OnAddSystemAbility unhandled sysabilityId:%{public}d", systemAbilityId); break; @@ -484,6 +510,11 @@ void HCameraService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::s case DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID: CameraCommonEventManager::GetInstance()->UnSubscribeCommonEvent(COMMON_EVENT_DATA_SHARE_READY); break; + case RES_SCHED_SYS_ABILITY_ID: + MEDIA_INFO_LOG("OnRemoveSystemAbility RES_SCHED_SYS_ABILITY_ID"); + ClearFreezedPidList(); + UnregisterSuspendObserver(); + break; default: break; } @@ -1072,6 +1103,20 @@ void HCameraService::OnCameraStatus(const string& cameraId, CameraStatus status, CAMERA_SYSEVENT_BEHAVIOR( CreateMsg("OnCameraStatusChanged! for cameraId:%s, current Camera Status:%d", cameraId.c_str(), status)); } + ReportRssCameraStatus(cameraId, status, bundleName); +} + +void HCameraService::ReportRssCameraStatus(const std::string& cameraId, int32_t status, const std::string& bundleName) +{ + CAMERA_SYNC_TRACE; + MEDIA_INFO_LOG("HCameraService::ReportRssCameraStatus cameraId = %{public}s, status = %{public}d, " + "bundleName = %{public}s", cameraId.c_str(), status, bundleName.c_str()); + using namespace OHOS::ResourceSchedule; + std::unordered_map mapPayload; + mapPayload["camId"] = cameraId; + mapPayload["cameraStatus"] = std::to_string(status); + mapPayload["bundleName"] = bundleName; + ResSchedClient::GetInstance().ReportData(ResType::RES_TYPE_CAMERA_STATUS_CHANGED, 0, mapPayload); } void HCameraService::OnFlashlightStatus(const string& cameraId, FlashStatus status) @@ -2612,54 +2657,26 @@ int32_t HCameraService::UpdateSkinToneSetting(std::shared_ptr& pidList) { - std::string ret = "["; - for (const auto& pid : pidList) { - ret += std::to_string(pid) + ","; + std::ostringstream oss; + oss << '['; + for (auto it = pidList.begin(); it != pidList.end(); ++it) { + CHECK_EXECUTE(it != pidList.begin(), oss << ','); + oss << *it; } - ret += "]"; - return ret; + oss << ']'; + return oss.str(); } int32_t HCameraService::ProxyForFreeze(const std::set& pidList, bool isProxy) { - constexpr int32_t maxSaUid = 10000; - CHECK_RETURN_RET_ELOG(IPCSkeleton::GetCallingUid() >= maxSaUid, CAMERA_OPERATION_NOT_ALLOWED, "not allow"); - { - std::lock_guard lock(freezedPidListMutex_); - if (isProxy) { - freezedPidList_.insert(pidList.begin(), pidList.end()); - MEDIA_DEBUG_LOG("after freeze freezedPidList_:%{public}s", g_toString(freezedPidList_).c_str()); - return CAMERA_OK; - } else { - for (auto pid : pidList) { - freezedPidList_.erase(pid); - } - MEDIA_DEBUG_LOG("after unfreeze freezedPidList_:%{public}s", g_toString(freezedPidList_).c_str()); - } - } - - { - std::lock_guard lock(cameraCbMutex_); - std::for_each(pidList.begin(), pidList.end(), [this](auto pid) { - auto pidIt = delayCbtaskMap_.find(pid); - CHECK_RETURN(pidIt == delayCbtaskMap_.end()); - for (const auto &[cameraId, taskCallback] : pidIt->second) { - CHECK_EXECUTE(taskCallback, taskCallback()); - } - delayCbtaskMap_.erase(pidIt); - }); - } - return CAMERA_OK; + MEDIA_ERR_LOG("HCameraService::ProxyForFreeze is Deprecated"); + return CAMERA_OPERATION_NOT_ALLOWED; } int32_t HCameraService::ResetAllFreezeStatus() { - constexpr int32_t maxSaUid = 10000; - CHECK_RETURN_RET_ELOG(IPCSkeleton::GetCallingUid() >= maxSaUid, CAMERA_OPERATION_NOT_ALLOWED, "not allow"); - std::lock_guard lock(freezedPidListMutex_); - freezedPidList_.clear(); - MEDIA_INFO_LOG("freezedPidList_ has been clear"); - return CAMERA_OK; + MEDIA_ERR_LOG("HCameraService::ResetAllFreezeStatus is Deprecated"); + return CAMERA_OPERATION_NOT_ALLOWED; } int32_t HCameraService::GetDmDeviceInfo(std::vector &deviceInfos) @@ -2794,5 +2811,43 @@ int32_t HCameraService::GetCameraStorageSize(int64_t& size) cameraHostManager_->GetCameraStorageSize(userId, size); return CAMERA_OK; } + +void HCameraService::ClearFreezedPidList() +{ + std::lock_guard lock(freezedPidListMutex_); + freezedPidList_.clear(); + MEDIA_INFO_LOG("freezedPidList_ has been clear"); +} + +void HCameraService::InsertFrozenPidList(const std::vector& pidList) +{ + std::lock_guard lock(freezedPidListMutex_); + freezedPidList_.insert(pidList.begin(), pidList.end()); + MEDIA_DEBUG_LOG("after freeze freezedPidList_:%{public}s", g_toString(freezedPidList_).c_str()); +} + +void HCameraService::EraseActivePidList(const std::vector& pidList) +{ + std::lock_guard lock(freezedPidListMutex_); + for (auto pid : pidList) { + freezedPidList_.erase(pid); + } + MEDIA_DEBUG_LOG("after unfreeze freezedPidList_:%{public}s", g_toString(freezedPidList_).c_str()); +} + +void HCameraService::ExecuteDelayCallbackTask(const std::vector& pidList) +{ + CAMERA_SYNC_TRACE; + MEDIA_DEBUG_LOG("HCameraService::ExecuteDelayCallbackTask is called"); + std::lock_guard lock(cameraCbMutex_); + std::for_each(pidList.begin(), pidList.end(), [this](auto pid) -> void { + auto pidIt = delayCbtaskMap_.find(pid); + CHECK_RETURN(pidIt == delayCbtaskMap_.end()); + for (const auto &[cameraId, taskCallback] : pidIt->second) { + CHECK_EXECUTE(taskCallback, taskCallback()); + } + delayCbtaskMap_.erase(pidIt); + }); +} } // namespace CameraStandard } // namespace OHOS diff --git a/services/camera_service/src/rss/suspend_state_observer.cpp b/services/camera_service/src/rss/suspend_state_observer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eb14b32f5fe6420b6ecff6337860e5ecef79f574 --- /dev/null +++ b/services/camera_service/src/rss/suspend_state_observer.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025-2025 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. + */ + +#include "suspend_state_observer.h" +#include "hcamera_service.h" + +namespace OHOS::CameraStandard { +ErrCode SuspendStateObserver::OnActive(const std::vector &pidList, int32_t uid) +{ + MEDIA_DEBUG_LOG("SuspendStateObserver::OnActive is called"); + if (auto service = service_.promote()) { + service->EraseActivePidList(pidList); + service->ExecuteDelayCallbackTask(pidList); + } + return ERR_OK; +} + +ErrCode SuspendStateObserver::OnDoze(const std::vector &pidList, int32_t uid) +{ + (void)pidList; + (void)uid; + return ERR_OK; +} + +ErrCode SuspendStateObserver::OnFrozen(const std::vector &pidList, int32_t uid) +{ + MEDIA_DEBUG_LOG("SuspendStateObserver::OnFrozen is called"); + if (auto service = service_.promote()) { + service->InsertFrozenPidList(pidList); + } + return ERR_OK; +} +} // namespace OHOS::CameraStandard \ No newline at end of file diff --git a/services/etc/camera_service.cfg b/services/etc/camera_service.cfg index 69f71911c812fd88c8a3b2dd7cca4d940ddf5e35..392ca0b452a193be5f591a7d1224c509a1331b83 100644 --- a/services/etc/camera_service.cfg +++ b/services/etc/camera_service.cfg @@ -31,7 +31,7 @@ "ohos.permission.RECEIVE_UPDATE_MESSAGE", "ohos.permission.MANAGE_CAMERA_CONFIG", "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS", - "ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT" + "ohos.permission.GET_SUSPEND_STATE" ], "permission_acls" : [ "ohos.permission.GET_SENSITIVE_PERMISSIONS", diff --git a/test/fuzztest/hcamerahostmanager_fuzzer/BUILD.gn b/test/fuzztest/hcamerahostmanager_fuzzer/BUILD.gn index 5c6e30f38accb883d3a777b98153cdc182af18f4..a4c590bbc1ff9e446f5bbf8c9f70259e7116c2b4 100644 --- a/test/fuzztest/hcamerahostmanager_fuzzer/BUILD.gn +++ b/test/fuzztest/hcamerahostmanager_fuzzer/BUILD.gn @@ -50,6 +50,7 @@ ohos_fuzztest("HCameraHostManagerFuzzTest") { "${multimedia_camera_framework_path}/services/camera_service/src", "${multimedia_camera_framework_path}/services/camera_service/binder", "${multimedia_camera_framework_path}/services/camera_service/include/app_manager_utils", + "${multimedia_camera_framework_path}/services/camera_service/include/rss", "${multimedia_camera_framework_path}/services/camera_service/include/window_manager_utils", "${multimedia_camera_framework_path}/services/camera_service/binder/server/include/window_manager_service_callback_stub", "${multimedia_camera_framework_path}/services/camera_service/binder/base/include/window_manager_service_utils",