一.应用端调用
import power from '@ohos.power';
power.shutdownDevice("shutdown_test");
import power from '@ohos.power';
power.shutdownDevice("shutdown_test");
二.客户端native调用
static napi_module g_module 定义了模块的属性.
定义模块模块名:nm_modname,JS应用层通过这个模块名调用。
接口注册函数:nm_register_func,在此函数中注册本模块要导出的接口。
使用DECLARE_NAPI_FUNCTION(“js函数名”, c++实现函数名)定义接口函数
DECLARE_NAPI_FUNCTION("rebootDevice", RebootDevice)
base/powermgr/power_manager/frameworks/napi/power/power.cpp
EXTERN_C_START
/*
* function for module exports
*/
static napi_value PowerInit(napi_env env, napi_value exports)
{
POWER_HILOGD(MODULE_JS_NAPI, "%{public}s: enter", __func__);
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("shutdownDevice", ShutdownDevice),
DECLARE_NAPI_FUNCTION("rebootDevice", RebootDevice),
DECLARE_NAPI_FUNCTION("isScreenOn", IsScreenOn),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
POWER_HILOGD(MODULE_JS_NAPI, "%{public}s: exit", __func__);
return exports;
}
EXTERN_C_END
/*
* Module definition
*/
定义模块
模块名:nm_modname,JS应用层通过这个模块名调用。
接口注册函数:nm_register_func,在此函数中注册本模块要导出的接口。
static napi_module g_module = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = "power",
.nm_register_func = PowerInit,
.nm_modname = "power",
.nm_priv = ((void *)0),
.reserved = {0}
};
注册模块,加载动态库时自动调用注册。
/*
* Module registration
*/
extern "C" __attribute__((constructor)) void RegisterPowerModule(void)
{
napi_module_register(&g_module);
}
对传入参数进行校验和转换成c/c++类型,具体代码位置见注释.
base/powermgr/power_manager/frameworks/napi/power/power.cpp
static napi_value RebootDevice(napi_env env, napi_callback_info info)
{
return RebootOrShutdown(env, info, true);
}
static napi_value RebootOrShutdown(napi_env env, napi_callback_info info, bool isReboot)
{
POWER_HILOGD(MODULE_JS_NAPI, "%{public}s: enter, %{public}s", __func__, isReboot ? "reboot" : "shutdown");
size_t argc = 1;
napi_value args[1] = { 0 };
napi_value jsthis;
void *data = nullptr;
napi_status status = napi_get_cb_info(env, info, &argc, args, &jsthis, &data);
NAPI_ASSERT(env, (status == napi_ok) && (argc >= 1), "failed to get cb info"); //校验传入参数个数
napi_valuetype type = napi_undefined;
NAPI_CALL(env, napi_typeof(env, args[0], &type)); //获取js传入类型
NAPI_ASSERT(env, type == napi_string, "wrong argument type. string expected."); //校验传入参数类型
char reason[REASON_MAX] = { 0 };
size_t reasonLen = 0;
status = napi_get_value_string_utf8(env, args[0], reason, REASON_MAX - 1, &reasonLen); //接受到参数转换成c/c++类型
if (status != napi_ok) {
POWER_HILOGE(MODULE_JS_NAPI, "%{public}s: get reason failed", __func__);
return nullptr;
}
if (isReboot) {
g_powerMgrClient.RebootDevice(std::string(reason));
} else {
g_powerMgrClient.ShutDownDevice(std::string(reason));
}
POWER_HILOGD(MODULE_JS_NAPI, "%{public}s: reason %{public}s, exit", __func__, reason);
return nullptr;
}
PowerMgrProxy对象会将重启的请求以IPC方式发送给电源管理服务提供端PowerMgrStub对象处理
base/powermgr/power_manager/frameworks/native/power_mgr_client.cpp
void PowerMgrClient::RebootDevice(const std::string& reason)
{
RETURN_IF(Connect() != ERR_OK);
POWER_HILOGE(MODULE_INNERKIT, "%{public}s called.", __func__);
proxy_->RebootDevice(reason);
}
PowerMgrProxy给电源管理服务发送请求
base/powermgr/power_manager/services/zidl/src/power_mgr_proxy.cpp
void PowerMgrProxy::RebootDevice(const std::string& reason)
{
sptr<IRemoteObject> remote = Remote();
RETURN_IF(remote == nullptr);
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(PowerMgrProxy::GetDescriptor())) {
POWER_HILOGE(MODULE_INNERKIT, "PowerMgrProxy::%{public}s write descriptor failed!", __func__);
return;
}
WRITE_PARCEL_NO_RET(data, String16, Str8ToStr16(reason));
int ret = remote->SendRequest(static_cast<int>(IPowerMgr::REBOOT_DEVICE), data, reply, option);
if (ret != ERR_OK) {
POWER_HILOGE(MODULE_INNERKIT, "PowerMgrProxy::%{public}s Transact is failed, error code: %d", __func__, ret);
}
}
三.电源服务内调用
电源管理服务是被加载到foundation的进程内
通过消息码匹配对应的业务函数,并调用,这里匹配的是RebootDeviceStub
base/powermgr/power_manager/services/zidl/src/power_mgr_stub.cpp
int PowerMgrStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
MessageParcel &reply, MessageOption &option)
{
POWER_HILOGD(MODULE_SERVICE,
"PowerMgrStub::OnRemoteRequest, cmd = %{public}u, flags= %{public}d", code, option.GetFlags());
std::u16string descripter = PowerMgrStub::GetDescriptor();
std::u16string remoteDescripter = data.ReadInterfaceToken();
if (descripter != remoteDescripter) {
POWER_HILOGE(MODULE_SERVICE,
"PowerMgrStub::OnRemoteRequest failed, descriptor is not matched!");
return E_GET_POWER_SERVICE_FAILED;
}
const int DFX_DELAY_MS = 10000;
int id = HiviewDFX::XCollie::GetInstance().SetTimer("PowerMgrStub", DFX_DELAY_MS, nullptr, nullptr,
HiviewDFX::XCOLLIE_FLAG_NOOP);
int ret = ERR_OK;
switch (code) {
case static_cast<int>(IPowerMgr::WAKEUP_DEVICE):
ret = WakeupDeviceStub(data);
break;
case static_cast<int>(IPowerMgr::SUSPEND_DEVICE):
ret = SuspendDeviceStub(data);
break;
case static_cast<int>(IPowerMgr::REFRESH_ACTIVITY):
ret = RefreshActivityStub(data);
break;
case static_cast<int>(IPowerMgr::REBOOT_DEVICE):
ret = RebootDeviceStub(data);
break;
case static_cast<int>(IPowerMgr::SHUTDOWN_DEVICE):
ret = ShutDownDeviceStub(data);
break;
......
......
default:
ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
HiviewDFX::XCollie::GetInstance().CancelTimer(id);
return ret;
}
int32_t PowerMgrStub::RebootDeviceStub(MessageParcel& data)
{
std::string reason = Str16ToStr8(data.ReadString16());
RebootDevice(reason);
return ERR_OK;
}
在RebootDevice方法中会判断相关的权限,以及调用ShutdownService对象的Reboot方法
base/powermgr/power_manager/services/native/src/power_mgr_service.cpp
void PowerMgrService::RebootDevice(const std::string& reason)
{
std::lock_guard lock(mutex_);
pid_t pid = IPCSkeleton::GetCallingPid();
auto uid = IPCSkeleton::GetCallingUid();
if (reason.find("updater") != std::string::npos) {
if (!Permission::CheckCallingPermission("ohos.permission.REBOOT_RECOVERY")) {
POWER_HILOGE(MODULE_SERVICE,
"%{public}s Request failed, %{public}d permission check fail",
__func__, pid);
return;
}
} else {
if (!Permission::CheckIsSystemAppByUid(uid)
&& !Permission::CheckCallingPermission("ohos.permission.REBOOT")) {
POWER_HILOGE(MODULE_SERVICE,
"%{public}s Request failed, %{public}d permission check fail",
__func__, pid);
return;
}
}
POWER_HILOGI(MODULE_SERVICE, "Cancel auto sleep timer");
powerStateMachine_->CancelDelayTimer(
PowermsEventHandler::CHECK_USER_ACTIVITY_TIMEOUT_MSG);
powerStateMachine_->CancelDelayTimer(
PowermsEventHandler::CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG);
powerStateMachine_->CancelDelayTimer(
PowermsEventHandler::CHECK_USER_ACTIVITY_SLEEP_TIMEOUT_MSG);
POWER_HILOGI(MODULE_SERVICE, "PID: %{public}d Call %{public}s !", pid, __func__);
shutdownService_.Reboot(reason);
}
base/powermgr/power_manager/services/native/src/shutdown_service.cpp
void ShutdownService::Reboot(const std::string& reason)
{
RebootOrShutdown(reason, true);
}
void ShutdownService::RebootOrShutdown(const std::string& reason, bool isReboot)
{
if (started_) {
POWER_HILOGE(MODULE_SERVICE, "Shutdown is already running.");
return;
}
started_ = true;
make_unique<thread>([=] {
Prepare();
POWER_HILOGD(MODULE_SERVICE, "reason = %{public}s, reboot = %{public}d", reason.c_str(), isReboot);
if (devicePowerAction_ != nullptr) {
isReboot ? devicePowerAction_->Reboot(reason) : devicePowerAction_->Shutdown(reason);
}
started_ = false;
})->detach();
}
执行系统调用,进行Reboot操作
base/powermgr/power_manager/services/native/src/actions/default/device_power_action.cpp
void DevicePowerAction::Reboot(const std::string& reason)
{
std::string rebootReason = Updater(reason);
POWER_HILOGI(MODULE_SERVICE, "Reboot executing.");
DoReboot(rebootReason.c_str());
}