当前位置:首页 >时尚 >OpenHarmony系统解决方案 统解如果超过检测次数

OpenHarmony系统解决方案 统解如果超过检测次数

2024-06-30 23:19:11 [百科] 来源:避面尹邢网

OpenHarmony系统解决方案 - 锁屏引起的统解卡开机动画

作者:TiZizzz 系统 OpenHarmony 根据设备性能调整OnSystemReady函数的tryTime变量数值,服务会间隔1S执行检测锁屏应用是决方否成功注册监听,并执行回调。统解如果超过检测次数,决方则会一直处于开机动画界面。统解

想了解更多关于开源的决方内容,请访问:

OpenHarmony系统解决方案 统解如果超过检测次数

51CTO 开源基础软件社区

OpenHarmony系统解决方案 统解如果超过检测次数

https://ost.51cto.com

OpenHarmony系统解决方案 统解如果超过检测次数

问题描述

问题环境

系统版本:OpenHarmony-3.2-Release

问题现象

设备接通电源,统解开机动画正常播放结束,决方长时间静止在开机动画结束界面,统解无法正常进入系统。决方

OpenHarmony系统解决方案 - 锁屏引起的统解卡开机动画-开源基础软件社区OpenHarmony系统解决方案 - 锁屏引起的卡开机动画-开源基础软件社区

问题原因

  • 设备性能导致的锁屏应用未在锁屏服务检测监听事件的时间段内启动完成,导致无法触发关闭开机动画。决方
  • 系统不需要锁屏应用,统解把锁屏应用删除后,决方未移除锁屏服务(theme_screenlock_mgr)导致无法触发关闭开机动画。统解

解决方案

针对设备性能问题的解决方案

调整锁屏检测次数,增加锁屏检测的时间,保证可以在锁屏应用启动后正常设置系统参数bootevent.lockscreen.readytrue

根据设备性能调整OnSystemReady函数的tryTime变量数值,服务会间隔1S执行检测锁屏应用是否成功注册监听,并执行回调。如果超过检测次数,则会一直处于开机动画界面。

// base/theme/screenlock_mgr/services/src/screenlock_system_ability.cppvoid ScreenLockSystemAbility::OnSystemReady(){     SCLOCK_HILOGI("ScreenLockSystemAbility OnSystemReady started.");    bool isExitFlag = false;    int tryTime = 20;	// 根据设备性能调整此处尝试次数    int minTryTime = 0;    while (!isExitFlag && (tryTime > minTryTime)) {         if (systemEventListener_ != nullptr) {             SCLOCK_HILOGI("ScreenLockSystemAbility OnSystemReady started1.");            std::lock_guard<std::mutex> lck(listenerMutex_);            SystemEvent systemEvent(SYSTEM_READY);            systemEventListener_->OnCallBack(systemEvent);            isExitFlag = true;        } else {             SCLOCK_HILOGE("ScreenLockSystemAbility OnSystemReady type not found., flag_ = %{ public}d", flag_);            sleep(1);        }        --tryTime;    }}

针对删除锁屏应用的解决方案

移除锁屏服务(screenlock_mgr)组件,以RK3568编译配置为例。需在编译配置文件productdefine/common/inherit/rich.json中删除screenlock_mgr组件的编译配置。以下为删除后的theme编译配置。

{   "version": "3.0",  "subsystems": [    ···    {       "subsystem": "theme",      "components": [        {           "component": "wallpaper_mgr",          "features": []        }      ]    },   	···  ]}

如果需要保留锁屏服务,则需删除锁屏服务开机检测项bootevents,配置项位于base/theme/screenlock_mgr/etc/init/screenlockservice.cfg。

定位过程

1. 开机动画退出逻辑,当开机动画获取到bootevent.boot.completed属性为true时,退出开机动画。

// foundation/graphic/graphic_2d/frameworks/bootanimation/src/boot_animation.cppvoid BootAnimation::CheckExitAnimation(){     LOGI("CheckExitAnimation enter");    if (!setBootEvent_) {         LOGI("CheckExitAnimation set bootevent parameter");        system::SetParameter("bootevent.bootanimation.started", "true");        setBootEvent_ = true;    }    std::string windowInit = system::GetParameter("bootevent.boot.completed", "false");    if (windowInit == "true") {         PostTask(std::bind(&AppExecFwk::EventRunner::Stop, runner_));        LOGI("CheckExitAnimation read windowInit is true");        return;    }}

2. 开机启动服务组件会收集设备服务开机配置信息中的bootevents配置,并统计数量后赋值变量g_bootEventNum。当系统参数被设置时,过滤bootevent字段,调用下方函数进行g_bootEventNum--。当数量变为0时则将bootevent.bootanimation.started设置为true。

// base/startup/init/services/modules/bootevent.c#define BOOT_EVENT_BOOT_COMPLETED "bootevent.boot.completed"static void BootEventParaFireByName(const char *paramName){     ListNode *found = NULL;    char *bootEventValue = strrchr(paramName, '.');    if (bootEventValue == NULL) {         return;    }    bootEventValue[0] = '\0';    found = OH_ListFind(&bootEventList, (void *)paramName, BootEventParaListCompareProc);    if (found == NULL) {         return;    }    if (((BOOT_EVENT_PARAM_ITEM *)found)->timestamp[BOOTEVENT_READY].tv_sec != 0) {         return;    }    INIT_CHECK_ONLY_RETURN(clock_gettime(CLOCK_MONOTONIC,        &(((BOOT_EVENT_PARAM_ITEM *)found)->timestamp[BOOTEVENT_READY])) == 0);    g_bootEventNum--;    // Check if all boot event params are fired    if (g_bootEventNum > 0) {         return;    }    // All parameters are fired, set boot completed now ...    INIT_LOGI("All boot events are fired, boot complete now ...");    SystemWriteParam(BOOT_EVENT_BOOT_COMPLETED, "true");   // 设置 bootevent.boot.completed 参数为 true    g_bootEventEnable = BOOT_EVENT_FINISH;    SaveServiceBootEvent();    const char *clearBootEventArgv[] = { "bootevent"};    // clear servie extra data    PluginExecCmd("clear", ARRAY_LENGTH(clearBootEventArgv), clearBootEventArgv);    return;}

3. 查看锁屏服务开机配置,存在bootevents配置项。

// base/theme/screenlock_mgr/etc/init/screenlockservice.cfg{     ···    "services" : [{             ···            "bootevents" : ["bootevent.lockscreen.ready"]        }    ]}

4. 通过shell查看系统中的参数。发现bootevent.lockscreen.ready参数未被设置。

param get | grep bootevent

OpenHarmony系统解决方案 - 锁屏引起的卡开机动画-开源基础软件社区OpenHarmony系统解决方案 - 锁屏引起的卡开机动画-开源基础软件社区

5. 尝试手动添加参数,判断是否为此问题。如果可以正常退出开机动画,则确定是由于锁屏参数未设置导致的此问题。

param set bootevent.lockscreen.ready true

6. 查看锁屏应用源码,应用启动后会注册ScreenLockMar.onSystemEvent事件。事件注册后,当触发systemReady设置时,会将bootevent.lockscreen.ready参数设置为true。

// applications/standard/screenlock/features/screenlock/src/main/ets/com/ohos/model/screenLockModel.tsexport default class ScreenLockModel {     @SysFaultLogger({ FAULT_ID: FaultID.SCREEN_LOCK_MANAGER, MSG: "call func on failed"})    eventListener(callback: Callback<String>) {         let isSuccess = ScreenLockMar.onSystemEvent((err, event) => {             Log.showInfo(TAG, `eventListener:callback:${ event.eventType}`)            callback(event.eventType);            if (err) {                 Log.showError(TAG, `on callback error -> ${ JSON.stringify(err)}`);            }        });        if (!isSuccess) {             callback('serviceRestart');        }    }    ···}// applications/standard/screenlock/features/screenlock/src/main/ets/com/ohos/model/screenLockService.tsconst EVENT_SYSTEM_READY: string = 'systemReady'···export class ScreenLockService {     monitorEvents() {         ···        this.screenLockModel.eventListener((typeName: String) => {             switch (typeName) {             // System ready on device boot                case EVENT_SYSTEM_READY:                    Log.showInfo(TAG, `EVENT_SYSTEM_READY event`);                    this.lockScreen();                    break;        })        ···    }    lockScreen() {         ···        this.screenLockModel.showScreenLockWindow(() => {             ···            if (this.currentLockStatus == ScreenLockStatus.Locking) {                 Log.showInfo(TAG, `had locked, no need to publish lock_screen`);            } else {                 this.notifyLockScreenResult(LockResult.Success)                this.publishByUser("common.event.LOCK_SCREEN", this.accountModel.getCurrentUserId());                setTimeout(() => {                     systemParameter.set('bootevent.lockscreen.ready','true')                }, 1000);                this.currentLockStatus = ScreenLockStatus.Locking;            }        });    }}

7. 在锁屏服务中遍历判断是否有systemEventListener_的监听,如果有systemReady事件将被触发。而systemEventListener_则是由步骤6中锁屏应用设置,形成闭环。

// base/theme/screenlock_mgr/services/src/screenlock_system_ability.cppvoid ScreenLockSystemAbility::OnSystemReady(){     SCLOCK_HILOGI("ScreenLockSystemAbility OnSystemReady started.");    bool isExitFlag = false;    int tryTime = 20;     int minTryTime = 0;    while (!isExitFlag && (tryTime > minTryTime)) {         if (systemEventListener_ != nullptr) {             SCLOCK_HILOGI("ScreenLockSystemAbility OnSystemReady started1.");            std::lock_guard<std::mutex> lck(listenerMutex_);            SystemEvent systemEvent(SYSTEM_READY);            systemEventListener_->OnCallBack(systemEvent);            isExitFlag = true;        } else {             SCLOCK_HILOGE("ScreenLockSystemAbility OnSystemReady type not found., flag_ = %{ public}d", flag_);            sleep(1);        }        --tryTime;    }}

8. 落盘开机Log,查看日志中ScreenLockSystemAbility OnSystemReady type not found., flag_ = %{ public}d日志的打印数量,如果为20条则确定是由于锁屏应用未在检测结束前注册监听导致。

想了解更多关于开源的内容,请访问:

51CTO 开源基础软件社区

https://ost.51cto.com

责任编辑:jianghua 来源: 51CTO 开源基础软件社区 鸿蒙检测锁屏应用

(责任编辑:时尚)

    推荐文章
    热点阅读