Open Harmony 重启调用过程

一.应用端调用

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());
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值