我是靠谱客的博主 魁梧夏天,最近开发中收集的这篇文章主要介绍开关机问题汇总,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.sensors-hal等sensor耗时

boot_progress_start:	4069
boot_progress_preload_start:4958	
boot_progress_preload_end:	6455
boot_progress_system_run:	6610
boot_progress_pms_start:6789	
boot_progress_pms_system_scan_start:6954	
boot_progress_pms_data_scan_start:	8078
boot_progress_pms_scan_end:	9189
boot_progress_pms_ready:9226	
boot_progress_ams_ready:15638	
boot_progress_enable_screen:16684	
sf_stop_bootanim:17625	
wm_boot_animation_done:	17646

主要耗时点在:boot_progress_pms_ready 到 boot_progress_ams_ready 时间段。

分析log发现:

有接近40处如下打印:ServiceManager: Waiting for service 'sensorservice' on '/dev/binder'...

并在后面有:05-28 16:02:10.901  900   E sensors-hal: wait_for_mandatory_sensors:425, some mandatory sensors not available even after 7 seconds, giving up.

原因分析:

由于Q R 版本使用的sensors列表不一样,Q版本使用了一个叫3d_signature的sensor,而R版本没有用;
如果QR升级,比如先刷Q版本设备会生成sensors_list.txt文件,保存在persist分区/mnt/vendor/persist/sensors/sensors_list.txt 然后升级到R版本 由于sensors_list.txt 在persist分区  所以升级也是不会更新这个分区的,导致该文件刷机也无法删除,设备起来后还是遍历这个文件找对应的sensor,如果找不到就会一直等待7s

删除sensors_list.txt文件,具体操作为

adb root

adb shell

rm mnt/vendor/persist/sensors/sensors_list.txt

adb reboot

验证开机时间正常了 。

解决办法:

在GOTA升级完成后删除该文件。
/build/tools/releasetools/edify_generator.py  
 self.script.append(xxxx
build/tools/releasetools/ota_from_target_files
  script.DeleteFiles([xxxx

2.selinux  avc权限问题导致耗时

观察events.log 发现boot_progress_enable_screen到wm_boot_animation_done 存在avc error

07-20 05:12:44.684 509 509 I auditd : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0

.同时间节点观察main.log 发现servermanager wait

07-20 05:12:39.668 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…

07-20 05:12:44.684 1279 1344 W ServiceManager: Service media.metrics didn’t start. Returning NULL
修改如下,即可优化-----5s

prebuilts/api/29.0/public/bootanim.te
public/bootanim.te

3.bindkeyguardservice 慢

//启动systemui

08-09 20:55:05.927 1597 1597 I SystemServer: StartSystemUI
...
08-09 20:55:08.174 2202 3110 D KeyguardViewMediator: onSystemReady
08-09 20:55:08.176 2202 3110 D KeyguardViewMediator: doKeyguard: showing the lock screen
08-09 20:55:08.176 2202 3110 D KeyguardViewMediator: showLocked
08-09 20:55:08.567 2202 2202 W KeyguardViewMediator: notifyDrawn

看StartSystemUI 和 onSystemReady之间的耗时,如果长就是bindKeyguard耗时。

导致开机动画结束的晚的原因可能还有:锁屏启动的慢、窗口绘制的慢

因为,只有锁屏和窗口都启动好了之后才会给SurfaceFlinger发bootFinished的消息,属性 service.bootanim.exit 才会被置为1,bootanimation才会停止。

[wm_boot_animation_done的时间就是Bootanimation停止的时间]

从boot_progress_enable_screen的源码处开始分析:

    void enableScreenAfterBoot(boolean booted) {
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
                SystemClock.uptimeMillis());
        mWindowManager.enableScreenAfterBoot();

        synchronized (mGlobalLock) {
            updateEventDispatchingLocked(booted);
        }
    }

进入mWindowManager.enableScreenAfterBoot()

 public void enableScreenAfterBoot() {
       ......
        performEnableScreen();
  }

接着进入performEnableScreen()

private void performEnableScreen() {
        synchronized (mGlobalLock) {
         .............
            if (!mShowingBootMessages && !mPolicy.canDismissBootAnimation()) {                                                                
                return;
            }
           

因为 mPolicy.canDismissBootAnimation() 接口一直返回false,直接return。所以performEnableScreen()接口走不下去,就不能给SurfaceFlinger发bootFinished的消息,bootanimation就继续播放。

看下mPolicy.canDismissBootAnimation()的实现:

    @Override
    public boolean canDismissBootAnimation() {
        return mDefaultDisplayPolicy.isKeyguardDrawComplete();                                                                                                
    }
    public boolean isKeyguardDrawComplete() {
        return mKeyguardDrawComplete;
    }    @Override

    public boolean canDismissBootAnimation() {
        return mDefaultDisplayPolicy.isKeyguardDrawComplete();                                                                                                
    }
    public boolean isKeyguardDrawComplete() {
        return mKeyguardDrawComplete;
    }

可知mPolicy.canDismissBootAnimation()返回的就是mKeyguardDrawComplete的值。

mKeyguardDrawComplete=true的值是在DisplayPolicy.java::finishKeyguardDrawn()中定义的。

DisplayPolicy.java::finishKeyguardDrawn()被PhoneWindowManager.java::finishKeyguardDrawn()调用。

PhoneWindowManager.java::finishKeyguardDrawn()被Handler处理:

 private class PolicyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                ....................
                case MSG_KEYGUARD_DRAWN_COMPLETE:
                    if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mKeyguardDrawComplete");
                    finishKeyguardDrawn();
                    break;
                case MSG_KEYGUARD_DRAWN_TIMEOUT:
                    Slog.w(TAG, "Keyguard drawn timeout. Setting mKeyguardDrawComplete");
                    finishKeyguardDrawn();
                    break;

Log中发现没有Keyguard drawn timeout. Setting mKeyguardDrawComplete打印,只有Setting mKeyguardDrawComplete打印,所以走的是case MSG_KEYGUARD_DRAWN_COMPLETE分支。

消息ID=MSG_KEYGUARD_DRAWN_COMPLETE的消息是在下面的代码中发送的:

 final DrawnListener mKeyguardDrawnCallback = new DrawnListener() {
        @Override
        public void onDrawn() {
            if (DEBUG_WAKEUP) Slog.i(TAG, "mKeyguardDelegate.ShowListener.onDrawn.");
            mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE);
        }
    };

mKeyguardDrawnCallback变量在下面的函数用到

@Override
    public void screenTurningOn(final ScreenOnListener screenOnListener) {
        if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on...");
        updateScreenOffSleepToken(false);
        mDefaultDisplayPolicy.screenTurnedOn(screenOnListener);
        synchronized (mLock) {
            if (mKeyguardDelegate != null && mKeyguardDelegate.hasKeyguard()) {
                mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
                mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT,
                        getKeyguardDrawnTimeout());
                mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);
            } else {
                if (DEBUG_WAKEUP) Slog.d(TAG,
                        "null mKeyguardDelegate: setting mKeyguardDrawComplete.");
                mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE);
            }
        }
    }

mKeyguardDrawnCallback中的onDraw应该是在KeyguardViewMediator.java::notifyDrawn调用的。
 

    private void notifyDrawn(final IKeyguardDrawnCallback callback) {
        Trace.beginSection("KeyguardViewMediator#notifyDrawn");
        try {
            callback.onDrawn();
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception calling onDrawn():", e);
        }
        Trace.endSection();
    }

分析LOG发现,调用notifyDrawn就晚了。

07-16 20:36:58.680  1000  1606  1653 I WindowManager: Screen turning on...

....

....

07-16 20:36:59.551  1000  2309  2309 W KeyguardViewMediator: handleNotifyScreenTurningOn

07-16 20:36:59.551  1000  2309  2309 W KeyguardViewMediator: notifyDrawn

继续分析LOG并加打印:

发现调用mKeyguardConnection对象的onServiceConnected方法就耗时了

07-17 19:07:58.817  1000  1597  1646 I xxx: WMS.enableScreenAfterBoot =111111=:::10718

.....

07-17 19:07:59.496  1000  1597  1644 I xxx: keyguardservice.onServiceConnected =111111=:::11397

 private final ServiceConnection mKeyguardConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Slog.i("xxx", "keyguardservice.onServiceConnected =111111=:::"+SystemClock.uptimeMillis());
            if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)");
            mKeyguardService = new KeyguardServiceWrapper(mContext,
                    IKeyguardService.Stub.asInterface(service), mCallback);

            if (mKeyguardState.systemIsReady) {
                // If the system is ready, it means keyguard crashed and restarted.
                mKeyguardService.onSystemReady();
                if (mKeyguardState.currentUser != UserHandle.USER_NULL) {
                    // There has been a user switch earlier
                    mKeyguardService.setCurrentUser(mKeyguardState.currentUser);
                }
                // This is used to hide the scrim once keyguard displays.
                if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE
                        || mKeyguardState.interactiveState == INTERACTIVE_STATE_WAKING) {
                    mKeyguardService.onStartedWakingUp();
                }
                if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) {
                    mKeyguardService.onFinishedWakingUp();
                }
                if (mKeyguardState.screenState == SCREEN_STATE_ON
                       || mKeyguardState.screenState == SCREEN_STATE_TURNING_ON) {
                    Slog.i("xxx", "keyguardservice.onServiceConnected =222222=:::"+SystemClock.uptimeMillis());
                    mKeyguardService.onScreenTurningOn(
                            new KeyguardShowDelegate(mDrawnListenerWhenConnect));
                }
                if (mKeyguardState.screenState == SCREEN_STATE_ON) {
                    mKeyguardService.onScreenTurnedOn();
                }
                mDrawnListenerWhenConnect = null;
            }
            if (mKeyguardState.bootCompleted) {
                mKeyguardService.onBootCompleted();
            }
            if (mKeyguardState.occluded) {
                mKeyguardService.setOccluded(mKeyguardState.occluded, false /* animate */);
            }
            if (!mKeyguardState.enabled) {
                mKeyguardService.setKeyguardEnabled(mKeyguardState.enabled);
            }
        }

Screen turning on...到Finished screen turning on...的时间段耗时,

对应的接口是:

PhoneWindowManager.java::screenTurningOn    到    DisplayPolicy.java::finishScreenTurningOn

 

DisplayPolicy.java::finishScreenTurningOn是finishWindowsDrawn()调用的。

finishWindowsDrawn()对应的 MSG_WINDOW_MANAGER_DRAWN_COMPLETE消息,

发该消息的地方在

    final Runnable mWindowManagerDrawCallback = new Runnable() {
        @Override
        public void run() {
            if (DEBUG_WAKEUP) Slog.i(TAG, "All windows ready for display!");
            mHandler.sendEmptyMessage(MSG_WINDOW_MANAGER_DRAWN_COMPLETE);
        }
    };
==========================================
    private void finishKeyguardDrawn() {                                                         //锁屏结束绘制
        synchronized (mLock) {
            if (!mScreenOnEarly || mKeyguardDrawComplete) {
                return; // We are not awake yet or we have already informed of this event.
            }

            mKeyguardDrawComplete = true;
            if (mKeyguardDelegate != null) {
                mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
            }
            mWindowManagerDrawComplete = false;
        }

        // ... eventually calls finishWindowsDrawn which will finalize our screen turn on
        // as well as enabling the orientation change logic/sensor.
        mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback,
                WAITING_FOR_DRAWN_TIMEOUT);
    }
==========================================
        @Override
        public void waitForAllWindowsDrawn(Runnable callback, long timeout) {
            boolean allWindowsDrawn = false;
            synchronized (mWindowMap) {
                mWaitingForDrawnCallback = callback;
                getDefaultDisplayContentLocked().waitForAllWindowsDrawn();
                mWindowPlacerLocked.requestTraversal();
                mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
                if (mWaitingForDrawn.isEmpty()) {
                    allWindowsDrawn = true;
               } else {
                    mH.sendEmptyMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, timeout);
                    checkDrawnWindowsLocked();
                }
            }
            if (allWindowsDrawn) {
                callback.run();                                                                  //调用mWindowManagerDrawCallback.run发MSG_WINDOW_MANAGER_DRAWN_COMPLETE消息
            }
        }

 

最后

以上就是魁梧夏天为你收集整理的开关机问题汇总的全部内容,希望文章能够帮你解决开关机问题汇总所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部