diff --git a/frameworks/napi/power/power_module.cpp b/frameworks/napi/power/power_module.cpp index 570a65c83d61d17afa004c181e5f56cbed64e398..09329e61d9038c22de4b800079f22866cdbc4d1e 100644 --- a/frameworks/napi/power/power_module.cpp +++ b/frameworks/napi/power/power_module.cpp @@ -92,7 +92,8 @@ static napi_value PowerInit(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("setPowerMode", PowerNapi::SetPowerMode), DECLARE_NAPI_FUNCTION("getPowerMode", PowerNapi::GetPowerMode), DECLARE_NAPI_FUNCTION("isStandby", PowerNapi::IsStandby), - DECLARE_NAPI_FUNCTION("setScreenOffTime", PowerNapi::SetScreenOffTime)}; + DECLARE_NAPI_FUNCTION("setScreenOffTime", PowerNapi::SetScreenOffTime), + DECLARE_NAPI_FUNCTION("refreshActivity", PowerNapi::RefreshActivity)}; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); CreateDevicePowerMode(env, exports); POWER_HILOGD(COMP_FWK, "The initialization of the Power module is complete"); diff --git a/frameworks/napi/power/power_napi.cpp b/frameworks/napi/power/power_napi.cpp index 46a68cea8a3d6bae3692fb35313e855177c6add5..801fb61ec9c7eebd41290772d7af1c6790972f15 100644 --- a/frameworks/napi/power/power_napi.cpp +++ b/frameworks/napi/power/power_napi.cpp @@ -37,6 +37,7 @@ constexpr uint32_t SET_MODE_PROMISE_MAX_ARGC = 1; constexpr uint32_t SUSPEND_MAX_ARGC = 1; constexpr uint32_t SET_SCREEN_OFFTIME_ARGC = 1; constexpr uint32_t HIBERNATE_ARGC = 1; +constexpr uint32_t REFRESH_ACTIVITY_ARGC = 1; constexpr int32_t INDEX_0 = 0; constexpr int32_t INDEX_1 = 1; constexpr int32_t RESTORE_DEFAULT_SCREENOFF_TIME = -1; @@ -363,5 +364,25 @@ napi_value PowerNapi::IsStandby(napi_env env, napi_callback_info info) NapiErrors error; return error.ThrowError(env, code); } + +napi_value PowerNapi::RefreshActivity(napi_env env, napi_callback_info info) +{ + size_t argc = REFRESH_ACTIVITY_ARGC; + napi_value argv[argc]; + NapiUtils::GetCallbackInfo(env, info, argc, argv); + + NapiErrors error; + if (argc != REFRESH_ACTIVITY_ARGC || !NapiUtils::CheckValueType(env, argv[INDEX_0], napi_string)) { + return error.ThrowError(env, PowerErrors::ERR_PARAM_INVALID); + } + + std::string reason = NapiUtils::GetStringFromNapi(env, argv[INDEX_0]); + PowerErrors code = g_powerMgrClient.RefreshActivity(UserActivityType::USER_ACTIVITY_TYPE_APPLICATION, reason); + if (code != PowerErrors::ERR_OK) { + POWER_HILOGE(FEATURE_ACTIVITY, "RefreshActivity failed. code:%{public}d", static_cast(code)); + return error.ThrowError(env, code); + } + return nullptr; +} } // namespace PowerMgr } // namespace OHOS diff --git a/frameworks/napi/power/power_napi.h b/frameworks/napi/power/power_napi.h index 714f006b3e1ff1eecf7a2042ba6be3243d348a50..b6af89630a09a330076191f72c5d3ebc34f64ca1 100644 --- a/frameworks/napi/power/power_napi.h +++ b/frameworks/napi/power/power_napi.h @@ -35,6 +35,7 @@ public: static napi_value GetPowerMode(napi_env env, napi_callback_info info); static napi_value IsStandby(napi_env env, napi_callback_info info); static napi_value SetScreenOffTime(napi_env env, napi_callback_info info); + static napi_value RefreshActivity(napi_env env, napi_callback_info info); private: static napi_value RebootOrShutdown(napi_env env, napi_callback_info info, bool isReboot); diff --git a/frameworks/napi/utils/napi_errors.cpp b/frameworks/napi/utils/napi_errors.cpp index 0b134747299daaf8da67adf53c2060efa1b7fa78..c5e2f10a71fe29d5d5dd48decf245577fd4090ca 100644 --- a/frameworks/napi/utils/napi_errors.cpp +++ b/frameworks/napi/utils/napi_errors.cpp @@ -22,7 +22,8 @@ std::map NapiErrors::errorTable_ = { {PowerErrors::ERR_CONNECTION_FAIL, "Failed to connect to the service."}, {PowerErrors::ERR_PERMISSION_DENIED, "Permission is denied" }, {PowerErrors::ERR_SYSTEM_API_DENIED, "System permission is denied" }, - {PowerErrors::ERR_PARAM_INVALID, "Invalid input parameter." } + {PowerErrors::ERR_PARAM_INVALID, "Invalid input parameter." }, + {PowerErrors::ERR_FREQUENT_FUNCTION_CALL, "Frequent function calls." } }; napi_value NapiErrors::GetNapiError(napi_env& env) const diff --git a/frameworks/native/power_mgr_client.cpp b/frameworks/native/power_mgr_client.cpp index 4538fb40f49f74860a201056e2ef5c80082d1a95..09178c1c92842250fb4af6c392768d7d3c59ffe1 100644 --- a/frameworks/native/power_mgr_client.cpp +++ b/frameworks/native/power_mgr_client.cpp @@ -637,5 +637,14 @@ PowerErrors PowerMgrClient::IsRunningLockEnabled(const RunningLockType type, boo return static_cast(powerError); } +PowerErrors PowerMgrClient::RefreshActivity(UserActivityType type, const std::string& refreshReason) +{ + sptr proxy = GetPowerMgrProxy(); + RETURN_IF_WITH_RET(proxy == nullptr, PowerErrors::ERR_CONNECTION_FAIL); + int32_t activityType = static_cast(type); + int32_t powerError = static_cast(PowerErrors::ERR_CONNECTION_FAIL); + proxy->RefreshActivityIpc(GetTickCount(), activityType, refreshReason, powerError); + return static_cast(powerError); +} } // namespace PowerMgr } // namespace OHOS diff --git a/interfaces/inner_api/IPowerMgr.idl b/interfaces/inner_api/IPowerMgr.idl index 9f32d5162c87c71d54d0ef48b4d48c67437b6c12..76cdef41da504fe01b1a5db8b02314ffad4eac5d 100644 --- a/interfaces/inner_api/IPowerMgr.idl +++ b/interfaces/inner_api/IPowerMgr.idl @@ -102,4 +102,7 @@ interface OHOS.PowerMgr.IPowerMgr { void UnRegisterRunningLockCallbackIpc([in] IPowerRunninglockCallback powerCallback); void IsRunningLockEnabledIpc([in] int lockType, [out] boolean lockEnabledResult, [out] int powerError); void IsForceSleepingIpc([out] boolean isForceSleeping); + + void RefreshActivityIpc([in] long callTimeMs, [in] int activityType, [in] String refreshReason, + [out] int powerError); } \ No newline at end of file diff --git a/interfaces/inner_api/native/include/power_errors.h b/interfaces/inner_api/native/include/power_errors.h index bf774a60d89ad46b82e64f85d744acb39f0b9fcf..cad8f80aff994473cd888b9a130054bea09bb8ec 100644 --- a/interfaces/inner_api/native/include/power_errors.h +++ b/interfaces/inner_api/native/include/power_errors.h @@ -24,7 +24,8 @@ enum class PowerErrors : int32_t { ERR_PERMISSION_DENIED = 201, ERR_SYSTEM_API_DENIED = 202, ERR_PARAM_INVALID = 401, - ERR_CONNECTION_FAIL = 4900101 + ERR_CONNECTION_FAIL = 4900101, + ERR_FREQUENT_FUNCTION_CALL = 4900201 }; } // namespace PowerMgr } // namespace OHOS diff --git a/interfaces/inner_api/native/include/power_mgr_client.h b/interfaces/inner_api/native/include/power_mgr_client.h index e7b54c295f3e4a64dc5e7e5ddbc5fb5a4b31f7da..bf33b7c0b3f7f371502c502735459dbdfb5c83a3 100644 --- a/interfaces/inner_api/native/include/power_mgr_client.h +++ b/interfaces/inner_api/native/include/power_mgr_client.h @@ -93,6 +93,15 @@ public: */ bool RefreshActivity(UserActivityType type = UserActivityType::USER_ACTIVITY_TYPE_OTHER); + /** + * Refresh the screentimeout time, and keep the screen on. RefreshActivity works only when the screen is on. + * + * @param type The RefreshActivity type, such as touch/button/accessibility and so on. + * @param refreshReason The reason to refresh the screentimeout time. + * @return PowerErrors::ERR_OK if the call success, otherwise return error code. + */ + PowerErrors RefreshActivity(UserActivityType type, const std::string& refreshReason); + /** * Windows overwrite timeout * @param timeout Specifies the timeout duration. diff --git a/interfaces/inner_api/native/include/power_state_machine_info.h b/interfaces/inner_api/native/include/power_state_machine_info.h index 294b466615c0b0fdc0aca3d76eb0a67006c7963e..5873e5edfba4f2d924fad1fb30143ef9fea1c57f 100644 --- a/interfaces/inner_api/native/include/power_state_machine_info.h +++ b/interfaces/inner_api/native/include/power_state_machine_info.h @@ -128,7 +128,8 @@ enum class UserActivityType : uint32_t { USER_ACTIVITY_TYPE_SOFTWARE = 5, USER_ACTIVITY_TYPE_SWITCH = 6, USER_ACTIVITY_TYPE_CABLE = 7, - USER_ACTIVITY_TYPE_MAX = USER_ACTIVITY_TYPE_CABLE, + USER_ACTIVITY_TYPE_APPLICATION = 8, + USER_ACTIVITY_TYPE_MAX = USER_ACTIVITY_TYPE_APPLICATION, }; // WakeupReasonType list diff --git a/services/native/include/power_mgr_service.h b/services/native/include/power_mgr_service.h index 42931ee9f27d52e061e891939a1edac0853ae406..07f89d2c62cd90aa5abd549feedd326f7502728f 100644 --- a/services/native/include/power_mgr_service.h +++ b/services/native/include/power_mgr_service.h @@ -135,6 +135,8 @@ public: virtual PowerErrors LockScreenAfterTimingOut( bool enabledLockScreen, bool checkLock, bool sendScreenOffEvent, const sptr& token) override; virtual PowerErrors IsRunningLockEnabled(const RunningLockType type, bool& result) override; + virtual PowerErrors RefreshActivity( + int64_t callTimeMs, UserActivityType type, const std::string& refreshReason) override; void SetEnableDoze(bool enable); void RegisterShutdownCallback(const sptr& callback, ShutdownPriority priority) override; diff --git a/services/native/include/power_mgr_service_ipc_adapter.h b/services/native/include/power_mgr_service_ipc_adapter.h index cec32cb22a3f0cb33d6120801eedcc9ab624b98f..39bbfc33d1b634c574b816f800bfbe9793d8974c 100644 --- a/services/native/include/power_mgr_service_ipc_adapter.h +++ b/services/native/include/power_mgr_service_ipc_adapter.h @@ -98,6 +98,8 @@ public: int32_t UnRegisterShutdownCallbackIpc(const sptr& callback) override; int32_t RegisterShutdownCallbackIpc(const sptr& callback, int32_t priorityValue) override; int32_t UnRegisterShutdownCallbackIpc(const sptr& callback) override; + virtual int32_t RefreshActivityIpc( + int64_t callTimeMs, int32_t activityType, const std::string& refreshReason, int32_t& powerError) override; virtual PowerErrors RebootDevice(const std::string& reason) = 0; virtual PowerErrors RebootDeviceForDeprecated(const std::string& reason) = 0; @@ -158,6 +160,8 @@ public: virtual PowerErrors LockScreenAfterTimingOut( bool enabledLockScreen, bool checkLock, bool sendScreenOffEvent, const sptr& token) = 0; virtual PowerErrors IsRunningLockEnabled(const RunningLockType type, bool& result) = 0; + virtual PowerErrors RefreshActivity( + int64_t callTimeMs, UserActivityType type, const std::string& refreshReason) = 0; virtual void RegisterShutdownCallback( const sptr& callback, ShutdownPriority priority) = 0; diff --git a/services/native/src/power_mgr_service.cpp b/services/native/src/power_mgr_service.cpp index 202188fe9c05ab743c5f8a22567e1ddf5918f9fa..1c9b864683cba951d88dfae28937f3c447d6f025 100644 --- a/services/native/src/power_mgr_service.cpp +++ b/services/native/src/power_mgr_service.cpp @@ -2431,5 +2431,25 @@ PowerErrors PowerMgrService::IsRunningLockEnabled(const RunningLockType type, bo result = num > 0 ? true : false; return PowerErrors::ERR_OK; } + +PowerErrors PowerMgrService::RefreshActivity( + int64_t callTimeMs, UserActivityType type, const std::string& refreshReason) +{ + if (!Permission::IsSystem()) { + POWER_HILOGI(FEATURE_ACTIVITY, "RefreshActivity failed, System permission intercept"); + return PowerErrors::ERR_SYSTEM_API_DENIED; + } + if (!Permission::IsPermissionGranted("ohos.permission.REFRESH_USER_ACTION")) { + POWER_HILOGI(FEATURE_ACTIVITY, "RefreshActivity failed, The caller does not have the permission"); + return PowerErrors::ERR_PERMISSION_DENIED; + } + pid_t pid = IPCSkeleton::GetCallingPid(); + auto uid = IPCSkeleton::GetCallingUid(); + POWER_HILOGI(FEATURE_ACTIVITY, + "Try to refresh activity, pid: %{public}d, uid: %{public}d, activity type: %{public}u, reason: %{public}s", + pid, uid, type, refreshReason.c_str()); + return RefreshActivityInner(callTimeMs, type, true) ? PowerErrors::ERR_OK : + PowerErrors::ERR_FREQUENT_FUNCTION_CALL; +} } // namespace PowerMgr } // namespace OHOS diff --git a/services/native/src/power_mgr_service_ipc_adapter.cpp b/services/native/src/power_mgr_service_ipc_adapter.cpp index 6e18c17db4ab6e4f3c12738407cd93e1b7804c9b..fea9c685f76cb9599cff6c1174bd264ce9e7e58c 100644 --- a/services/native/src/power_mgr_service_ipc_adapter.cpp +++ b/services/native/src/power_mgr_service_ipc_adapter.cpp @@ -445,5 +445,14 @@ int32_t PowerMgrServiceAdapter::IsForceSleepingIpc(bool& isForceSleeping) isForceSleeping = IsForceSleeping(); return ERR_OK; } + +int32_t PowerMgrServiceAdapter::RefreshActivityIpc( + int64_t callTimeMs, int32_t activityType, const std::string& refreshReason, int32_t& powerError) +{ + PowerXCollie powerXCollie("PowerMgrServiceAdapter::RefreshActivity LongIntStringInt", false); + UserActivityType type = static_cast(activityType); + powerError = static_cast(RefreshActivity(callTimeMs, type, refreshReason)); + return ERR_OK; +} } // namespace PowerMgr } // namespace OHOS diff --git a/test/fuzztest/refreshactivity_fuzzer/refreshactivity_fuzzer_test.cpp b/test/fuzztest/refreshactivity_fuzzer/refreshactivity_fuzzer_test.cpp index 2ebe2e37c3721eb27f6bfac109ba2144c35a826e..fcac6c43418a9e5f89eee1980a95aa2857a6b836 100644 --- a/test/fuzztest/refreshactivity_fuzzer/refreshactivity_fuzzer_test.cpp +++ b/test/fuzztest/refreshactivity_fuzzer/refreshactivity_fuzzer_test.cpp @@ -32,5 +32,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) PowerFuzzerTest g_serviceTest; uint32_t code = static_cast(IPowerMgrIpcCode::COMMAND_REFRESH_ACTIVITY_IPC); g_serviceTest.TestPowerServiceStub(code, data, size); + code = static_cast(IPowerMgrIpcCode::COMMAND_REFRESH_ACTIVITY_IPC_IN_LONG_IN_INT_IN_STRING_OUT_INT); + g_serviceTest.TestPowerServiceStub(code, data, size); return 0; } diff --git a/test/unittest/include/power_screenon_mock_test.h b/test/unittest/include/power_screenon_mock_test.h index 76f03f31066db3ce3922ba9e1d23f7f9620c1a51..c3f3f9e348a816927ee822649ad5a44fa2816e1a 100644 --- a/test/unittest/include/power_screenon_mock_test.h +++ b/test/unittest/include/power_screenon_mock_test.h @@ -23,6 +23,8 @@ class PowerScreenOnMockTest : public testing::Test { public: static void SetUpTestCase(); static void TearDownTestCase(); + void SetUp(); + void TearDown(); }; } // namespace PowerMgr } // namespace OHOS diff --git a/test/unittest/src/interface_test/power_mgr_client_test.cpp b/test/unittest/src/interface_test/power_mgr_client_test.cpp index b57a2dd3dda7bed9131682a1bdf11924ecf9c39d..6f974cc6ddbd1cf66c882b13b44f90ddec820c2a 100644 --- a/test/unittest/src/interface_test/power_mgr_client_test.cpp +++ b/test/unittest/src/interface_test/power_mgr_client_test.cpp @@ -1433,4 +1433,30 @@ HWTEST_F(PowerMgrClientTest, PowerMgrClient057, TestSize.Level2) EXPECT_EQ(powerMgrClient.IsForceSleeping(), false); POWER_HILOGI(LABEL_TEST, "PowerMgrClient057 function end!"); } + +/** + * @tc.name: PowerMgrClient058 + * @tc.desc: test RefreshActivity + * @tc.type: FUNC + * @tc.require: issueICPVG3 + */ +HWTEST_F(PowerMgrClientTest, PowerMgrClient058, TestSize.Level2) +{ + POWER_HILOGI(LABEL_TEST, "PowerMgrClient058 function start!"); + uint32_t PARM_TWO = 2; + auto& powerMgrClient = PowerMgrClient::GetInstance(); + + powerMgrClient.SuspendDevice(); + // Wakeup Device before test + powerMgrClient.WakeupDevice(); + EXPECT_EQ(powerMgrClient.IsScreenOn(), true) << "PowerMgrClient058: Prepare Fail, Screen is OFF."; + powerMgrClient.OverrideScreenOffTime(SCREEN_OFF_WAIT_TIME_MS); + usleep(SCREEN_OFF_WAIT_TIME_S * TRANSFER_NS_TO_MS / PARM_TWO); + EXPECT_EQ(powerMgrClient.IsScreenOn(), true) << "PowerMgrClient058: Prepare Fail, Screen is OFF."; + powerMgrClient.RefreshActivity(UserActivityType::USER_ACTIVITY_TYPE_APPLICATION, "PowerMgrClient058"); + usleep(SCREEN_OFF_WAIT_TIME_S * TRANSFER_NS_TO_MS / PARM_TWO + WAIT_SUSPEND_TIME_MS * TRANSFER_MS_TO_S); + EXPECT_EQ(powerMgrClient.IsScreenOn(), false) << "PowerMgrClient058: RefreshActivity Device Fail, Screen is OFF"; + powerMgrClient.OverrideScreenOffTime(PowerStateMachine::DEFAULT_SLEEP_TIME_MS); + POWER_HILOGI(LABEL_TEST, "PowerMgrClient058 function end!"); +} } // namespace \ No newline at end of file diff --git a/test/unittest/src/power_screenon_mock_test.cpp b/test/unittest/src/power_screenon_mock_test.cpp index 7f399425e4e48e825e1036cb82a362d999f3c10b..65951f796883f1a321fb61e459754efc7b0ea1a3 100644 --- a/test/unittest/src/power_screenon_mock_test.cpp +++ b/test/unittest/src/power_screenon_mock_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Copyright (c) 2023-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 @@ -41,6 +41,12 @@ static sptr g_service; static constexpr int32_t TEST_MODEL = 2; static constexpr int SLEEP_WAIT_TIME_S = 2; +namespace { +bool g_isSystem = true; +bool g_isPermissionGranted = true; +} // namespace + +namespace OHOS::PowerMgr { void PowerScreenOnMockTest::SetUpTestCase(void) { g_service = DelayedSpSingleton::GetInstance(); @@ -53,6 +59,18 @@ void PowerScreenOnMockTest::TearDownTestCase(void) DelayedSpSingleton::DestroyInstance(); } +void PowerScreenOnMockTest::SetUp(void) +{ + EXPECT_TRUE(g_isSystem); + EXPECT_TRUE(g_isPermissionGranted); +} + +void PowerScreenOnMockTest::TearDown(void) +{ + g_isSystem = true; + g_isPermissionGranted = true; +} + bool PowerMgrService::IsScreenOn(bool needPrintLog) { static uint32_t count = 0; @@ -67,8 +85,17 @@ bool PowerMgrService::IsScreenOn(bool needPrintLog) bool Permission::IsSystem() { - return true; + GTEST_LOG_(INFO) << "PowerScreenOnMockTest g_isSystem: " << g_isSystem; + return g_isSystem; +} + +bool Permission::IsPermissionGranted(const std::string& perm) +{ + GTEST_LOG_(INFO) << "PowerScreenOnMockTest IsPermissionGranted: " << g_isSystem; + return g_isPermissionGranted; } +} // namespace OHOS::PowerMgr + namespace { /** @@ -96,4 +123,33 @@ HWTEST_F(PowerScreenOnMockTest, PowerScreenOnMockTest001, TestSize.Level1) POWER_HILOGI(LABEL_TEST, "PowerScreenOnMockTest001 function end!"); GTEST_LOG_(INFO) << "PowerScreenOnMockTest001: end"; } + +/** + * @tc.name: PowerScreenOnMockTest002 + * @tc.desc: test RefreshActivity(exception) + * @tc.type: FUNC + * @tc.require: issueI7G6OY + */ +HWTEST_F(PowerScreenOnMockTest, PowerScreenOnMockTest002, TestSize.Level1) +{ + POWER_HILOGI(LABEL_TEST, "PowerScreenOnMockTest002 function start!"); + auto pmsTest = DelayedSpSingleton::GetInstance(); + if (pmsTest == nullptr) { + GTEST_LOG_(INFO) << "PowerScreenOnMockTest002: Failed to get PowerMgrService"; + } + pmsTest->Init(); + std::string reason = "PowerScreenOnMockTest002"; + PowerErrors ret = + pmsTest->RefreshActivity(GetTickCount(), UserActivityType::USER_ACTIVITY_TYPE_APPLICATION, reason); + EXPECT_EQ(ret, PowerErrors::ERR_OK); + ret = pmsTest->RefreshActivity(GetTickCount(), UserActivityType::USER_ACTIVITY_TYPE_APPLICATION, reason); + EXPECT_EQ(ret, PowerErrors::ERR_FREQUENT_FUNCTION_CALL); + g_isPermissionGranted = false; + ret = pmsTest->RefreshActivity(GetTickCount(), UserActivityType::USER_ACTIVITY_TYPE_APPLICATION, reason); + EXPECT_EQ(ret, PowerErrors::ERR_PERMISSION_DENIED); + g_isSystem = false; + ret = pmsTest->RefreshActivity(GetTickCount(), UserActivityType::USER_ACTIVITY_TYPE_APPLICATION, reason); + EXPECT_EQ(ret, PowerErrors::ERR_SYSTEM_API_DENIED); + POWER_HILOGI(LABEL_TEST, "PowerScreenOnMockTest002 function end!"); +} } // namespace \ No newline at end of file