基于Android R版别分析

在多个屏幕上显现StatusBar和NavigationBar,需求修正两个方位:

  • DisplayPolicy

    • 在DisplayPolicy中有两个变量:mHasStatusBarmHasNavigationBar,该变量用于判别当前屏幕中是否需求显现StatusBar和NavigationBar;

      • mHasStatusBar:默许在DefaultDisplay中显现,在其他非DefaultDisplay中不显现;
      • mHasNavigationBar:根据 “qemu.hw.mainkeys” 这个SystemProperties来标识是否需求显现;
  • SystemUI进程中:在SystemUI代码中,需求主动的遍历所有的DisplayIds,为每一个Display配套一组StatusBar和NavigationBar,本质上其实便是为每一个Display创建两个Window窗口用于承载对应的StatusBar和NavigationBar,这个StatusBar和NavigationBar可以和主屏显现相同,也可以定制化副屏的StatusBar和NavigationBar;

DisplayPolicy patch

diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 2267bcb3..d6aa613b 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -157,6 +157,7 @@ import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.util.ArraySet;
 import android.util.IntArray;
+import android.util.Log;
 import android.util.Pair;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
@@ -649,18 +650,27 @@ public class DisplayPolicy {
     if (mDisplayContent.isDefaultDisplay) {
       mHasStatusBar = true;
+      // 在/frameworks/base/core/res/res/values/config.xml中定义的config_showNavigationBar:
+      // <bool name="config_showNavigationBar">false</bool>
       mHasNavigationBar = mContext.getResources().getBoolean(R.bool.config_showNavigationBar);
       // Allow a system property to override this. Used by the emulator.
       // See also hasNavigationBar().
+      // 经过该SystemProperties来操控display是否需求显现navigation bar
       String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
+      /**
+       * qemu.hw.mainkeys = 1 //不存在
+       * qemu.hw.mainkeys = 0 //存在
+       */
       if ("1".equals(navBarOverride)) {
         mHasNavigationBar = false;
       } else if ("0".equals(navBarOverride)) {
         mHasNavigationBar = true;
       }
     } else {
-      mHasStatusBar = false;
+      // 默许在副屏中,StatusBar不显现,即使在SystemUI中强制使其显现,但是在DisplayPolicy中也不会符号
+      // StatusBar已显现
+      mHasStatusBar = true;
       mHasNavigationBar = mDisplayContent.supportsSystemDecorations();
     }
@@ -748,6 +758,7 @@ public class DisplayPolicy {
     return mDockMode;
   }
+  // 在CUX SystemUI中判斷是否需求显现navigation bar便是经过DisplayPolicy中的hasNavigationBar实现的
   public boolean hasNavigationBar() {
     return mHasNavigationBar;
   }
@@ -3033,18 +3044,30 @@ public class DisplayPolicy {
   /**
   * Called when the configuration has changed, and it's safe to load new values from resources.
+   *
+   * onConfigurationChanged事件并不是只要屏幕方向改动才可以触发,其他的一些系统设置改动也可以触发,比如翻开或许隐藏键盘
   */
   public void onConfigurationChanged() {
     final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
     final Resources res = getCurrentUserResources();
+    // 这个几个rotation代表了横竖屏设置的参数
+    /**
+     * portrait Rotation:肖像 旋转
+     * landscape Rotation:景象 旋转
+     */
     final int portraitRotation = displayRotation.getPortraitRotation();
     final int upsideDownRotation = displayRotation.getUpsideDownRotation();
     final int landscapeRotation = displayRotation.getLandscapeRotation();
     final int seascapeRotation = displayRotation.getSeascapeRotation();
     final int uiMode = mService.mPolicy.getUiMode();
+    /**
+     * 判别DisplayContent对应的DisplayPolicy中是否符号了已存在hasStatusBar
+     * 默许在副屏中不存在StatusBar
+     */
     if (hasStatusBar()) {
+      // 在判别答应存在StatusBar之后,StatusBarHeight的值就不能为0
       mStatusBarHeightForRotation[portraitRotation] =
           mStatusBarHeightForRotation[upsideDownRotation] =
               res.getDimensionPixelSize(R.dimen.status_bar_height_portrait);
@@ -3244,6 +3267,14 @@ public class DisplayPolicy {
   * decorations that could never be removed in Honeycomb. That is, system bar or
   * button bar.
   */
+  /**
+   * 使用区域分两种状况:
+   *  1、当导航栏显现的时分,使用区域会减去导航栏的高度
+   *  2、当状态栏显现的时分,使用区域的距离会减去状态栏的高度
+   *
+   *  在原生的逻辑中,只考虑了navigation bar的height和cutout的height,由于statusbar在副屏的height默许为0,
+   *  所以就没有考虑statusBar的height
+   */
   public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
       DisplayCutout displayCutout) {
     int height = fullHeight;
@@ -3288,6 +3319,13 @@ public class DisplayPolicy {
       // bar height.
       statusBarHeight = Math.max(0, statusBarHeight - displayCutout.getSafeInsetTop());
     }
+    // 获取使用区域的高度
+    /**
+     * 使用区域分两种状况:
+     *  1、当导航栏显现的时分,使用区域会减去导航栏的高度
+     *  2、当状态栏显现的时分,使用区域的距离会减去状态栏的高度(StatusBar的height需求手动的进行删除,由于
+     *   getNonDecorDisplayHeight方法中没有考虑StatusBar)
+     */
     return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation, uiMode, displayCutout)
         - statusBarHeight;
   }