framework——DisplayContent簡介

little_fat_sheep發表於2020-12-07

1 前言

DisplayContent 用於管理螢幕,一塊螢幕對應一個 DisplayContent 物件,雖然手機只有一個螢幕,但是可以建立多個 DisplayContent 物件,如投屏時,可以建立一個虛擬的 DisplayContent。

關於其父類及祖父類的介紹,見 → WindowContainer簡介ConfigurationContainer簡介,其父容器的介紹見 → RootWindowContainer簡介

 

2 原始碼

(1)類定義

//DisplayChildWindowContainer 為子節點型別
class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer> implements WindowManagerPolicy.DisplayContentInfo

(2)主要屬性

private final int mDisplayId

boolean isDefaultDisplay

ActivityDisplay mAcitvityDisplay

//apps (Activities) 容器
private final TaskStackContainers mTaskStackContainers = new TaskStackContainers(mWmService)

//頂部容器(如:Status bar 等)
private final AboveAppWindowContainers mAboveAppWindowsContainers = new AboveAppWindowContainers("mAboveAppWindowsContainers", mWmService)

//底部容器(如:Wallpaper、navigation bar 等)
private final NonAppWindowContainers mBelowAppWindowsContainers = new NonAppWindowContainers("mBelowAppWindowsContainers", mWmService)

//輸入法容器
private final NonAppWindowContainers mImeWindowsContainers = new NonAppWindowContainers("mImeWindowsContainers", mWmService)

final ArraySet<AppWindowToken> mOpeningApps = new ArraySet<>()

final ArraySet<AppWindowToken> mClosingApps = new ArraySet<>()

final ArraySet<AppWindowToken> mChangingApps = new ArraySet<>()

private final HashMap<IBinder, WindowToken> mTokenMap = new HashMap()

int mInitialDisplayWidth = 0

int mInitialDisplayHeight = 0

int mInitialDisplayDensity = 0

int mBaseDisplayWidth = 0

int mBaseDisplayHeight = 0

int mBaseDisplayDensity = 0

private final DisplayInfo mDisplayInfo = new DisplayInfo()

private final Display mDisplay

private final DisplayMetrics mDisplayMetrics = new DisplayMetrics()

private final DisplayPolicy mDisplayPolicy

private DisplayRotation mDisplayRotation

DisplayFrames mDisplayFrames

final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();

private final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();

private final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics()

float mCompatibleScreenScale

private int mRotation = 0

private int mLastOrientation = SCREEN_ORIENTATION_UNSPECIFIED;

private int mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;

private int mLastKeyguardForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;

private Rect mBaseDisplayRect = new Rect()

final ArrayList<WindowToken> mExitingTokens = new ArrayList<>()

final TaskTapPointerEventListener mTapDetector

final DockedStackDividerController mDividerControllerLocked

final PinnedStackController mPinnedStackControllerLocked

WallpaperController mWallpaperController

private final SurfaceSession mSession = new SurfaceSession()

WindowState mCurrentFocus = null;

WindowState mLastFocus = null

ArrayList<WindowState> mLosingFocus = new ArrayList<>()

AppWindowToken mFocusedApp = null

private SurfaceControl mOverlayLayer;

private SurfaceControl mWindowingLayer

private InputMonitor mInputMonitor

private boolean mLastHasContent

WindowState mInputMethodWindow

WindowState mInputMethodTarget

boolean mInputMethodTargetWaitingAnim

private final PointerEventDispatcher mPointerEventDispatcher

private final InsetsStateController mInsetsStateController

private WindowState mParentWindow

private Point mLocationInParentWindow = new Point()

private SurfaceControl mParentSurfaceControl

private InputWindowHandle mPortalWindowHandle

private final float mWindowCornerRadius

(3)構造方法

DisplayContent(Display display, WindowManagerService service, ActivityDisplay activityDisplay) {
    //Display相關
    mDisplay = display
    mDisplayId = display.getDisplayId()
    display.getDisplayInfo(mDisplayInfo)
    display.getMetrics(mDisplayMetrics)
    //桌布
    mWallpaperController = new WallpaperController(mWmService, this)
    //輸入相關(點選、觸控等)
    final InputChannel inputChannel =        mWmService.mInputManager.monitorInput("PointerEventDispatcher" + mDisplayId, mDisplayId)
    mInputMonitor = new InputMonitor(service, mDisplayId)
    mPointerEventDispatcher = new PointerEventDispatcher(inputChannel)
    mTapDetector = new TaskTapPointerEventListener(mWmService, this);
    registerPointerEventListener(mTapDetector);
    registerPointerEventListener(mWmService.mMousePositionTracker)
    //策略
    mDisplayPolicy = new DisplayPolicy(service, this)
    mDisplayRotation = new DisplayRotation(service, this)
    //新增子容器
    super.addChild(mBelowAppWindowsContainers, null)
    super.addChild(mTaskStackContainers, null)
    super.addChild(mAboveAppWindowsContainers, null)
    super.addChild(mImeWindowsContainers, null)
    //將該物件新增到根容器中
    mWmService.mRoot.addChild(this, null)
}

(4)獲取/注入屬性

//mDisplayId
int getDisplayId()

//mWindowCornerRadius
float getWindowCornerRadius()

//mTokenMap.get(binder)
WindowToken getWindowToken(IBinder binder)

//mDisplay
public Display getDisplay()

//mDisplayInfo
DisplayInfo getDisplayInfo()

//mDisplayMetrics
DisplayMetrics getDisplayMetrics()

//mDisplayPolicy
DisplayPolicy getDisplayPolicy()

//mInsetsStateController
InsetsStateController getInsetsStateController()

//mDisplayRotation
public DisplayRotation getDisplayRotation()

//mDisplayRotation = displayRotation
void setDisplayRotation(DisplayRotation displayRotation)

//mRotation
int getRotation()

//mRotation = newRotation
//mDisplayRotation.setRotation(newRotation)
void setRotation(int newRotation)

//mLastOrientation
int getLastOrientation()

//mLastWindowForcedOrientation
int getLastWindowForcedOrientation()

(5)消費者

//w 為 WindowState 型別
private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> {
    //mWmService.mWindowPlacerLocked.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5", pendingLayoutChanges)
}

private final Consumer<WindowState> mUpdateWallpaperForAnimator = w -> {
    //final AnimationAdapter anim = w.mAppToken != null ? w.mAppToken.getAnimation() : w.getAnimation()
    //final TaskStack stack = w.getStack()
    //stack.setAnimationBackground(winAnimator, color)
}

private final Consumer<WindowState> mScheduleToastTimeout = w -> {
    //final Handler handler = mWmService.mH
    //handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, w), w.mAttrs.hideTimeoutMilliseconds)
}

private final Consumer<WindowState> mPerformLayout = w -> {
    //w.resetContentChanged()
    //w.prelayout()
    //mDisplayPolicy.layoutWindowLw(w, null, mDisplayFrames)
    //w.updateLastInsetValues()
    //w.mAppToken.layoutLetterbox(w)
}

private final Consumer<WindowState> mPerformLayoutAttached = w -> {
    //w.resetContentChanged()
    //w.prelayout()
    //mDisplayPolicy.layoutWindowLw(w, w.getParentWindow(), mDisplayFrames)
}

private final Consumer<WindowState> mApplyPostLayoutPolicy = w -> { 
    //mDisplayPolicy.applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow(), mInputMethodTarget)
}

private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> {
    //mWallpaperController.updateWallpaperVisibility()
    //w.handleWindowMovedIfNeeded()
    //w.resetContentChanged()
    //mWmService.mH.obtainMessage(REPORT_LOSING_FOCUS, this).sendToTarget()
    //w.updateResizingWindowIfNeeded()
}

其中,Consumer 類如下:

public interface Consumer<T> {
    void accept(T t);
 
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

(6)謂詞

//w 為 WindowState 型別
private final Predicate<WindowState> mComputeImeTargetPredicate = w -> {
    //return w.canBeImeTarget()
}

其中,Predicate 介面如下:

public interface Predicate<T> {
    boolean test(T t);
    
    //與運算:return (t) -> test(t) && other.test(t)
    default Predicate<T> and(Predicate<? super T> other)
    
    //非運算:return (t) -> !test(t)
    default Predicate<T> negate()
    
    //或運算:return (t) -> test(t) || other.test(t)
    default Predicate<T> or(Predicate<? super T> other)
 
    //判等運算:return object -> targetRef.equals(object)
    static <T> Predicate<T> isEqual(Object targetRef)
}

(7)函式

private final ToBooleanFunction<WindowState> mFindFocusedWindow = w -> {
    //mTmpWindow = w
}

其中,ToBooleanFunction 介面如下: 

public interface ToBooleanFunction<T> {
    boolean apply(T value);
}

(8)Token 相關

//getWindowToken(binder).asAppWindowToken()
AppWindowToken getAppWindowToken(IBinder binder)

//final WindowToken token = removeWindowToken(binder)
//final AppWindowToken appToken = token.asAppWindowToken()
//appToken.onRemovedFromDisplay()
void removeAppToken(IBinder binder)

//final WindowToken token = mTokenMap.remove(binder)
WindowToken removeWindowToken(IBinder binder)

//addWindowToken(token.token, token)
void reParentWindowToken(WindowToken token)

(9)Orientation 相關

//mDisplayRotation.respectAppRequestedOrientation()
boolean handlesOrientationChangeFromDescendant()

//updateOrientationFromAppTokens(false)
boolean updateOrientationFromAppTokens()

//updateOrientationFromAppTokens(forceUpdate)
//computeScreenConfiguration(config)
Configuration updateOrientationFromAppTokens(Configuration currentConfig, IBinder freezeDisplayToken, boolean forceUpdate)

(10)Rotation 相關

//updateRotationAndSendNewConfigIfNeeded()
void resumeRotationLocked()

//final int rotation = mDisplayRotation.rotationForOrientation(lastOrientation, oldRotation)
boolean rotationNeedsUpdate()

//sendNewConfiguration()
boolean updateRotationAndSendNewConfigIfNeeded()

//updateRotationUnchecked(false)
boolean updateRotationUnchecked()

//final int rotation = mDisplayRotation.rotationForOrientation(lastOrientation, oldRotation)
//mWmService.mH.sendNewMessageDelayed(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT, this, WINDOW_FREEZE_TIMEOUT_DURATION)
//setLayoutNeeded()
boolean updateRotationUnchecked(boolean forceUpdate)

//mDisplayRotation.setRotation(rotation)
//updateDisplayAndOrientation(getConfiguration().uiMode, null)
void applyRotationLocked(final int oldRotation, final int rotation)

(11)其他方法

//mWmService.mDisplayReady && mDisplayReady
boolean isReady()

//mWmService.mH.obtainMessage(SEND_NEW_CONFIGURATION, this).sendToTarget()
void sendNewConfiguration()

//mDisplayPolicy.updateConfigurationAndScreenSizeDependentBehaviors();
//mDisplayRotation.configure(width, height, shortSizeDp, longSizeDp);
//mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo, calculateDisplayCutoutForRotation(mDisplayInfo.rotation))
void configureDisplayPolicy()

//mWmService.mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence)
void computeScreenConfiguration(Configuration config)