log打印
在日志中经常可以看到打印
WindowManager: Override config changes=20005df8 {0.0 ?mcc?mnc ?localeList ?layoutDir sw294dp w294dp h654dp 587dpi nrml long port ?uimode ?night -touch -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 1080, 2400) mAppBounds=Rect(0, 0 - 1080, 2400) mMaxBounds=Rect(0, 0 - 1080, 2400) mDisplayRotation=ROTATION_0 mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=undefined mAlwaysOnTop=undefined mRotation=ROTATION_0} ?fontWeightAdjustment} for displayId=2
代码路径:frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
int performDisplayOverrideConfigUpdate(Configuration values) {mTempConfig.setTo(getRequestedOverrideConfiguration());final int changes = mTempConfig.updateFrom(values);if (changes != 0) {Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "+ mTempConfig + " for displayId=" + mDisplayId);if (isReady() && mTransitionController.isShellTransitionsEnabled()) {requestChangeTransitionIfNeeded(changes, null /* displayChange */);}onRequestedOverrideConfigurationChanged(mTempConfig);final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;if (isDensityChange && mDisplayId == DEFAULT_DISPLAY) {mAtmService.mAppWarnings.onDensityChanged();// Post message to start process to avoid possible deadlock of calling into AMS with// the ATMS lock held.final Message msg = PooledLambda.obtainMessage(ActivityManagerInternal::killAllBackgroundProcessesExcept,mAtmService.mAmInternal, N,ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);mAtmService.mH.sendMessage(msg);}mWmService.mDisplayNotificationController.dispatchDisplayChanged(this, getConfiguration());}return changes;}
一般来说Configuration发生变化时,便会刷新打印关键log:Override config changes
这里的mTempConfig
就是Configuration
对象,其对应
Configuration
Configuration类则用于描述整个设备或应用的配置信息。它包含了更广泛的属性,如屏幕方向、触摸方式、字体缩放比例、MCC(移动国家码)、MNC(移动网络码)、地区设置、屏幕分辨率(以dp为单位)以及屏幕密度(以dpi为单位)等。
代码路径:frameworks/base/core/java/android/content/res/Configuration.java
/*** This class describes all device configuration information that can* impact the resources the application retrieves. This includes both* user-specified configuration options (locale list and scaling) as well* as device configurations (such as input modes, screen size and screen orientation).* <p>You can acquire this object from {@link Resources}, using {@link* Resources#getConfiguration}. Thus, from an activity, you can get it by chaining the request* with {@link android.app.Activity#getResources}:</p>* <pre>Configuration config = getResources().getConfiguration();</pre>*/
public final class Configuration implements Parcelable, Comparable<Configuration> {
public String toString() {StringBuilder sb = new StringBuilder(128);sb.append("{");sb.append(fontScale);sb.append(" ");if (mcc != 0) {sb.append(mcc);sb.append("mcc");} else {sb.append("?mcc");}if (mnc != MNC_ZERO) {sb.append(mnc);sb.append("mnc");} else {sb.append("?mnc");}fixUpLocaleList();if (!mLocaleList.isEmpty()) {sb.append(" ");sb.append(mLocaleList);} else {sb.append(" ?localeList");}if (mGrammaticalGender != 0) {switch (mGrammaticalGender) {case GRAMMATICAL_GENDER_NEUTRAL: sb.append(" neuter"); break;case GRAMMATICAL_GENDER_FEMININE: sb.append(" feminine"); break;case GRAMMATICAL_GENDER_MASCULINE: sb.append(" masculine"); break;case GRAMMATICAL_GENDER_NOT_SPECIFIED: sb.append(" ?grgend"); break;}}int layoutDir = (screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK);switch (layoutDir) {case SCREENLAYOUT_LAYOUTDIR_UNDEFINED: sb.append(" ?layoutDir"); break;case SCREENLAYOUT_LAYOUTDIR_LTR: sb.append(" ldltr"); break;case SCREENLAYOUT_LAYOUTDIR_RTL: sb.append(" ldrtl"); break;default: sb.append(" layoutDir=");sb.append(layoutDir >> SCREENLAYOUT_LAYOUTDIR_SHIFT); break;}if (smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {sb.append(" sw"); sb.append(smallestScreenWidthDp); sb.append("dp");} else {sb.append(" ?swdp");}if (screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) {sb.append(" w"); sb.append(screenWidthDp); sb.append("dp");} else {sb.append(" ?wdp");}if (screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {sb.append(" h"); sb.append(screenHeightDp); sb.append("dp");} else {sb.append(" ?hdp");}if (densityDpi != DENSITY_DPI_UNDEFINED) {sb.append(" "); sb.append(densityDpi); sb.append("dpi");} else {sb.append(" ?density");}switch ((screenLayout&SCREENLAYOUT_SIZE_MASK)) {case SCREENLAYOUT_SIZE_UNDEFINED: sb.append(" ?lsize"); break;case SCREENLAYOUT_SIZE_SMALL: sb.append(" smll"); break;case SCREENLAYOUT_SIZE_NORMAL: sb.append(" nrml"); break;case SCREENLAYOUT_SIZE_LARGE: sb.append(" lrg"); break;case SCREENLAYOUT_SIZE_XLARGE: sb.append(" xlrg"); break;default: sb.append(" layoutSize=");sb.append(screenLayout&SCREENLAYOUT_SIZE_MASK); break;}switch ((screenLayout&SCREENLAYOUT_LONG_MASK)) {case SCREENLAYOUT_LONG_UNDEFINED: sb.append(" ?long"); break;case SCREENLAYOUT_LONG_NO: /* not-long is not interesting to print */ break;case SCREENLAYOUT_LONG_YES: sb.append(" long"); break;default: sb.append(" layoutLong=");sb.append(screenLayout&SCREENLAYOUT_LONG_MASK); break;}switch ((colorMode &COLOR_MODE_HDR_MASK)) {case COLOR_MODE_HDR_UNDEFINED: sb.append(" ?ldr"); break; // most likely not HDRcase COLOR_MODE_HDR_NO: /* ldr is not interesting to print */ break;case COLOR_MODE_HDR_YES: sb.append(" hdr"); break;default: sb.append(" dynamicRange=");sb.append(colorMode &COLOR_MODE_HDR_MASK); break;}switch ((colorMode &COLOR_MODE_WIDE_COLOR_GAMUT_MASK)) {case COLOR_MODE_WIDE_COLOR_GAMUT_UNDEFINED: sb.append(" ?wideColorGamut"); break;case COLOR_MODE_WIDE_COLOR_GAMUT_NO: /* not wide is not interesting to print */ break;case COLOR_MODE_WIDE_COLOR_GAMUT_YES: sb.append(" widecg"); break;default: sb.append(" wideColorGamut=");sb.append(colorMode &COLOR_MODE_WIDE_COLOR_GAMUT_MASK); break;}switch (orientation) {case ORIENTATION_UNDEFINED: sb.append(" ?orien"); break;case ORIENTATION_LANDSCAPE: sb.append(" land"); break;case ORIENTATION_PORTRAIT: sb.append(" port"); break;default: sb.append(" orien="); sb.append(orientation); break;}switch ((uiMode&UI_MODE_TYPE_MASK)) {case UI_MODE_TYPE_UNDEFINED: sb.append(" ?uimode"); break;case UI_MODE_TYPE_NORMAL: /* normal is not interesting to print */ break;case UI_MODE_TYPE_DESK: sb.append(" desk"); break;case UI_MODE_TYPE_CAR: sb.append(" car"); break;case UI_MODE_TYPE_TELEVISION: sb.append(" television"); break;case UI_MODE_TYPE_APPLIANCE: sb.append(" appliance"); break;case UI_MODE_TYPE_WATCH: sb.append(" watch"); break;case UI_MODE_TYPE_VR_HEADSET: sb.append(" vrheadset"); break;default: sb.append(" uimode="); sb.append(uiMode&UI_MODE_TYPE_MASK); break;}switch ((uiMode&UI_MODE_NIGHT_MASK)) {case UI_MODE_NIGHT_UNDEFINED: sb.append(" ?night"); break;case UI_MODE_NIGHT_NO: /* not-night is not interesting to print */ break;case UI_MODE_NIGHT_YES: sb.append(" night"); break;default: sb.append(" night="); sb.append(uiMode&UI_MODE_NIGHT_MASK); break;}switch (touchscreen) {case TOUCHSCREEN_UNDEFINED: sb.append(" ?touch"); break;case TOUCHSCREEN_NOTOUCH: sb.append(" -touch"); break;case TOUCHSCREEN_STYLUS: sb.append(" stylus"); break;case TOUCHSCREEN_FINGER: sb.append(" finger"); break;default: sb.append(" touch="); sb.append(touchscreen); break;}switch (keyboard) {case KEYBOARD_UNDEFINED: sb.append(" ?keyb"); break;case KEYBOARD_NOKEYS: sb.append(" -keyb"); break;case KEYBOARD_QWERTY: sb.append(" qwerty"); break;case KEYBOARD_12KEY: sb.append(" 12key"); break;default: sb.append(" keys="); sb.append(keyboard); break;}switch (keyboardHidden) {case KEYBOARDHIDDEN_UNDEFINED: sb.append("/?"); break;case KEYBOARDHIDDEN_NO: sb.append("/v"); break;case KEYBOARDHIDDEN_YES: sb.append("/h"); break;case KEYBOARDHIDDEN_SOFT: sb.append("/s"); break;default: sb.append("/"); sb.append(keyboardHidden); break;}switch (hardKeyboardHidden) {case HARDKEYBOARDHIDDEN_UNDEFINED: sb.append("/?"); break;case HARDKEYBOARDHIDDEN_NO: sb.append("/v"); break;case HARDKEYBOARDHIDDEN_YES: sb.append("/h"); break;default: sb.append("/"); sb.append(hardKeyboardHidden); break;}switch (navigation) {case NAVIGATION_UNDEFINED: sb.append(" ?nav"); break;case NAVIGATION_NONAV: sb.append(" -nav"); break;case NAVIGATION_DPAD: sb.append(" dpad"); break;case NAVIGATION_TRACKBALL: sb.append(" tball"); break;case NAVIGATION_WHEEL: sb.append(" wheel"); break;default: sb.append(" nav="); sb.append(navigation); break;}switch (navigationHidden) {case NAVIGATIONHIDDEN_UNDEFINED: sb.append("/?"); break;case NAVIGATIONHIDDEN_NO: sb.append("/v"); break;case NAVIGATIONHIDDEN_YES: sb.append("/h"); break;default: sb.append("/"); sb.append(navigationHidden); break;}sb.append(" winConfig="); sb.append(windowConfiguration);if (assetsSeq != 0) {sb.append(" as.").append(assetsSeq);}if (seq != 0) {sb.append(" s.").append(seq);}if (fontWeightAdjustment != FONT_WEIGHT_ADJUSTMENT_UNDEFINED) {sb.append(" fontWeightAdjustment=");sb.append(fontWeightAdjustment);} else {sb.append(" ?fontWeightAdjustment");}sb.append('}');return sb.toString();}
常见参数介绍:
- fontScale:当前用户设置的字体的缩放因子
- mcc:获取移动信号的国家码
- mnc:获取移动信号的网络码
- locale:获取用户当前的语言环境
- densityDpi:屏幕密度
- navigation:判断系统上方向导航设备的类型。该属性的返回值:NAVIGATION_NONAV(无导航)、 NAVIGATION_DPAD(DPAD导航)NAVIGATION_TRACKBALL(轨迹球导航)、NAVIGATION_WHEEL(滚轮导航)
orientation:获取系统屏幕的方向。该属性的返回值:ORIENTATION_LANDSCAPE(横向屏幕)、ORIENTATION_PORTRAIT(竖向屏幕) - screenHeightDp,screenWidthDp:屏幕可用高和宽,用dp表示
- touchscreen:获取系统触摸屏的触摸方式。该属性的返回值:TOUCHSCREEN_NOTOUCH(无触摸屏)、TOUCHSCREEN_STYLUS(触摸笔式触摸屏)、TOUCHSCREEN_FINGER(接收手指的触摸屏)
- windowConfiguration:窗口相关信息
windowConfiguration
WindowConfiguration是用来描述窗口的配置信息的类,包括窗口的大小、位置、方向、可见性等。WindowConfiguration会在以下情况下更新:
- 屏幕方向改变:当设备的屏幕方向发生改变时,WindowConfiguration会更新以反映新的方向。
- 窗口大小改变:当窗口的大小发生改变时,WindowConfiguration会更新以反映新的大小。
- 窗口位置改变:当窗口的位置发生改变时,WindowConfiguration会更新以反映新的位置。
- 窗口可见性改变:当窗口的可见性发生改变时,WindowConfiguration会更新以反映新的可见性。
- 窗口类型改变:当窗口的类型发生改变时,WindowConfiguration会更新以反映新的类型。
总之,当窗口的任何配置信息发生改变时,WindowConfiguration都会更新以反映新的配置信息
代码路径:frameworks/base/core/java/android/app/WindowConfiguration.java
/*** Class that contains windowing configuration/state for other objects that contain windows directly* or indirectly. E.g. Activities, Task, Displays, ...* The test class is {@link com.android.server.wm.WindowConfigurationTests} which must be kept* up-to-date and ran anytime changes are made to this class.* @hide*/
@TestApi
public class WindowConfiguration implements Parcelable, Comparable<WindowConfiguration> {
@Overridepublic String toString() {return "{ mBounds=" + mBounds+ " mAppBounds=" + mAppBounds+ " mMaxBounds=" + mMaxBounds+ " mDisplayRotation=" + (mRotation == ROTATION_UNDEFINED? "undefined" : rotationToString(mDisplayRotation))+ " mWindowingMode=" + windowingModeToString(mWindowingMode)+ " mDisplayWindowingMode=" + windowingModeToString(mDisplayWindowingMode)+ " mActivityType=" + activityTypeToString(mActivityType)+ " mAlwaysOnTop=" + alwaysOnTopToString(mAlwaysOnTop)+ " mRotation=" + (mRotation == ROTATION_UNDEFINED? "undefined" : rotationToString(mRotation))+ "}";}
常见参数介绍:
- mWindowingMode:窗口模式,用于描述窗口的显示方式,包括以下几种模式: - WINDOWING_MODE_UNDEFINED:未定义的窗口模式。 - WINDOWING_MODE_FULLSCREEN:全屏模式,窗口将占据整个屏幕。 - WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:分屏模式,窗口将占据屏幕的一半。 - WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:分屏模式,窗口将占据屏幕的另一半。 - WINDOWING_MODE_FREEFORM:自由形式模式,窗口可以自由调整大小和位置。
- mActivityType:活动类型,用于描述窗口所属的活动类型,包括以下几种类型: - ACTIVITY_TYPE_UNDEFINED:未定义的活动类型。 - ACTIVITY_TYPE_STANDARD:标准活动类型,即普通的Activity。 - ACTIVITY_TYPE_HOME:主页活动类型,即Launcher。 - ACTIVITY_TYPE_RECENTS:最近使用的活动类型,即Recents。 - ACTIVITY_TYPE_ASSISTANT:助手活动类型,即Assistant。
- mRotation:屏幕方向,用于描述窗口所处的屏幕方向,包括以下几种方向: - ROTATION_UNDEFINED:未定义的屏幕方向。 - ROTATION_0:竖屏方向。 - ROTATION_90:横屏方向。 - ROTATION_180:反向竖屏方向。 - ROTATION_270:反向横屏方向。
- mBounds:窗口边界,用于描述窗口的位置和大小。
- mAppBounds:应用边界,用于描述应用的位置和大小。
- mAlwaysOnTop:是否始终置顶,用于描述窗口是否始终置顶。
isAlwaysOnTop():判断是否置顶 - isFloating():是否浮动,用于描述窗口是否浮动。