Loading core/java/android/view/IWindowManager.aidl +12 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.os.Bundle; import android.os.IRemoteCallback; import android.os.ParcelFileDescriptor; import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.IApplicationToken; import android.view.IAppTransitionAnimationSpecsFuture; import android.view.ICrossWindowBlurEnabledListener; Loading Loading @@ -735,6 +736,17 @@ interface IWindowManager boolean getWindowInsets(in WindowManager.LayoutParams attrs, int displayId, out InsetsState outInsetsState); /** * Returns a list of {@link android.view.DisplayInfo} for the logical display. This is not * guaranteed to include all possible device states. The list items are unique. * * If invoked through a package other than a launcher app, returns an empty list. * * @param displayId the id of the logical display * @param packageName the name of the calling package */ List<DisplayInfo> getPossibleDisplayInfo(int displayId, String packageName); /** * Called to show global actions. */ Loading core/java/android/view/InsetsState.java +1 −1 Original line number Diff line number Diff line Loading @@ -202,7 +202,7 @@ public class InsetsState implements Parcelable { @Nullable @InternalInsetsSide SparseIntArray typeSideMap) { Insets[] typeInsetsMap = new Insets[Type.SIZE]; Insets[] typeMaxInsetsMap = new Insets[Type.SIZE]; boolean[] typeVisibilityMap = new boolean[SIZE]; boolean[] typeVisibilityMap = new boolean[Type.SIZE]; final Rect relativeFrame = new Rect(frame); final Rect relativeFrameMax = new Rect(frame); for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) { Loading core/java/android/view/WindowInsets.java +10 −0 Original line number Diff line number Diff line Loading @@ -903,6 +903,16 @@ public final class WindowInsets { result.append(mPrivacyIndicatorBounds != null ? "privacyIndicatorBounds=" + mPrivacyIndicatorBounds : ""); result.append("\n "); result.append("compatInsetsTypes=" + mCompatInsetsTypes); result.append("\n "); result.append("compatIgnoreVisibility=" + mCompatIgnoreVisibility); result.append("\n "); result.append("systemWindowInsetsConsumed=" + mSystemWindowInsetsConsumed); result.append("\n "); result.append("stableInsetsConsumed=" + mStableInsetsConsumed); result.append("\n "); result.append("displayCutoutConsumed=" + mDisplayCutoutConsumed); result.append("\n "); result.append(isRound() ? "round" : ""); result.append("}"); return result.toString(); Loading core/java/android/view/WindowManager.java +15 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; import java.util.function.Consumer; Loading Loading @@ -713,6 +714,20 @@ public interface WindowManager extends ViewManager { throw new UnsupportedOperationException(); } /** * Returns a set of {@link WindowMetrics} for the given display. Each WindowMetrics instance * is the maximum WindowMetrics for a device state, including rotations. This is not guaranteed * to include all possible device states. * * This API can only be used by Launcher. * * @param displayId the id of the logical display * @hide */ default @NonNull Set<WindowMetrics> getPossibleMaximumWindowMetrics(int displayId) { throw new UnsupportedOperationException(); } /** * Used to asynchronously request Keyboard Shortcuts from the focused window. * Loading core/java/android/view/WindowManagerImpl.java +70 −16 Original line number Diff line number Diff line Loading @@ -16,12 +16,9 @@ package android.view; import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.View.SYSTEM_UI_FLAG_VISIBLE; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; import static android.window.WindowProviderService.isWindowProviderService; Loading @@ -46,7 +43,9 @@ import android.window.WindowProvider; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.IResultReceiver; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.Executor; import java.util.function.Consumer; Loading Loading @@ -304,31 +303,86 @@ public final class WindowManagerImpl implements WindowManager { private WindowInsets computeWindowInsets(Rect bounds) { // Initialize params which used for obtaining all system insets. final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.flags = FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR; final Context context = (mParentWindow != null) ? mParentWindow.getContext() : mContext; params.token = Context.getToken(context); params.systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; params.setFitInsetsTypes(0); params.setFitInsetsSides(0); return getWindowInsetsFromServerForCurrentDisplay(params, bounds); } return getWindowInsetsFromServer(params, bounds); private WindowInsets getWindowInsetsFromServerForCurrentDisplay( WindowManager.LayoutParams attrs, Rect bounds) { final Configuration config = mContext.getResources().getConfiguration(); return getWindowInsetsFromServerForDisplay(mContext.getDisplayId(), attrs, bounds, config.isScreenRound(), config.windowConfiguration.getWindowingMode()); } private WindowInsets getWindowInsetsFromServer(WindowManager.LayoutParams attrs, Rect bounds) { /** * Retrieves WindowInsets for the given context and display, given the window bounds. * * @param displayId the ID of the logical display to calculate insets for * @param attrs the LayoutParams for the calling app * @param bounds the window bounds to calculate insets for * @param isScreenRound if the display identified by displayId is round * @param windowingMode the windowing mode of the window to calculate insets for * @return WindowInsets calculated for the given window bounds, on the given display */ private static WindowInsets getWindowInsetsFromServerForDisplay(int displayId, WindowManager.LayoutParams attrs, Rect bounds, boolean isScreenRound, int windowingMode) { try { final InsetsState insetsState = new InsetsState(); final boolean alwaysConsumeSystemBars = WindowManagerGlobal.getWindowManagerService() .getWindowInsets(attrs, mContext.getDisplayId(), insetsState); final Configuration config = mContext.getResources().getConfiguration(); final boolean isScreenRound = config.isScreenRound(); final int windowingMode = config.windowConfiguration.getWindowingMode(); .getWindowInsets(attrs, displayId, insetsState); return insetsState.calculateInsets(bounds, null /* ignoringVisibilityState*/, isScreenRound, alwaysConsumeSystemBars, SOFT_INPUT_ADJUST_NOTHING, attrs.flags, SYSTEM_UI_FLAG_VISIBLE, attrs.type, windowingMode, null /* typeSideMap */); SYSTEM_UI_FLAG_VISIBLE, attrs.type, windowingMode, null /* typeSideMap */); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } @Override @NonNull public Set<WindowMetrics> getPossibleMaximumWindowMetrics(int displayId) { List<DisplayInfo> possibleDisplayInfos; try { possibleDisplayInfos = WindowManagerGlobal.getWindowManagerService() .getPossibleDisplayInfo(displayId, mContext.getPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } int size = possibleDisplayInfos.size(); DisplayInfo currentDisplayInfo; WindowInsets windowInsets = null; if (size > 0) { currentDisplayInfo = possibleDisplayInfos.get(0); final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); final boolean isScreenRound = (currentDisplayInfo.flags & Display.FLAG_ROUND) != 0; // TODO(181127261) not computing insets correctly - need to have underlying // frame reflect the faked orientation. windowInsets = getWindowInsetsFromServerForDisplay( currentDisplayInfo.displayId, params, new Rect(0, 0, currentDisplayInfo.getNaturalWidth(), currentDisplayInfo.getNaturalHeight()), isScreenRound, WINDOWING_MODE_FULLSCREEN); } Set<WindowMetrics> maxMetrics = new HashSet<>(); for (int i = 0; i < size; i++) { currentDisplayInfo = possibleDisplayInfos.get(i); // Calculate max bounds for this rotation and state. Rect maxBounds = new Rect(0, 0, currentDisplayInfo.getNaturalWidth(), currentDisplayInfo.getNaturalHeight()); // Calculate insets for the rotated max bounds. // TODO(181127261) calculate insets for each display rotation and state. maxMetrics.add(new WindowMetrics(maxBounds, windowInsets)); } return maxMetrics; } @Override Loading Loading
core/java/android/view/IWindowManager.aidl +12 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.os.Bundle; import android.os.IRemoteCallback; import android.os.ParcelFileDescriptor; import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.IApplicationToken; import android.view.IAppTransitionAnimationSpecsFuture; import android.view.ICrossWindowBlurEnabledListener; Loading Loading @@ -735,6 +736,17 @@ interface IWindowManager boolean getWindowInsets(in WindowManager.LayoutParams attrs, int displayId, out InsetsState outInsetsState); /** * Returns a list of {@link android.view.DisplayInfo} for the logical display. This is not * guaranteed to include all possible device states. The list items are unique. * * If invoked through a package other than a launcher app, returns an empty list. * * @param displayId the id of the logical display * @param packageName the name of the calling package */ List<DisplayInfo> getPossibleDisplayInfo(int displayId, String packageName); /** * Called to show global actions. */ Loading
core/java/android/view/InsetsState.java +1 −1 Original line number Diff line number Diff line Loading @@ -202,7 +202,7 @@ public class InsetsState implements Parcelable { @Nullable @InternalInsetsSide SparseIntArray typeSideMap) { Insets[] typeInsetsMap = new Insets[Type.SIZE]; Insets[] typeMaxInsetsMap = new Insets[Type.SIZE]; boolean[] typeVisibilityMap = new boolean[SIZE]; boolean[] typeVisibilityMap = new boolean[Type.SIZE]; final Rect relativeFrame = new Rect(frame); final Rect relativeFrameMax = new Rect(frame); for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) { Loading
core/java/android/view/WindowInsets.java +10 −0 Original line number Diff line number Diff line Loading @@ -903,6 +903,16 @@ public final class WindowInsets { result.append(mPrivacyIndicatorBounds != null ? "privacyIndicatorBounds=" + mPrivacyIndicatorBounds : ""); result.append("\n "); result.append("compatInsetsTypes=" + mCompatInsetsTypes); result.append("\n "); result.append("compatIgnoreVisibility=" + mCompatIgnoreVisibility); result.append("\n "); result.append("systemWindowInsetsConsumed=" + mSystemWindowInsetsConsumed); result.append("\n "); result.append("stableInsetsConsumed=" + mStableInsetsConsumed); result.append("\n "); result.append("displayCutoutConsumed=" + mDisplayCutoutConsumed); result.append("\n "); result.append(isRound() ? "round" : ""); result.append("}"); return result.toString(); Loading
core/java/android/view/WindowManager.java +15 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; import java.util.function.Consumer; Loading Loading @@ -713,6 +714,20 @@ public interface WindowManager extends ViewManager { throw new UnsupportedOperationException(); } /** * Returns a set of {@link WindowMetrics} for the given display. Each WindowMetrics instance * is the maximum WindowMetrics for a device state, including rotations. This is not guaranteed * to include all possible device states. * * This API can only be used by Launcher. * * @param displayId the id of the logical display * @hide */ default @NonNull Set<WindowMetrics> getPossibleMaximumWindowMetrics(int displayId) { throw new UnsupportedOperationException(); } /** * Used to asynchronously request Keyboard Shortcuts from the focused window. * Loading
core/java/android/view/WindowManagerImpl.java +70 −16 Original line number Diff line number Diff line Loading @@ -16,12 +16,9 @@ package android.view; import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.View.SYSTEM_UI_FLAG_VISIBLE; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; import static android.window.WindowProviderService.isWindowProviderService; Loading @@ -46,7 +43,9 @@ import android.window.WindowProvider; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.IResultReceiver; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.Executor; import java.util.function.Consumer; Loading Loading @@ -304,31 +303,86 @@ public final class WindowManagerImpl implements WindowManager { private WindowInsets computeWindowInsets(Rect bounds) { // Initialize params which used for obtaining all system insets. final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.flags = FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR; final Context context = (mParentWindow != null) ? mParentWindow.getContext() : mContext; params.token = Context.getToken(context); params.systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; params.setFitInsetsTypes(0); params.setFitInsetsSides(0); return getWindowInsetsFromServerForCurrentDisplay(params, bounds); } return getWindowInsetsFromServer(params, bounds); private WindowInsets getWindowInsetsFromServerForCurrentDisplay( WindowManager.LayoutParams attrs, Rect bounds) { final Configuration config = mContext.getResources().getConfiguration(); return getWindowInsetsFromServerForDisplay(mContext.getDisplayId(), attrs, bounds, config.isScreenRound(), config.windowConfiguration.getWindowingMode()); } private WindowInsets getWindowInsetsFromServer(WindowManager.LayoutParams attrs, Rect bounds) { /** * Retrieves WindowInsets for the given context and display, given the window bounds. * * @param displayId the ID of the logical display to calculate insets for * @param attrs the LayoutParams for the calling app * @param bounds the window bounds to calculate insets for * @param isScreenRound if the display identified by displayId is round * @param windowingMode the windowing mode of the window to calculate insets for * @return WindowInsets calculated for the given window bounds, on the given display */ private static WindowInsets getWindowInsetsFromServerForDisplay(int displayId, WindowManager.LayoutParams attrs, Rect bounds, boolean isScreenRound, int windowingMode) { try { final InsetsState insetsState = new InsetsState(); final boolean alwaysConsumeSystemBars = WindowManagerGlobal.getWindowManagerService() .getWindowInsets(attrs, mContext.getDisplayId(), insetsState); final Configuration config = mContext.getResources().getConfiguration(); final boolean isScreenRound = config.isScreenRound(); final int windowingMode = config.windowConfiguration.getWindowingMode(); .getWindowInsets(attrs, displayId, insetsState); return insetsState.calculateInsets(bounds, null /* ignoringVisibilityState*/, isScreenRound, alwaysConsumeSystemBars, SOFT_INPUT_ADJUST_NOTHING, attrs.flags, SYSTEM_UI_FLAG_VISIBLE, attrs.type, windowingMode, null /* typeSideMap */); SYSTEM_UI_FLAG_VISIBLE, attrs.type, windowingMode, null /* typeSideMap */); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } @Override @NonNull public Set<WindowMetrics> getPossibleMaximumWindowMetrics(int displayId) { List<DisplayInfo> possibleDisplayInfos; try { possibleDisplayInfos = WindowManagerGlobal.getWindowManagerService() .getPossibleDisplayInfo(displayId, mContext.getPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } int size = possibleDisplayInfos.size(); DisplayInfo currentDisplayInfo; WindowInsets windowInsets = null; if (size > 0) { currentDisplayInfo = possibleDisplayInfos.get(0); final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); final boolean isScreenRound = (currentDisplayInfo.flags & Display.FLAG_ROUND) != 0; // TODO(181127261) not computing insets correctly - need to have underlying // frame reflect the faked orientation. windowInsets = getWindowInsetsFromServerForDisplay( currentDisplayInfo.displayId, params, new Rect(0, 0, currentDisplayInfo.getNaturalWidth(), currentDisplayInfo.getNaturalHeight()), isScreenRound, WINDOWING_MODE_FULLSCREEN); } Set<WindowMetrics> maxMetrics = new HashSet<>(); for (int i = 0; i < size; i++) { currentDisplayInfo = possibleDisplayInfos.get(i); // Calculate max bounds for this rotation and state. Rect maxBounds = new Rect(0, 0, currentDisplayInfo.getNaturalWidth(), currentDisplayInfo.getNaturalHeight()); // Calculate insets for the rotated max bounds. // TODO(181127261) calculate insets for each display rotation and state. maxMetrics.add(new WindowMetrics(maxBounds, windowInsets)); } return maxMetrics; } @Override Loading