拆解步骤
1、app强制横屏显现,无视android:screenOrientation=”portrait”属性
2、屏幕接触坐标修正为横屏
3、开机动画横屏
4、开机logo、关机充电动画横屏
上代码
1、app强制横屏显现
修正rotationForOrientationLw(),默许回来270
frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java
@OverridepublicintrotationForOrientationLw(intorientation,intlastRotation,booleandefaultDisplay){
….synchronized(mLock){
…default://ForUSER,UNSPECIFIED,NOSENSOR,SENSORandFULL_SENSOR,//justreturnthepreferredorientationwealreadycalculated.if(preferredRotation>=0){returnpreferredRotation;
}//returnSurface.ROTATION_0;returnSurface.ROTATION_270;//cczhengaddforlandscap}
}
}
activity默许强制属性为SCREEN_ORIENTATION_LANDSCAPE
frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java
booleanupdateOrientationFromAppTokensLocked(intdisplayId,booleanforceUpdate){longident=Binder.clearCallingIdentity();try{finalDisplayContentdc=mRoot.getDisplayContent(displayId);//finalintreq=dc.getOrientation();intreq=android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;//cczhengaddforlandscapif(req!=dc.getLastOrientation()||forceUpdate){if(DEBUG_ORIENTATION){
Slog.v(TAG,”updateOrientation:req=”+req+”,mLastOrientation=”+dc.getLastOrientation(),newThrowable(“updateOrientation”));
}
dc.setLastOrientation(req);//sendamessagetoPolicyindicatingorientationchangetotake//actionlikedisabling/enablingsensorsetc.,//TODO(multi-display):Implementpolicyforsecondarydisplays.if(dc.isDefaultDisplay){
mPolicy.setCurrentOrientationLw(req);
}returndc.updateRotationUnchecked(forceUpdate);
}returnfalse;
}finally{
Binder.restoreCallingIdentity(ident);
}
}
DisPlayContent显现mRotation默许改为3(270)
frameworks\base\services\core\java\com\android\server\wm\DisplayContent.java
/**
*Currentrotationofthedisplay.
*Constantsasper{@linkandroid.view.Surface.Rotation}.
*
*@see#updateRotationUnchecked()
*///privateintmRotation=0;privateintmRotation=3;//cczhengaddforlandscap
修正默许值config_reverseDefaultRotation为true,翻转显现角度
frameworks\base\core\res\res\values\config.xml
true
270
2、屏幕接触坐标修正为横屏
对调frame的宽和高,设置方向为270
frameworks\native\services\surfaceflinger\DisplayDevice.cpp
voidDisplayDevice::setProjection(intorientation,constRect&newViewport,constRect&newFrame){Rectviewport(newViewport);Rectframe(newFrame);constintw=mDisplayWidth;constinth=mDisplayHeight;
TransformR;
DisplayDevice::orientationToTransfrom(orientation,w,h,&R);if(!frame.isValid()){//thedestinationframecanbeinvalidifithasneverbeenset,//inthatcaseweassumethewholedisplayframe.//cczhengaddforlandscap//frame=Rect(w,h);if(w
frame=Rect(h,w);elseframe=Rect(w,h);
}
….
}//clang-formatoffDisplayDevice::DisplayDevice(constsp&flinger,
DisplayTypetype,
int32_thwcId,
boolisSecure,constwp&displayToken,constsp&nativeWindow,constsp&displaySurface,
std::unique_ptrrenderSurface,intdisplayWidth,intdisplayHeight,
boolhasWideColorGamut,constHdrCapabilities&hdrCapabilities,constint32_tsupportedPerFrameMetadata,conststd::unordered_map&hwcColorModes,intinitialPowerMode)
…..
mHdrCapabilities=HdrCapabilities(types,maxLuminance,maxAverageLuminance,minLuminance);//initializethedisplayorientationtransform.//setProjection(DisplayState::eOrientationDefault,mViewport,mFrame);//cczhengaddforlandscapsetProjection(DisplayState::eOrientation270,mViewport,mFrame);
#ifdefMTK_SF_DEBUG_SUPPORT
mFps=FpsCounterLoader::getInstance().create();
#endif
}
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
voidSurfaceFlinger::onInitializeDisplays(){//resetscreenorientationanduseprimarylayerstackVectorstate;
Vectordisplays;
DisplayStated;
d.what=DisplayState::eDisplayProjectionChanged|
DisplayState::eLayerStackChanged;
d.token=mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
d.layerStack=0;//d.orientation=DisplayState::eOrientationDefault;//cczhengaddforlandscapd.orientation=DisplayState::eOrientation270;
d.frame.makeInvalid();
d.viewport.makeInvalid();
d.width=0;
d.height=0;
displays.add(d);
….
}
3、开机动画横屏
对调createSurface()的w和h
frameworks\base\cmds\bootanimation\BootAnimation.cpp
status_tBootAnimation::readyToRun(){
mAssets.addDefaultAssets();spdtoken(SurfaceComposerClient::getBuiltInDisplay(
ISurfaceComposer::eDisplayIdMain));
DisplayInfodinfo;
status_tstatus=SurfaceComposerClient::getDisplayInfo(dtoken,&dinfo);if(status)return-1;//createthenativesurface/*spcontrol=session()->createSurface(String8(“BootAnimation”),
dinfo.w,dinfo.h,PIXEL_FORMAT_RGB_565);*///cczhengaddforlandscap[S]spcontrol;if(dinfo.w
control=session()->createSurface(String8(“BootAnimation”),
dinfo.h,dinfo.w,PIXEL_FORMAT_RGB_565);elsecontrol=session()->createSurface(String8(“BootAnimation”),
dinfo.w,dinfo.h,PIXEL_FORMAT_RGB_565);//cczhengaddforlandscap[E]SurfaceComposerClient::Transactiont;
t.setLayer(control,0x40000000)
.apply();
…..
}
开机动画制造替换后边弥补。。。
4、开机logo、关机充电动画横屏
开机logo定义屏幕分辨率以对应资源文件夹的方位为
vendor\mediatek\proprietary\bootable\bootloader\lk\project\xxxx.mk没有则看下面的
device\mediateksample\xxxx\ProjectConfig.mk
mk中的BOOT_LOGO=wxga
对应的资源文件方位在vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo/wxga
能够看到wxga中都是竖屏的图片,而wxganl中已经是横屏的图片
ubWkNt.png
则咱们将BOOT_LOGO修正为wxganl即可
接下来还需求继续修正显现的角度,仍旧改成270,否则会呈现花屏的现象
开机第一张图片uboot对应显现
vendor\mediatek\proprietary\bootable\bootloader\lk\platform\mt6765\mt_logo.c
voidinit_fb_screen(){
…..//inJB2.MPneedtoallignwidthandheightto32,butjb5.mpneedn’tphical_screen.needAllign=1;
phical_screen.allignWidth=ALIGN_TO(CFG_DISPLAY_WIDTH,MTK_FB_ALIGNMENT);/*InGB,noneedtoadjust180showinglogo,forfbdriverdealingthechange*//*butinJB,needadjustitforscreen180roration*/phical_screen.need180Adjust=0;//needsyncwithchipdriverdprintf(INFO,”[lklogo:%s%d]MTK_LCM_PHYSICAL_ROTATION=%s\n”,__FUNCTION__,__LINE__,MTK_LCM_PHYSICAL_ROTATION);if(0==strncmp(MTK_LCM_PHYSICAL_ROTATION,”270″,3)){
phical_screen.rotation=270;
}elseif(0==strncmp(MTK_LCM_PHYSICAL_ROTATION,”90″,2)){
phical_screen.rotation=90;
}elseif(0==strncmp(MTK_LCM_PHYSICAL_ROTATION,”180″,3)&&(phical_screen.need180Adjust==1)){
phical_screen.rotation=180;
}else{
phical_screen.rotation=270;//cczhengaddforlandscap}
….
开机第二张图片kernel对应显现
vendor\mediatek\proprietary\external\libshowlogo\charging_animation.cpp
intanim_fb_init(void){
…..
phical_screen.needAllign=1;
phical_screen.need180Adjust=1;
phical_screen.fb_size=fb_size;if(MTK_LOG_ENABLE==1){
SLOGD(“[libshowlogo:%s%d]MTK_LCM_PHYSICAL_ROTATION=%s\n”,__FUNCTION__,__LINE__,MTK_LCM_PHYSICAL_ROTATION);
}if(0==strncmp(MTK_LCM_PHYSICAL_ROTATION,”270″,3))
{
phical_screen.rotation=270;
}elseif(0==strncmp(MTK_LCM_PHYSICAL_ROTATION,”90″,2)){
phical_screen.rotation=90;
}elseif(0==strncmp(MTK_LCM_PHYSICAL_ROTATION,”180″,3)&&(phical_screen.need180Adjust==1)){
phical_screen.rotation=180;
}else{
phical_screen.rotation=270;//cczhengaddforlandscap}if(MTK_LOG_ENABLE==1){
SLOGD(“[libshowlogo]phical_screen:width=%d,height=%d,bits_per_pixel=%d,needAllign=%d,allignWidth=%drotation=%d,need180Adjust=%d\n”,
phical_screen.width,phical_screen.height,
phical_screen.bits_per_pixel,phical_screen.needAllign,
phical_screen.allignWidth,phical_screen.rotation,phical_screen.need180Adjust);
SLOGD(“[libshowlogo:%s%d]showoldanimtion=1,runningshow_animationm_ver%d\n”,__FUNCTION__,__LINE__,show_animationm_ver);
SLOGD(“[libshowlogo:%s%d]draw_anim_mode=1,runningmode%d\n”,__FUNCTION__,__LINE__,draw_anim_mode);
}return0;
}
假如呈现充电动画图片错位的现象,大都都是由于图形制作点和屏幕尺度不匹配导致的。可通过调整cust_display.h中方位参数
AndroidM后:/vendor/mediatek/proprietary/external/libshowlogo/cust_display.h
AndroidM前:/vendor/mediatek/proprietary/bootable/bootloader/lk/target/${PROJECT}/include/target/cust_display.h
(1,运用oldversion动画计划的调整如下设置,
#defineBAR_LEFT(215)
#defineBAR_TOP(156)
#defineBAR_RIGHT(265)
#defineBAR_BOTTOM(278)
能够用windows的画图软件翻开第1点里提到的图片,根据电池边框的像素来调整。
这里坐标的参阅原点是左上角,背景图片的左上角是(0,0),这四个值都是相对于左上角的坐标来确认的,因此RIGHT>LEFT,BOTTOM>TOP
小技巧:1)翻开画图软件,挑选检查->缩放->自定义,将图片放到到800%
2)挑选检查->缩放->显现网格
这样就能够看到一个一个的像素
(2,运用newversion动画计划调整如下设置:
#defineCAPACITY_LEFT(278)#defineCAPACITY_TOP(556)#defineCAPACITY_RIGHT(441)#defineCAPACITY_BOTTOM(817)
5、RecoveryUI横屏
参阅之前写的文章MTKRecovery模式横屏修正(适用于6.0+8.1+9.0)
6、体系导航栏方位调整,横屏后navigationBarPosition默许在左面
作为平板项目,需求将方位改为底部,直接修正navigationBarPosition()回来NAV_BAR_BOTTOM
frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java
@NavigationBarPositionprivateintnavigationBarPosition(intdisplayWidth,intdisplayHeight,intdisplayRotation){//cchznegannotaionforlandscape/*if(mNavigationBarCanMove&&displayWidth>displayHeight){
if(displayRotation==Surface.ROTATION_270){
returnNAV_BAR_LEFT;
}else{
returnNAV_BAR_RIGHT;
}
}*/returnNAV_BAR_BOTTOM;
}
这样方位是变为底部了,但是三个按钮都重叠在一起了,需求修正SystemUI的布局显现
在这里插入图片描绘
vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\statusbar\phone\NavigationBarView.java
privatevoidupdateRotatedViews(){//cczhengchangerot0rot90forlandscapemRotatedViews[Surface.ROTATION_0]=
mRotatedViews[Surface.ROTATION_180]=findViewById(R.id.rot90);//mRotatedViews[Surface.ROTATION_180]=findViewById(R.id.rot0);mRotatedViews[Surface.ROTATION_270]=
mRotatedViews[Surface.ROTATION_90]=findViewById(R.id.rot0);//mRotatedViews[Surface.ROTATION_90]=findViewById(R.id.rot90);updateCurrentView();
}
顺带再调整下NavigationBarView的默许高度和左面Back键区域太大的问题
vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\statusbar\phone\NavigationBarInflaterView.java
privateViewcreateView(StringbuttonSpec,ViewGroupparent,LayoutInflaterinflater){
Viewv=null;
Stringbutton=extractButton(buttonSpec);if(LEFT.equals(button)){//cchzhengchangeNAVSPACEtoMENU_IMEforsmallleftbackclickareaStrings=Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT,MENU_IME_ROTATE/*NAVSPACE*/);
button=extractButton(s);
}elseif(RIGHT.equals(button)){
Strings=Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT,MENU_IME_ROTATE);
button=extractButton(s);
}
…
frameworks\base\core\res\res\values\dimens.xml
“navigation_bar_height”>30dp
ok,这样就大功告成了,完美的横屏适配