概述
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消息
}
}
最后
以上就是魁梧夏天为你收集整理的开关机问题汇总的全部内容,希望文章能够帮你解决开关机问题汇总所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复