• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ohos.power.proj.hpp"
17 #include "ohos.power.impl.hpp"
18 #include "taihe/runtime.hpp"
19 #include "stdexcept"
20 #include "power_common.h"
21 #include "power_log.h"
22 #include "power_mgr_client.h"
23 #include <fcntl.h>
24 #include <sys/ioctl.h>
25 #include <unistd.h>
26 #include "app_manager_utils.h"
27 
28 #define SET_REBOOT _IOW(BOOT_DETECTOR_IOCTL_BASE, 109, int)
29 
30 using namespace taihe;
31 using namespace ohos::power;
32 using namespace OHOS::PowerMgr;
33 
34 namespace {
35 std::map<PowerErrors, std::string> g_errorTable = {
36     {PowerErrors::ERR_CONNECTION_FAIL,   "Failed to connect to the service."},
37     {PowerErrors::ERR_PERMISSION_DENIED, "Permission is denied"             },
38     {PowerErrors::ERR_SYSTEM_API_DENIED, "System permission is denied"      },
39     {PowerErrors::ERR_PARAM_INVALID,     "Invalid input parameter."         }
40 };
41 static PowerMgrClient& g_powerMgrClient = PowerMgrClient::GetInstance();
42 constexpr int32_t RESTORE_DEFAULT_SCREENOFF_TIME = -1;
43 
SetFrameworkBootStage(bool isReboot)44 static void SetFrameworkBootStage(bool isReboot)
45 {
46     int fd = open("/dev/bbox", O_WRONLY);
47     if (fd < 0) {
48         POWER_HILOGE(FEATURE_SHUTDOWN, "open /dev/bbox failed!");
49         return;
50     }
51 
52     fdsan_exchange_owner_tag(fd, 0, DOMAIN_FEATURE_SHUTDOWN);
53     POWER_HILOGI(FEATURE_SHUTDOWN, "Set shutdown fw start timeout.");
54 
55     int rebootFlag = isReboot ? 1 : 0;
56     int ret = ioctl(fd, SET_REBOOT, &rebootFlag);
57     if (ret < 0) {
58         POWER_HILOGE(FEATURE_SHUTDOWN, "set reboot flag failed!");
59         fdsan_close_with_tag(fd, DOMAIN_FEATURE_SHUTDOWN);
60         return;
61     }
62 
63     int stage = SHUT_STAGE_FRAMEWORK_START;
64     ret = ioctl(fd, SET_SHUT_STAGE, &stage);
65     if (ret < 0) {
66         POWER_HILOGE(FEATURE_SHUTDOWN, "set shut stage failed!");
67     }
68 
69     POWER_HILOGI(FEATURE_SHUTDOWN, "Set shutdown timeout mechanism started.");
70     fdsan_close_with_tag(fd, DOMAIN_FEATURE_SHUTDOWN);
71 
72     return;
73 }
74 
Shutdown(string_view reason)75 void Shutdown(string_view reason)
76 {
77     SetFrameworkBootStage(false);
78     POWER_HILOGD(FEATURE_SHUTDOWN, "reboot: %{public}d, reason: %{public}s", false, reason.c_str());
79     PowerErrors code = g_powerMgrClient.ShutDownDevice(std::string(reason));
80     if (code != PowerErrors::ERR_OK && code != PowerErrors::ERR_FAILURE) {
81         taihe::set_business_error(static_cast<int32_t>(code), g_errorTable[code]);
82     }
83 }
84 
Reboot(string_view reason)85 void Reboot(string_view reason)
86 {
87     SetFrameworkBootStage(true);
88     POWER_HILOGD(FEATURE_SHUTDOWN, "reboot: %{public}d, reason: %{public}s", true, reason.c_str());
89     PowerErrors code = g_powerMgrClient.RebootDevice(std::string(reason));
90     if (code != PowerErrors::ERR_OK && code != PowerErrors::ERR_FAILURE) {
91         taihe::set_business_error(static_cast<int32_t>(code), g_errorTable[code]);
92     }
93 }
94 
IsActive()95 bool IsActive()
96 {
97     return g_powerMgrClient.IsScreenOn();
98 }
99 
Wakeup(string_view detail)100 void Wakeup(string_view detail)
101 {
102     POWER_HILOGD(FEATURE_WAKEUP, "Wakeup type: APPLICATION, reason: %{public}s", detail.c_str());
103     int32_t apiVersion = AppManagerUtils::GetApiTargetVersion();
104     PowerErrors code = g_powerMgrClient.WakeupDevice(
105         WakeupDeviceType::WAKEUP_DEVICE_APPLICATION, std::string(detail), std::to_string(apiVersion));
106     if (code != PowerErrors::ERR_OK && code != PowerErrors::ERR_FAILURE) {
107         taihe::set_business_error(static_cast<int32_t>(code), g_errorTable[code]);
108     }
109 }
110 
Suspend(optional_view<bool> isImmediate)111 void Suspend(optional_view<bool> isImmediate)
112 {
113     bool isForce = isImmediate.value_or(false);
114 
115     PowerErrors code;
116     int32_t apiVersion = AppManagerUtils::GetApiTargetVersion();
117     if (isForce) {
118         code = g_powerMgrClient.ForceSuspendDevice(std::to_string(apiVersion));
119     } else {
120         code = g_powerMgrClient.SuspendDevice(
121             SuspendDeviceType::SUSPEND_DEVICE_REASON_APPLICATION, false, std::to_string(apiVersion));
122     }
123     if (code != PowerErrors::ERR_OK && code != PowerErrors::ERR_FAILURE) {
124         POWER_HILOGE(FEATURE_SUSPEND, "Suspend Device fail, isForce:%{public}d", isForce);
125         taihe::set_business_error(static_cast<int32_t>(code), g_errorTable[code]);
126     }
127 }
128 
GetPowerMode()129 DevicePowerMode GetPowerMode()
130 {
131     PowerMode mode = g_powerMgrClient.GetDeviceMode();
132     DevicePowerMode deviceMode(DevicePowerMode::key_t::MODE_NORMAL);
133     switch (mode) {
134         case PowerMode::NORMAL_MODE:
135             deviceMode = DevicePowerMode::key_t::MODE_NORMAL;
136             break;
137         case PowerMode::POWER_SAVE_MODE:
138             deviceMode = DevicePowerMode::key_t::MODE_POWER_SAVE;
139             break;
140         case PowerMode::PERFORMANCE_MODE:
141             deviceMode = DevicePowerMode::key_t::MODE_PERFORMANCE;
142             break;
143         case PowerMode::EXTREME_POWER_SAVE_MODE:
144             deviceMode = DevicePowerMode::key_t::MODE_EXTREME_POWER_SAVE;
145             break;
146         default:
147             POWER_HILOGE(FEATURE_POWER_MODE, "Unknown mode");
148     }
149     return deviceMode;
150 }
151 
SetPowerModeSync(DevicePowerMode mode)152 void SetPowerModeSync(DevicePowerMode mode)
153 {
154     PowerErrors code = g_powerMgrClient.SetDeviceMode(PowerMode(static_cast<uint32_t>(mode)));
155     if (code != PowerErrors::ERR_OK && code != PowerErrors::ERR_FAILURE) {
156         taihe::set_business_error(static_cast<int32_t>(code), g_errorTable[code]);
157     }
158 }
159 
IsStandby()160 bool IsStandby()
161 {
162     bool isStandby = false;
163     PowerErrors code = g_powerMgrClient.IsStandby(isStandby);
164     if (code != PowerErrors::ERR_OK && code != PowerErrors::ERR_FAILURE) {
165         taihe::set_business_error(static_cast<int32_t>(code), g_errorTable[code]);
166     }
167     return isStandby;
168 }
169 
Hibernate(bool clearMemory)170 void Hibernate(bool clearMemory)
171 {
172     int32_t apiVersion = AppManagerUtils::GetApiTargetVersion();
173     PowerErrors code = g_powerMgrClient.Hibernate(clearMemory, "", std::to_string(apiVersion));
174     if (code != PowerErrors::ERR_OK && code != PowerErrors::ERR_FAILURE) {
175         POWER_HILOGE(FEATURE_WAKEUP, "Hibernate failed.");
176         taihe::set_business_error(static_cast<int32_t>(code), g_errorTable[code]);
177     }
178 }
179 
SetScreenOffTime(int64_t timeout)180 void SetScreenOffTime(int64_t timeout)
181 {
182     if (timeout == 0 || (timeout < 0 && timeout != RESTORE_DEFAULT_SCREENOFF_TIME)) {
183         POWER_HILOGE(FEATURE_WAKEUP, "timeout is not right.");
184         taihe::set_business_error(
185             static_cast<int32_t>(PowerErrors::ERR_PARAM_INVALID), g_errorTable[PowerErrors::ERR_PARAM_INVALID]);
186     }
187 
188     PowerErrors code;
189     int32_t apiVersion = AppManagerUtils::GetApiTargetVersion();
190     if (timeout == RESTORE_DEFAULT_SCREENOFF_TIME) {
191         code = g_powerMgrClient.RestoreScreenOffTime(std::to_string(apiVersion));
192     } else {
193         code = g_powerMgrClient.OverrideScreenOffTime(timeout, std::to_string(apiVersion));
194     }
195     if (code != PowerErrors::ERR_OK && code != PowerErrors::ERR_FAILURE) {
196         POWER_HILOGE(FEATURE_WAKEUP, "SetScreenOffTime failed.");
197         taihe::set_business_error(static_cast<int32_t>(code), g_errorTable[code]);
198     }
199 }
200 }  // namespace
201 
202 // Since these macros are auto-generate, lint will cause false positive
203 // NOLINTBEGIN
204 TH_EXPORT_CPP_API_Shutdown(Shutdown);
205 TH_EXPORT_CPP_API_Reboot(Reboot);
206 TH_EXPORT_CPP_API_IsActive(IsActive);
207 TH_EXPORT_CPP_API_Wakeup(Wakeup);
208 TH_EXPORT_CPP_API_Suspend(Suspend);
209 TH_EXPORT_CPP_API_GetPowerMode(GetPowerMode);
210 TH_EXPORT_CPP_API_SetPowerModeSync(SetPowerModeSync);
211 TH_EXPORT_CPP_API_IsStandby(IsStandby);
212 TH_EXPORT_CPP_API_Hibernate(Hibernate);
213 TH_EXPORT_CPP_API_SetScreenOffTime(SetScreenOffTime);
214 // NOLINTEND