public void layoutWindowLw(WindowState win, WindowState attached, DisplayFrames displayFrames) {
// We've already done the navigation bar, status bar, and all screen decor windows. If the
// status bar can receive input, we need to layout it again to accommodate for the IME
// window.
if ((win == mStatusBar && !canReceiveInput(win)) || win == mNavigationBar || win == mNavigationBar || win == mCarDialLeft || win == mCarDialRight
|| mScreenDecorWindows.contains(win)) {
return;
}
final WindowManager.LayoutParams attrs = win.getAttrs();
final int type = attrs.type;
final int fl = PolicyControl.getWindowFlags(win, attrs);
final int pfl = attrs.privateFlags;
final int sim = attrs.softInputMode;
final int requestedSysUiFl = 0; //PolicyControl.getSystemUiVisibility(null, attrs);
final int sysUiFl = 0; // requestedSysUiFl | getImpliedSysUiFlagsForLayout(attrs);
if(DEBUG_HUIDU){
Slog.d(TAG, "huidu add getsystemuivisibility type = " + type + " fl = " + fl + " pfl = " + pfl + " sim = " + sim + " requestedSysUiFl = " + requestedSysUiFl + " sysUiFl = " + sysUiFl);
}
if( win.getOwningPackage()!= null){
String pkg_bright = win.getOwningPackage();
// "com.android.systemui/com.android.systemui.settings.BrightnessDialog"
if("com.android.systemui".equals(pkg_bright)){
Log.d(TAG, "huidu add layoutWindowLw systemui = " + win);
return ;
}
}
displayFrames = win.getDisplayFrames(displayFrames);
final WindowFrames windowFrames = win.getWindowFrames();
sTmpLastParentFrame.set(windowFrames.mParentFrame);
final Rect pf = windowFrames.mParentFrame;
final Rect df = windowFrames.mDisplayFrame;
final Rect cf = windowFrames.mContentFrame;
final Rect vf = windowFrames.mVisibleFrame;
final Rect dcf = windowFrames.mDecorFrame;
final Rect sf = windowFrames.mStableFrame;
dcf.setEmpty();
windowFrames.setParentFrameWasClippedByDisplayCutout(false);
final boolean hasNavBar = hasNavigationBar() && ((mNavigationBar != null
&& mNavigationBar.isVisibleLw()) || (mCarDialLeft != null
&& mCarDialLeft.isVisibleLw()) || (mCarDialRight != null
&& mCarDialRight.isVisibleLw()));
final int adjust = sim & SOFT_INPUT_MASK_ADJUST;
final boolean layoutInScreen = (fl & FLAG_LAYOUT_IN_SCREEN) == FLAG_LAYOUT_IN_SCREEN;
final boolean layoutInsetDecor = (fl & FLAG_LAYOUT_INSET_DECOR) == FLAG_LAYOUT_INSET_DECOR;
sf.set(displayFrames.mStable);
if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL) {
final @InsetsType int typesToFit = attrs.getFitInsetsTypes();
final @InsetsSide int sidesToFit = attrs.getFitInsetsSides();
final ArraySet<Integer> types = InsetsState.toInternalType(typesToFit);
final Rect dfu = displayFrames.mUnrestricted;
Insets insets = Insets.of(0, 0, 0, 0);
for (int i = types.size() - 1; i >= 0; i--) {
final InsetsSource source = mDisplayContent.getInsetsPolicy()
.getInsetsForDispatch(win).peekSource(types.valueAt(i));
if (source == null) {
continue;
}
insets = Insets.max(insets, source.calculateInsets(
dfu, attrs.isFitInsetsIgnoringVisibility()));
}
int left = (sidesToFit & Side.LEFT) != 0 ? insets.left : 0;
final int top = (sidesToFit & Side.TOP) != 0 ? insets.top : 0;
int right = (sidesToFit & Side.RIGHT) != 0 ? insets.right : 0;
final int bottom = (sidesToFit & Side.BOTTOM) != 0 ? insets.bottom : 0;
final boolean isAppScren = true;
// dfu 是显示器大小:dfu.right = 1920,dfu.bottom = 560
final String pkg = win.getOwningPackage();
if(DEBUG_HUIDU){
Log.w(TAG,"huidu add getOwningPackage = "+pkg);
}
if(pkg != null){
if(pkg.equals("com.android.systemui")){
return ;
}
}
if(isAppScren){
// huidu add
if(!"cn.huidu.lcd.player".equals(pkg) && !"cn.huidu.toolbox".equals(pkg)){
if(mCarDialLeft!=null && mCarDialLeft.isVisibleLw()){
left = getNavigationCarBarWidth(mCarDialLeft,displayFrames.mRotation,mDisplayContent.getConfiguration().uiMode);
}
if(mCarDialRight!=null && mCarDialRight.isVisibleLw()){
right = getNavigationCarBarWidth(mCarDialRight,displayFrames.mRotation,mDisplayContent.getConfiguration().uiMode);
}
}
}
if(DEBUG_HUIDU){
Log.w(TAG,"huidu add getOwningPackage left "+left+",top="+top+",right="+(dfu.right - right)+",bottom="+(dfu.bottom - bottom));
}
df.set(left, top, dfu.right - right, dfu.bottom - bottom);
// df.set(left, top, dfu.right - right, dfu.bottom - bottom);
//df.set(400, top, 1520, dfu.bottom - bottom);
/// HD CODE ADD special-shaped screen
if (SystemProperties.getBoolean("ro.hd.special.screen", false)) {
Slog.d(TAG, "huidu insets.left: " + insets.left + ", insets.top: " + insets.top + ", insets.right: " + insets.right + ", insets.bottom: " + insets.bottom);
Slog.d(TAG, "huidu pkg: " + pkg);
String mpkg = SystemProperties.get("persist.hd.display.packagename", "cn.huidu.lcd.player");
if (!pkg.equals(mpkg)) {
/// HD CODE ADD 为什么要平移窗口内容,因为切割屏时,它是从左上角原点往下
int mLeft = SystemProperties.getInt("ro.hd.display.left", 0);
int mTop = SystemProperties.getInt("ro.hd.display.top", 0);
int mRight = SystemProperties.getInt("ro.hd.display.right", 0);
int mBottom = SystemProperties.getInt("ro.hd.display.bottom", 0);
int navBarState = getNavBarState(mContext);
int statusBarState = getStatusBarState(mContext);
int navBarHeight = getNavigationBarHeight(displayFrames.mRotation, mDisplayContent.getConfiguration().uiMode);
int statusBarHeight = getStatusBarHeight(displayFrames);
Slog.d(TAG, " navBarState = " + navBarState + " navBarHeight = " + navBarHeight + " statusBarState = " + statusBarState + " statusBarHeight = " + statusBarHeight);
if (navBarState == 1 && statusBarState == 0) {
mTop -= statusBarHeight;
}
if (navBarState == 0) {
mBottom += navBarHeight;
}
df.set(mLeft, mTop, dfu.right - mRight, dfu.bottom - mBottom);
}
Slog.d(TAG, "huidu dfu.left: " + dfu.left + ", dfu.top: " + dfu.top + ", dfu.right: " + dfu.right + ", dfu.bottom: " + dfu.bottom);
}
/// HD CODE END
if (attached == null) {
pf.set(df);
if ((pfl & PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME) != 0) {
final InsetsSource source = mDisplayContent.getInsetsPolicy()
.getInsetsForDispatch(win).peekSource(ITYPE_IME);
if (source != null) {
pf.inset(source.calculateInsets(pf, false /* ignoreVisibility */));
}
}
vf.set(adjust != SOFT_INPUT_ADJUST_NOTHING
? displayFrames.mCurrent : displayFrames.mDock);
} else {
pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0 ? attached.getFrameLw() : df);
vf.set(attached.getVisibleFrameLw());
}
cf.set(adjust != SOFT_INPUT_ADJUST_RESIZE
? displayFrames.mDock : displayFrames.mContent);
dcf.set(displayFrames.mSystem);
} else if (type == TYPE_INPUT_METHOD) {
vf.set(displayFrames.mDock);
cf.set(displayFrames.mDock);
df.set(displayFrames.mDock);
pf.set(displayFrames.mDock);
// IM dock windows layout below the nav bar...
pf.bottom = df.bottom = displayFrames.mUnrestricted.bottom;
// ...with content insets above the nav bar
cf.bottom = vf.bottom = displayFrames.mStable.bottom;
if (mStatusBar != null && mFocusedWindow == mStatusBar && canReceiveInput(mStatusBar)) {
// The status bar forces the navigation bar while it's visible. Make sure the IME
// avoids the navigation bar in that case.
if (mNavigationBarPosition == NAV_BAR_RIGHT) {
pf.right = df.right = cf.right = vf.right =
displayFrames.mStable.right;
} else if (mNavigationBarPosition == NAV_BAR_LEFT) {
pf.left = df.left = cf.left = vf.left = displayFrames.mStable.left;
}
}
// In case the navigation bar is on the bottom, we use the frame height instead of the
// regular height for the insets we send to the IME as we need some space to show
// additional buttons in SystemUI when the IME is up.
if (mNavigationBarPosition == NAV_BAR_BOTTOM) {
final int rotation = displayFrames.mRotation;
final int uimode = mService.mPolicy.getUiMode();
final int navHeightOffset = getNavigationBarFrameHeight(rotation, uimode)
- getNavigationBarHeight(rotation, uimode);
if (navHeightOffset > 0) {
cf.bottom -= navHeightOffset;
sf.bottom -= navHeightOffset;
vf.bottom -= navHeightOffset;
dcf.bottom -= navHeightOffset;
}
}
// IM dock windows always go to the bottom of the screen.
attrs.gravity = Gravity.BOTTOM;
} else if (type == TYPE_VOICE_INTERACTION) {
df.set(displayFrames.mUnrestricted);
pf.set(displayFrames.mUnrestricted);
if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
cf.set(displayFrames.mDock);
} else {
cf.set(displayFrames.mContent);
}
if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
vf.set(displayFrames.mCurrent);
} else {
vf.set(cf);
}
} else if (type == TYPE_WALLPAPER) {
layoutWallpaper(displayFrames, pf, df, cf);
} else if (type == TYPE_CAR_DIAL_LEFT) { // huidu update : 添加车载界面处理
df.set(displayFrames.mUnrestricted);
pf.set(displayFrames.mUnrestricted);
cf.set(displayFrames.mUnrestricted);
vf.set(displayFrames.mUnrestricted);
attrs.gravity = Gravity.LEFT;
} else if (type == TYPE_CAR_DIAL_RIGHT) { // huidu update : 添加车载界面处理
df.set(displayFrames.mUnrestricted);
pf.set(displayFrames.mUnrestricted);
cf.set(displayFrames.mUnrestricted);
vf.set(displayFrames.mUnrestricted);
attrs.gravity = Gravity.RIGHT;
} else if (win == mStatusBar || type == TYPE_NOTIFICATION_SHADE) {
df.set(displayFrames.mUnrestricted);
pf.set(displayFrames.mUnrestricted);
cf.set(displayFrames.mStable);
vf.set(displayFrames.mStable);
if (adjust == SOFT_INPUT_ADJUST_RESIZE) {
// cf.bottom should not be below the stable bottom, or the content might be obscured
// by the navigation bar.
if (cf.bottom > displayFrames.mContent.bottom) {
cf.bottom = displayFrames.mContent.bottom;
}
} else {
if (cf.bottom > displayFrames.mDock.bottom) {
cf.bottom = displayFrames.mDock.bottom;
}
if (vf.bottom > displayFrames.mContent.bottom) {
vf.bottom = displayFrames.mContent.bottom;
}
}
} else {
dcf.set(displayFrames.mSystem);
final boolean isAppWindow =
type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW;
final boolean topAtRest =
win == mTopFullscreenOpaqueWindowState && !win.isAnimatingLw();
if (isAppWindow && !topAtRest) {
if ((sysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0
&& (fl & FLAG_FULLSCREEN) == 0
&& (fl & FLAG_TRANSLUCENT_STATUS) == 0
&& (fl & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
&& (pfl & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) == 0) {
// Ensure policy decor includes status bar
dcf.top = displayFrames.mStable.top;
}
if ((fl & FLAG_TRANSLUCENT_NAVIGATION) == 0
&& (sysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0
&& (fl & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
&& (pfl & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) == 0) {
// Ensure policy decor includes navigation bar
dcf.bottom = displayFrames.mStable.bottom;
dcf.right = displayFrames.mStable.right;
}
}
if (layoutInScreen && layoutInsetDecor) {
if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle()
+ "): IN_SCREEN, INSET_DECOR");
// This is the case for a normal activity window: we want it to cover all of the
// screen space, and it can take care of moving its contents to account for screen
// decorations that intrude into that space.
if (attached != null) {
// If this window is attached to another, our display
// frame is the same as the one we are attached to.
setAttachedWindowFrames(win, fl, adjust, attached, true, pf, df, cf, vf,
displayFrames);
} else {
if (type == TYPE_STATUS_BAR_ADDITIONAL || type == TYPE_STATUS_BAR_SUB_PANEL) {
// Status bar panels are the only windows who can go on top of the status
// bar. They are protected by the STATUS_BAR_SERVICE permission, so they
// have the same privileges as the status bar itself.
//
// However, they should still dodge the navigation bar if it exists.
pf.left = df.left = hasNavBar
? displayFrames.mDock.left : displayFrames.mUnrestricted.left;
pf.top = df.top = displayFrames.mUnrestricted.top;
pf.right = df.right = hasNavBar
? displayFrames.mRestricted.right
: displayFrames.mUnrestricted.right;
pf.bottom = df.bottom = hasNavBar
? displayFrames.mRestricted.bottom
: displayFrames.mUnrestricted.bottom;
if (DEBUG_LAYOUT) Slog.v(TAG, "Laying out status bar window: " + pf);
} else if ((sysUiFl & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
&& (type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW
|| type == TYPE_VOLUME_OVERLAY
|| type == TYPE_KEYGUARD_DIALOG)) {
// Asking for layout as if the nav bar is hidden, lets the application
// extend into the unrestricted overscan screen area. We only do this for
// application windows and certain system windows to ensure no window that
// can be above the nav bar can do this.
df.set(displayFrames.mUnrestricted);
pf.set(displayFrames.mUnrestricted);
} else {
df.set(displayFrames.mRestricted);
pf.set(displayFrames.mRestricted);
}
if ((fl & FLAG_FULLSCREEN) == 0) {
if (win.isVoiceInteraction()) {
cf.set(displayFrames.mVoiceContent);
} else {
// IME Insets are handled on the client for ADJUST_RESIZE in the new
// insets world
if (ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_NONE
|| adjust != SOFT_INPUT_ADJUST_RESIZE) {
cf.set(displayFrames.mDock);
} else {
cf.set(displayFrames.mContent);
}
}
} else {
// Full screen windows are always given a layout that is as if the status
// bar and other transient decors are gone. This is to avoid bad states when
// moving from a window that is not hiding the status bar to one that is.
cf.set(displayFrames.mRestricted);
}
applyStableConstraints(sysUiFl, fl, cf, displayFrames);
if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE
&& adjust != SOFT_INPUT_ADJUST_NOTHING) {
vf.set(displayFrames.mCurrent);
} else {
vf.set(cf);
}
}
} else if (layoutInScreen || (sysUiFl
& (SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)) != 0) {
if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle()
+ "): IN_SCREEN");
// A window that has requested to fill the entire screen just
// gets everything, period.
if (type == TYPE_STATUS_BAR_ADDITIONAL || type == TYPE_STATUS_BAR_SUB_PANEL) {
cf.set(displayFrames.mUnrestricted);
df.set(displayFrames.mUnrestricted);
pf.set(displayFrames.mUnrestricted);
if (hasNavBar) {
pf.left = df.left = cf.left = displayFrames.mDock.left;
pf.right = df.right = cf.right = displayFrames.mRestricted.right;
pf.bottom = df.bottom = cf.bottom =
displayFrames.mRestricted.bottom;
}
if (DEBUG_LAYOUT) Slog.v(TAG, "Laying out IN_SCREEN status bar window: " + pf);
} else if (type == TYPE_NAVIGATION_BAR || type == TYPE_NAVIGATION_BAR_PANEL) {
// The navigation bar has Real Ultimate Power.
df.set(displayFrames.mUnrestricted);
pf.set(displayFrames.mUnrestricted);
if (DEBUG_LAYOUT) Slog.v(TAG, "Laying out navigation bar window: " + pf);
} else if ((type == TYPE_SECURE_SYSTEM_OVERLAY || type == TYPE_SCREENSHOT)
&& ((fl & FLAG_FULLSCREEN) != 0)) {
// Fullscreen secure system overlays get what they ask for. Screenshot region
// selection overlay should also expand to full screen.
cf.set(displayFrames.mUnrestricted);
df.set(displayFrames.mUnrestricted);
pf.set(displayFrames.mUnrestricted);
} else if (type == TYPE_BOOT_PROGRESS) {
// Boot progress screen always covers entire display.
cf.set(displayFrames.mUnrestricted);
df.set(displayFrames.mUnrestricted);
pf.set(displayFrames.mUnrestricted);
} else if ((sysUiFl & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
&& (type == TYPE_NOTIFICATION_SHADE
|| type == TYPE_TOAST
|| type == TYPE_DOCK_DIVIDER
|| type == TYPE_VOICE_INTERACTION_STARTING
|| (type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW))) {
// Asking for layout as if the nav bar is hidden, lets the
// application extend into the unrestricted screen area. We
// only do this for application windows (or toasts) to ensure no window that
// can be above the nav bar can do this.
// XXX This assumes that an app asking for this will also
// ask for layout in only content. We can't currently figure out
// what the screen would be if only laying out to hide the nav bar.
cf.set(displayFrames.mUnrestricted);
df.set(displayFrames.mUnrestricted);
pf.set(displayFrames.mUnrestricted);
} else if ((sysUiFl & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0) {
df.set(displayFrames.mRestricted);
pf.set(displayFrames.mRestricted);
// IME Insets are handled on the client for ADJUST_RESIZE in the new insets
// world
if (ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_NONE
|| adjust != SOFT_INPUT_ADJUST_RESIZE) {
cf.set(displayFrames.mDock);
} else {
cf.set(displayFrames.mContent);
}
} else {
cf.set(displayFrames.mRestricted);
df.set(displayFrames.mRestricted);
pf.set(displayFrames.mRestricted);
}
applyStableConstraints(sysUiFl, fl, cf, displayFrames);
if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE
&& adjust != SOFT_INPUT_ADJUST_NOTHING) {
vf.set(displayFrames.mCurrent);
} else {
vf.set(cf);
}
} else if (attached != null) {
if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle()
+ "): attached to " + attached);
// A child window should be placed inside of the same visible
// frame that its parent had.
setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, cf, vf,
displayFrames);
} else {
if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle()
+ "): normal window");
// Otherwise, a normal window must be placed inside the content
// of all screen decorations.
if (type == TYPE_STATUS_BAR_ADDITIONAL) {
// Status bar panels can go on
// top of the status bar. They are protected by the STATUS_BAR_SERVICE
// permission, so they have the same privileges as the status bar itself.
cf.set(displayFrames.mRestricted);
df.set(displayFrames.mRestricted);
pf.set(displayFrames.mRestricted);
} else if (type == TYPE_TOAST || type == TYPE_SYSTEM_ALERT) {
// These dialogs are stable to interim decor changes.
cf.set(displayFrames.mStable);
df.set(displayFrames.mStable);
pf.set(displayFrames.mStable);
} else {
pf.set(displayFrames.mContent);
if (win.isVoiceInteraction()) {
cf.set(displayFrames.mVoiceContent);
df.set(displayFrames.mVoiceContent);
} else if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
cf.set(displayFrames.mDock);
df.set(displayFrames.mDock);
} else {
cf.set(displayFrames.mContent);
df.set(displayFrames.mContent);
}
if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE
&& adjust != SOFT_INPUT_ADJUST_NOTHING) {
vf.set(displayFrames.mCurrent);
} else {
vf.set(cf);
}
}
}
dcf.setEmpty() 如何修改应用窗口大小
最新发布