Android 9.0 app全屏通过系统属性控制手势上滑是否显示虚拟导航栏和状态栏

发布时间 2023-12-04 15:27:00作者: xiaowang_lj

1.前言

在9.0的系统rom产品定制化os开发中,在系统设置app的全屏后,默认会隐藏导航栏和状态栏,页面全屏显示的时候,

然后底部上滑会显示虚拟状态栏和导航栏显示几秒钟后会自动消失,由于项目开发需要要求通过api

来控制全屏时上滑是否显示虚拟导航栏和状态栏,这就要从上滑事件分析看如何显示虚拟导航栏和状态栏的流程来控制是否显示

2.app全屏通过系统属性控制手势上滑是否显示虚拟导航栏和状态栏的核心类

  1.  
    frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
  2.  
    frameworks/base/services/core/java/com/android/server/policy/BarController.java

3.app全屏通过系统属性控制手势上滑是否显示虚拟导航栏和状态栏的核心功能分析和实现

3.1PhoneWindowManager.java中关于系统手势的相关源码分析

         // monitor for system gestures
          // TODO(multi-display): Needs to be display specific.
          mSystemGestures = new SystemGesturesPointerEventListener(context,
                  new SystemGesturesPointerEventListener.Callbacks() {
                      @Override
                      public void onSwipeFromTop() {
                          if (mStatusBar != null) {
                              requestTransientBars(mStatusBar);
                          }
                      }
                      @Override
                      public void onSwipeFromBottom() {
                          if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) {
                              requestTransientBars(mNavigationBar);
                          }
                      }
                      @Override
                      public void onSwipeFromRight() {
                          if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_RIGHT) {
                              requestTransientBars(mNavigationBar);
                          }
                      }
                      @Override
                      public void onSwipeFromLeft() {
                          if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_LEFT) {
                              requestTransientBars(mNavigationBar);
                          }
                      }
                      @Override
                      public void onFling(int duration) {
                          if (mPowerManagerInternal != null) {
                              mPowerManagerInternal.powerHint(
                                      PowerHint.INTERACTION, duration);
                          }
                      }
                      @Override
                      public void onDebug() {
                          // no-op
                      }
                      @Override
                      public void onDown() {
                          mOrientationListener.onTouchStart();
                      }
                      @Override
                      public void onUpOrCancel() {
                          mOrientationListener.onTouchEnd();
                      }
                      @Override
                      public void onMouseHoverAtTop() {
                          mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
                          Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
                          msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS;
                          mHandler.sendMessageDelayed(msg, 500);
                      }
                      @Override
                      public void onMouseHoverAtBottom() {
                          mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
                          Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
                          msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION;
                          mHandler.sendMessageDelayed(msg, 500);
                      }
                      @Override
                      public void onMouseLeaveFromEdge() {
                          mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
                      }
                  });
          mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext);
          mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);

 

在PhoneWindowManager.java的上述源码中,可以看出在SystemGesturesPointerEventListener中的相关源码中

在onSwipeFromBottom() 就是系统手势上滑处理的方法,然后掉requestTransientBars(mNavigationBar);执行相关功能

接下来分析下requestTransientBars(mNavigationBar)的相关源码

    private void requestTransientBars(WindowState swipeTarget) {
          synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
              if (!isUserSetupComplete()) {
                  // Swipe-up for navigation bar is disabled during setup
                  return;
              }
              boolean sb = mStatusBarController.checkShowTransientBarLw();
              boolean nb = mNavigationBarController.checkShowTransientBarLw()
                      && !isNavBarEmpty(mLastSystemUiFlags);
              if (sb || nb) {
                  // Don't show status bar when swiping on already visible navigation bar
                  if (!nb && swipeTarget == mNavigationBar) {
                      if (DEBUG) Slog.d(TAG, "Not showing transient bar, wrong swipe target");
                      return;
                  }
               // add core start 
              int settings_custom = Settings.Global.getInt(getContext().getContentResolver(),"settings_custom",0);
              if (settings_custom ==1){
                 if (sb) mStatusBarController.showTransient();
                 if (nb) mNavigationBarController.showTransient();
              }
              // add core end
                  mImmersiveModeConfirmation.confirmCurrentPrompt();
                  updateSystemUiVisibilityLw();
              }
          }
      }

 

在PhoneWindowManager.java的上述源码中,可以看出在requestTransientBars(WindowState swipeTarget)中的

上述方法,在通过代码中

if (sb) mStatusBarController.showTransient();

if (nb) mNavigationBarController.showTransient();

来判断是否显示状态栏和导航栏,所以通过上述增加系统属性根据系统属性值来判断是否打开系统状态栏和导航栏来实现功能的开发

3.2 StatusBarController.java关于状态栏的相关代码

    public void setContentFrame(Rect frame) {
         mContentFrame.set(frame);
     }
  
      public void setShowTransparent(boolean transparent) {
          if (transparent != mShowTransparent) {
              mShowTransparent = transparent;
              mSetUnHideFlagWhenNextTransparent = transparent;
              mNoAnimationOnNextShow = true;
          }
      }
  
      public void showTransient() {
          if (mWin != null) {
              setTransientBarState(TRANSIENT_BAR_SHOW_REQUESTED);
          }
      }
    public boolean checkShowTransientBarLw() {
          if (mTransientBarState == TRANSIENT_BAR_SHOWING) {
              if (DEBUG) Slog.d(mTag, "Not showing transient bar, already shown");
              return false;
          } else if (mTransientBarState == TRANSIENT_BAR_SHOW_REQUESTED) {
              if (DEBUG) Slog.d(mTag, "Not showing transient bar, already requested");
              return false;
          } else if (mWin == null) {
              if (DEBUG) Slog.d(mTag, "Not showing transient bar, bar doesn't exist");
              return false;
          } else if (mWin.isDisplayedLw()) {
              if (DEBUG) Slog.d(mTag, "Not showing transient bar, bar already visible");
              return false;
          } else {
              return true;
          }
      }

 

从BarController.java的上述相关代码中可以发现StatusBarController继承

BarController实现相关方法,核心方法就是在BarController.java中实现的

然后通过调用showTransient()来实现状态栏的 显示,而通过checkShowTransientBarLw()

来返回当前的状态栏导航栏是否显示,然后决定是否需要显示导航栏状态栏