#夏日挑战赛#OpenHarmony源码解析之开关机流程分析 原创 精华

深开鸿
发布于 2022-7-29 14:17
浏览
3收藏

本文正在参加星光计划3.0–夏日挑战赛
作者:严明舟

本文以OpenHarmony 3.1 Release - powermgr_power_manager源码为基础进行分析。

1 简介

电源管理服务组件是OpenHarmony电源管理子系统的一个组件,主要负责如下功能:

  1. 系统关机
  2. 重启设备
  3. 检测当前设备的亮灭屏状态
  4. 查询系统是否支持该类型的锁
  5. 创建RunningLock锁
  6. 锁定和持有RunningLock锁
  7. 释放RunningLock锁
  8. 查询当前RunningLock锁是持有状态,还是释放状态
  9. 系统休眠和唤醒以及屏幕开关

本文主要分析开关机功能,包括NAPI接口以及功能实现的整个流程。

图1 电源管理子系统架构图

#夏日挑战赛#OpenHarmony源码解析之开关机流程分析-鸿蒙开发者社区

图2 电源管理服务组件架构图

#夏日挑战赛#OpenHarmony源码解析之开关机流程分析-鸿蒙开发者社区

2 电源管理服务组件代码目录

/base/powermgr/power_manager
├── figures                  	# 架构图
├── frameworks                  # FrameWork层
│   ├── dialog                  # Dialog 资源文件
│   ├── include                 # 头文件
│   ├── napi                  	# NAPI
│   └── native                  # Native层
├── interfaces                  # 接口层
│   ├── innerkits               # 内部接口
│   └── kits                    # 外置接口
├── sa_profile                  # SA 配置文件
├── services                    # 服务层
│   ├── native                  # Native 层
│   └── zidl                    # zidl 接口层
├── test                        # 测试用例
└── utils                       # 工具和通用层

3 开关机整体流程

#夏日挑战赛#OpenHarmony源码解析之开关机流程分析-鸿蒙开发者社区

流程描述:

  1. JavaScript应用调用shutdownDevice执行系统关机功能;
  2. shutdownDevice调用power.cpp注册的NAPI接口ShutdownDevice,ShutdownDevice接口进一步调用NAPI封装的RebootOrShutdown方法,RebootOrShutdown会根据true或false参数,决定是调用PowerMgrClient的系统关机ShutDownDevice方法还是重启设备RebootDevice方法;
  3. ShutDownDevice首先会调用Connect方法,Connect会通过GetSystemAbilityManager方法获取SystemAbilityManager实例,然后通过CheckSystemAbility方法检查对应的SA是否存在,并返回remoteObject对象,最后通过iface_cast构造proxy对象,此时创建了PowerMgrProxy实例,最后ShutDownDevice调用PowerMgrProxy的ShutDownDevice方法;
  4. 电源管理服务代理请求端PowerMgrProxy的ShutDownDevice方法调用SendRequest方法向电源管理服务提供端PowerMgrStub发送系统关机请求;
  5. 电源管理服务提供端PowerMgrStub接收到系统关机请求后,调用ShutDownDeviceStub方法;
  6. PowerMgrService继承PowerMgrStub的ShutDownDeviceStub方法,并进一步调用PowerMgrService的ShutDownDevice方法;
  7. ShutDownDevice首先判断是否持有系统APP的uid权限,以及是否持有"ohos.permission.REBOOT"的权限,随后执行ShutdownService的Shutdown方法;
  8. Shutdown方法进一步执行ShutdownService的RebootOrShutdown方法,根据true或false决定是执行Reboot或Shutdown;
  9. 在Shutdown方法中会通过系统调用方法DoReboot执行shutdown命令;

日志

ShutdownDevice
01-01 06:36:32.772  1200  1209 D 02907/PowerMgrJSNAPI: [power.cpp] RebootOrShutdown# RebootOrShutdown: enter, reboot
01-01 06:36:32.772  1200  1209 E 02900/PowerMgrClient: [power_mgr_client.cpp] RebootDevice# ymz PowerMgrClient::RebootDevice called.
01-01 06:36:32.772  1200  1209 E 02900/PowerMgrClient: [power_mgr_client.cpp] Connect# ymz PowerMgrClient::Connect called.
01-01 06:36:32.772  1200  1209 E 02900/PowerMgrClient: [power_mgr_proxy.cpp] RebootDevice# ymz PowerMgrProxy::RebootDevice called!
01-01 06:45:13.576   373   373 D 02901/PowerMgrService: [power_mgr_stub.cpp] RebootDeviceStub# ymz PowerMgrStub::RebootDeviceStub called!
01-01 06:45:13.576   373   373 I 02901/PowerMgrService: [power_mgr_service.cpp] RebootDevice# ymz PowerMgrService::RebootDevice called!
01-01 06:45:13.576   373   373 I 02901/PowerMgrService: [shutdown_service.cpp] Reboot# ymz ShutdownService::Reboot called!
01-01 06:45:13.576   373   373 I 02901/PowerMgrService: [shutdown_service.cpp] RebootOrShutdown# ymz ShutdownService::RebootOrShutdown called!

3.1 电源管理服务注册

  1. 调用System Ability的MakeAndRegisterAbility接口注册Power Manager Service实例
//OpenHarmony/base/powermgr/power_manager/services/native/src/power_mgr_service.cpp

auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(pms.GetRefPtr());
  1. System Ability调用Power Manager Service的OnStart函数实现电源管理服务组件的启动
//OpenHarmony/base/powermgr/power_manager/services/native/src/power_mgr_service.cpp

void PowerMgrService::OnStart()
{
    POWER_HILOGI(MODULE_SERVICE, "OnStart enter.");
    //如果Power Manager Service已启动,则返回(单实例)
    if (//OpenHarmony/base/powermgr/power_manager/services/native/src/power_mgr_service.cppready_) {
        
        
        POWER_HILOGE(MODULE_SERVICE, "OnStart is ready, nothing to do.");
        return;
    }

    //初始化操作较复杂,需进一步展开解析
    if (!Init()) {
        POWER_HILOGE(MODULE_SERVICE, "OnStart call init fail");
        return;
    }
    
    //将Power Manager Service服务发布到System Ability,此时PowerMgrService成为了电源管理服务提供端
    if (!Publish(DelayedSpSingleton<PowerMgrService>::GetInstance())) {
        POWER_HILOGE(MODULE_SERVICE, "OnStart register to system ability manager failed.");
        return;
    }
    
    //标记Power Manager Service服务已启动
    ready_ = true;
    POWER_HILOGI(MODULE_SERVICE, "OnStart and add system ability success.");
}
  1. PowerMgrService的初始化
//OpenHarmony/base/powermgr/power_manager/services/native/src/power_mgr_service.cpp

bool PowerMgrService::Init()
{
    POWER_HILOGI(MODULE_SERVICE, "Init start");

    //创建eventRunner
    if (!eventRunner_) {
        eventRunner_ = AppExecFwk::EventRunner::Create(POWERMGR_SERVICE_NAME);
        if (eventRunner_ == nullptr) {
            POWER_HILOGE(MODULE_SERVICE, "Init failed due to create EventRunner");
            return false;
        }
    }

    //创建PowermsEventHandler实例
    if (!handler_) {
        handler_ = std::make_shared<PowermsEventHandler>(eventRunner_, pms);
        std::string handlerName("PowerMgrEventHandler");
        HiviewDFX::Watchdog::GetInstance().AddThread(handlerName, handler_, WATCH_DOG_DELAY_MS);
    }

    //创建RunningLockMgr实例
    if (!runningLockMgr_) {
        runningLockMgr_ = std::make_shared<RunningLockMgr>(pms);
    }
    
    //执行RunningLockMgr的初始化,并创建RunningLockAction实例
    if (!runningLockMgr_->Init()) {
        POWER_HILOGE(MODULE_SERVICE, "OnStart init fail");
        return false;
    }
    
    //创建PowerStateMachine实例,执行PowerStateMachine的初始化,并创建PowerMgrNotify实例以及执行它的RegisterPublishEvents方法
    if (!PowerStateMachineInit()) {
        POWER_HILOGE(MODULE_SERVICE, "power state machine init fail!");
    }
    
    //创建PowerSaveMode实例
    if (DelayedSpSingleton<PowerSaveMode>::GetInstance()) {
        powerModeModule_.EnableMode(powerModeModule_.GetModeItem());
    } else {
        POWER_HILOGE(MODULE_SERVICE, "power mode init fail!");
    }
    
    //执行PowermsEventHandler的SendEvent方法
    handler_->SendEvent(PowermsEventHandler::INIT_KEY_MONITOR_MSG, 0, INIT_KEY_MONITOR_DELAY_MS);
    POWER_HILOGI(MODULE_SERVICE, "Init success");
    return true;
}

3.2 开关机NAPI接口定义及实现

  1. NAPI接口声明
//OpenHarmony/base/powermgr/power_manager/interfaces/kits/js/@ohos.power.d.ts

import {AsyncCallback} from './basic';

declare namespace power {
	...
	function shutdownDevice(reason: string): void;
	...
}
export default power;
  1. NAPI接口实现,NAPI接口shutdownDevice会进一步调用NAPI封装的RebootOrShutdown方法,RebootOrShutdown会根据true或false参数,决定是调用PowerMgrClient的系统关机ShutDownDevice方法还是重启设备RebootDevice方法
//OpenHarmony/base/powermgr/power_manager/frameworks/napi/power/power.cpp

//模块初始化
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),
        ...
    };
    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;
}

//开关机接口NAPI实现
static napi_value ShutdownDevice(napi_env env, napi_callback_info info)
{
    POWER_HILOGE(MODULE_JS_NAPI, "ymz %{public}s called.", __func__);
    return RebootOrShutdown(env, info, false);
}

static napi_value RebootOrShutdown(napi_env env, napi_callback_info info, bool isReboot)
{
    POWER_HILOGD(MODULE_JS_NAPI, "ymz %{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));
    //读取并检查入参
    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);
    //读取并检查入参
    if (status != napi_ok) {
        POWER_HILOGE(MODULE_JS_NAPI, "%{public}s: get reason failed", __func__);
        return nullptr;
    }
    
    //根据true或false参数,决定是调用PowerMgrClient的系统关机ShutDownDevice方法还是重启设备RebootDevice方法
    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;
}

3.3 开关机客户端native实现

  1. ShutDownDevice首先会调用Connect方法,Connect会通过GetSystemAbilityManager方法获取SystemAbilityManager实例,然后通过CheckSystemAbility方法检查对应的SA是否存在,并返回remoteObject对象,最后通过iface_cast构造proxy对象,此时创建了PowerMgrProxy实例
  2. 最后ShutDownDevice将开关机请求委托给电源管理服务代理PowerMgrProxy的ShutDownDevice方法去处理
//OpenHarmony/base/powermgr/power_manager/frameworks/native/power_mgr_client.cpp

// 调用方不提供id参数,id默认为0,表示本地显示设备
void PowerMgrClient::ShutDownDevice(const std::string& reason)
{
    POWER_HILOGE(MODULE_INNERKIT, "ymz PowerMgrClient::%{public}s called.", __func__);
    // 获取电源管理服务的代理端对象,这里返回的是PowerMgrProxy对象
    // 查找POWER_MANAGER_SERVICE_ID,即上面注册的PowerMgrService服务
    RETURN_IF(Connect() != ERR_OK);
    POWER_HILOGE(MODULE_INNERKIT, "%{public}s called.", __func__);
    // 调用PowerMgrProxy的ShutDownDevice,通过ipc方式执行开关机指令
    proxy_->ShutDownDevice(reason);
}

// 获取电源管理服务的代理端对象
ErrCode PowerMgrClient::Connect()
{
    POWER_HILOGE(MODULE_INNERKIT, "ymz PowerMgrClient::%{public}s called.", __func__);
    std::lock_guard<std::mutex> lock(mutex_);
    if (proxy_ != nullptr) {
        return ERR_OK;
    }

    //获取SystemAbilityManager实例
    sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
    if (sam == nullptr) {
        POWER_HILOGE(MODULE_INNERKIT, "%{public}s:Failed to get Registry!", __func__);
        return E_GET_SYSTEM_ABILITY_MANAGER_FAILED;
    }
    //调用CheckSystemAbility方法检查对应的SA是否已注册,并返回remoteObject对象
    sptr<IRemoteObject> remoteObject_ = sam->CheckSystemAbility(POWER_MANAGER_SERVICE_ID);
    if (remoteObject_ == nullptr) {
        POWER_HILOGE(MODULE_INNERKIT, "GetSystemAbility failed!");
        return E_GET_POWER_SERVICE_FAILED;
    }

    deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new PowerMgrDeathRecipient());
    if (deathRecipient_ == nullptr) {
        POWER_HILOGE(MODULE_INNERKIT, "%{public}s :Failed to create PowerMgrDeathRecipient!", __func__);
        return ERR_NO_MEMORY;
    }
    if ((remoteObject_->IsProxyObject()) && (!remoteObject_->AddDeathRecipient(deathRecipient_))) {
        POWER_HILOGE(MODULE_INNERKIT, "%{public}s :Add death recipient to PowerMgr service failed.", __func__);
        return E_ADD_DEATH_RECIPIENT_FAILED;
    }

    //通过iface_cast构造proxy对象,将remoteObject_转换为具体类型,此时创建了PowerMgrProxy实例
    proxy_ = iface_cast<IPowerMgr>(remoteObject_);
    POWER_HILOGI(MODULE_INNERKIT, "%{public}s :Connecting PowerMgrService success.", __func__);
    return ERR_OK;
}

3.4 开关机代理端实现

PowerMgrProxy对象会将开关机的请求以IPC方式发送给电源管理服务提供端PowerMgrStub对象处理

//OpenHarmony/base/powermgr/power_manager/services/zidl/src/power_mgr_proxy.cpp

// 电源管理服务代理端开关机功能实现
void PowerMgrProxy::ShutDownDevice(const std::string& reason)
{
    POWER_HILOGE(MODULE_INNERKIT, "ymz PowerMgrProxy::%{public}s called!", __func__);
    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));

     // 将请求发送给电源管理服务的stub端,消息类型是SHUTDOWN_DEVICE
    int ret = remote->SendRequest(static_cast<int>(IPowerMgr::SHUTDOWN_DEVICE), data, reply, option);
    if (ret != ERR_OK) {
        POWER_HILOGE(MODULE_INNERKIT, "PowerMgrProxy::%{public}s Transact is failed, error code: %d", __func__, ret);
    }
}

3.5 开关机服务提供端实现

  1. 服务提供端(Stub),继承IRemoteStub,实现业务函数,重写OnRemoteRequest()方法用于接收客户端请求
  2. 通过消息码匹配对应的业务函数,并调用,这里匹配的是ShutDownDeviceStub
//OpenHarmony/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) {
        ...
        // 消息类型为SHUTDOWN_DEVICE的处理函数  
        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;
}

// 电源管理stub端处理函数
int32_t PowerMgrStub::ShutDownDeviceStub(MessageParcel& data)
{
    POWER_HILOGD(MODULE_SERVICE, "ymz PowerMgrStub::%{public}s called!", __func__);
    std::string reason = Str16ToStr8(data.ReadString16());
    ShutDownDevice(reason);
    return ERR_OK;
}
  1. 服务提供端stub将开关机的请求转发给子类对象PowerMgrService的ShutDownDevice方法去处理,在ShutDownDevice方法中会判断相关的权限,以及调用ShutdownService对象的Shutdown方法
//OpenHarmony/base/powermgr/power_manager/services/native/src/power_mgr_service.cpp

// 电源管理管理服务端关机功能实现函数
void PowerMgrService::ShutDownDevice(const std::string& reason)
{
    POWER_HILOGI(MODULE_SERVICE, "ymz PowerMgrService::%{public}s called!", __func__);
    std::lock_guard lock(mutex_);
    pid_t pid  = IPCSkeleton::GetCallingPid();
    auto uid = IPCSkeleton::GetCallingUid();
    //判断执行权限
    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对象的Shutdown方法
    shutdownService_.Shutdown(reason);
}

3.6 ShutdownService对象的Shutdown方法实现

  1. Shutdown进一步调用RebootOrShutdown方法,RebootOrShutdown根据true或false决定是执行系统关机Shutdown还是重启设备Reboot
//OpenHarmony/base/powermgr/power_manager/services/native/src/shutdown_service.cpp

void ShutdownService::Shutdown(const std::string& reason)
{
    POWER_HILOGI(MODULE_SERVICE, "ymz ShutdownService::%{public}s called!", __func__);
    RebootOrShutdown(reason, false);
}

void ShutdownService::RebootOrShutdown(const std::string& reason, bool isReboot)
{
    POWER_HILOGI(MODULE_SERVICE, "ymz ShutdownService::%{public}s called!", __func__);
    if (started_) {
        POWER_HILOGE(MODULE_SERVICE, "Shutdown is already running.");
        return;
    }
    started_ = true;
    make_unique<thread>([=] {
        Prepare();//发布COMMON_EVENT_SHUTDOWN公共事件
        POWER_HILOGD(MODULE_SERVICE, "reason = %{public}s, reboot = %{public}d", reason.c_str(), isReboot);
        //执行DevicePowerAction::Shutdown(const std::string& reason)
        if (devicePowerAction_ != nullptr) {
            isReboot ? devicePowerAction_->Reboot(reason) : devicePowerAction_->Shutdown(reason);
        }
        started_ = false;
    })->detach();
}

3.7 电源管理action实现

执行系统调用,进行shutdown操作

//OpenHarmony/base/powermgr/power_manager/services/native/src/actions/default/device_power_action.cpp

void DevicePowerAction::Shutdown(const std::string& reason)
{
    POWER_HILOGI(MODULE_SERVICE, "ymz DevicePowerAction::%{public}s called!", __func__);
    POWER_HILOGI(MODULE_SERVICE, "Shutdown executing.");
     //执行系统调用,进行shutdown操作
    DoReboot(SHUTDOWN_CMD.c_str());
}

4 应用demo

import power from '@ohos.power'

@Entry
@Component
struct Index {
  @State window: string = ''
  //buttonText数组,包含:关机、重启、检查屏幕状态
  private buttonText: Resource[] = [$r('app.string.turnOff'), $r('app.string.restart'), $r('app.string.checkState')]

  dialog(title: Resource, message: Resource) {
    //警告弹窗
    AlertDialog.show(
      {
        title: title,
        message: message,
        //按钮的文本内容、文本色、按钮背景色和点击回调。
        primaryButton: {
          value: $r('app.string.cancel'),//取消
          action: () => {
            console.info(`Callback when the first button is clicked`)
          }
        },
        //按钮的文本内容、文本色、按钮背景色和点击回调。
        secondaryButton: {
          value: $r('app.string.determine'),//确认
          action: () => {
            console.info(`Callback when the second button is clicked`)
            if (title === $r('app.string.turnOff')) {
              this.window = 'Is power off'
              power.shutdownDevice('shutdown_test')//关机
              console.info(`power_shutdown_device_test success`)
            } else {
              this.window = 'Is to restart'
              power.rebootDevice('');//重启
              console.info(`power_reboot_device_test success`)
            }
          }
        },
        cancel: () => {
          console.info(`Closed callbacks`)
        }
      }
    )
  }

  checkState() {
    power.isScreenOn((error, screenOn) => {//检查屏幕亮灭
      if (typeof error === 'undefined') {
        this.window = 'screenOn status is' + screenOn
        console.log(this.window);
      } else {
        console.log(`error: ${error}`);
      }
    })
  }

  build() {
    //弹性布局容器
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
      //沿水平方向布局容器
      Row() {
        //文本组件
        Text($r('app.string.MainAbility_label'))
          .fontColor(Color.White)
          .fontSize(20)
      }
      .size({ width: '100%', height: 50 })
      .padding({ left: 15 })
      .backgroundColor('#0D9FFB')

      //文本组件
      Text(this.window)
        .width('90%')
        .height(100)
        .border({ width: 2, radius: 10, color: Color.Black })
        .margin({ top: 20 })
        .padding({ left: 10 })
        .fontSize(20)
        .fontWeight(FontWeight.Bold)

      ForEach(this.buttonText, (item, index) => {
        //按钮组件
        Button() {
          Text(item)
            .fontSize(25)
            .fontWeight(FontWeight.Bold)
        }
        .width('80%')
        .margin({ top: '20' })
        .type(ButtonType.Capsule)
        .backgroundColor('#0D9FFB')
        .onClick(() => {
          index = this.buttonText.indexOf(item)
          switch (index) {
            case 0:
              this.dialog($r('app.string.turnOff'), $r('app.string.questionTurnOff'))//关机
              break
            case 1:
              this.dialog($r('app.string.restart'), $r('app.string.questionRestart'))//重启
              break
            case 2:
              this.checkState()//检查屏幕亮灭
              break
            default:
              break
          }
        })
      }, item => JSON.stringify(item))

    }
    .width('100%')
    .height('100%')
  }
}

总结

本文主要和大家分享了OpenHarmony电源管理子系统中开关机功能的实现细节,对NAPI接口、电源管理服务请求端及电源管理服务提供端流程等,做了较为详细的代码说明,希望通过本文您能初步掌握电源管理子系统的关键功能和核心流程。关于OpenHarmony其它子系统的分析,请关注后续文章。

更多原创内容请关注:深开鸿技术团队

入门到精通、技巧到案例,系统化分享OpenHarmony开发技术,欢迎投稿和订阅,让我们一起携手前行共建生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-11-10 15:40:55修改
4
收藏 3
回复
举报
2条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

老师图1好像挂掉了,方便补一下吗?

回复
2022-7-29 14:37:00
云端筑梦
云端筑梦

实现关机重启的话好像会有很多权限问题,博主大大能讲一下吗


回复
2023-8-15 10:54:12
回复
    相关推荐