经反复测试,图片显示不全这一现象,只会发生在选择重启设备,而不会发生在选择关机后。因此判断,可能还是由于开机动画出现问题导致。图片大约能显示一半多一点。
尝试修改BootAnimation
但没有生效,修改DisplayDevice
也没有生效。
//frameworks\native\services\surfaceflinger\DisplayDevice.cpp
DisplayDevice::DisplayDevice(....){
// setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
setProjection(DisplayState::eOrientation90, mViewport, mFrame);
}
Android8中,关机动画使用的就是开机动画。一开始我怀疑过是自定义的开机动画有问题导致选择重启设备后,关机图片显示不全。
因此,修改了threadLoop,无论是否存在自定义的动画文件,始终执行Android系统默认动画。
android-logo-mask.png
//frameworks\base\cmds\bootanimation\BootAnimation.cpp
bool BootAnimation::threadLoop()
{
bool r;
// We have no bootanimation file, so we use the stock android logo
// animation.
if (mZipFileName.isEmpty()) {
r = android();
} else {
// r = movie();
r = android();
}
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(mDisplay, mContext);
eglDestroySurface(mDisplay, mSurface);
mFlingerSurface.clear();
mFlingerSurfaceControl.clear();
eglTerminate(mDisplay);
eglReleaseThread();
IPCThreadState::self()->stopProcess();
return r;
}
发现,该情况下,依旧图片显示不全。而通过进一步测试发现,当开机后,快速重启不会发生图片显示不全的现象,并且查看SurfaceFlinger中的log,关于mode的log,与现象的发生有一定的关联。
不同的选择会导致Set power mode=的结果不同。
//frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
int mode, bool stateLockHeld) {
ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
this);
}
因此最后通过在setPowerModeInternal
的调用处加log,找到了void SurfaceFlinger::onInitializeDisplays()
,而调用 onInitializeDisplays
的是 initializeDisplays
。
出现的原因在于调用了setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL, /*stateLockHeld*/ false);
HWC_POWER_MODE_NORMAL定义在hwcomposer_defs.h中,表示普通状态,而在没有发生图片显示不全的情况下,都是给mode赋值0,也就是HWC_POWER_MODE_OFF,因此解决思路是不赋值或赋值0。
/* The display is turned off (blanked). */
HWC_POWER_MODE_OFF = 0,
/* The display is turned on and configured in a low power state
* that is suitable for presenting ambient information to the user,
* possibly with lower fidelity than normal but greater efficiency. */
HWC_POWER_MODE_DOZE = 1,
/* The display is turned on normally. */
HWC_POWER_MODE_NORMAL = 2,
而选择重启后,调用的是binderDied
函数。因此先尝试屏蔽掉binderDied
中的initializeDisplays();
。
////frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
void SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
{
// the window manager died on us. prepare its eulogy.
#ifdef MTK_AOSP_DISPLAY_BUGFIX
char value[PROPERTY_VALUE_MAX] = {'\0'};
property_get("sys.powerctl", value, "");
if(strstr(value, "shutdown"))
return;
#endif
// restore initial conditions (default device unblank, etc)
//屏蔽initializeDisplays
//initializeDisplays();
// restart the boot-animation
startBootAnim();
}
经测试后发现,屏蔽后关机图片显示正常,没有发现其他异常。
猜测可能是SurfaceFlinger
出现了冲突导致。
参考链接:
MTK 屏幕旋转90度
【Android系统源码修改】开机动画只显示一半
android系统知识(8.0)---Android O 开关机动画流程
网友评论