Introduce WindowMetrics and WM#getCurrent/MaximumWindowMetrics
Bug: 128338354 Bug: 146820733 Test: atest WindowMetricsTests Change-Id: I328b1b5a2296e470072a439e412276c1b6008789
This commit is contained in:
committed by
Andrii Kulian
parent
4a31697319
commit
f65e022caa
@@ -54148,7 +54148,9 @@ package android.view {
|
||||
}
|
||||
|
||||
public interface WindowManager extends android.view.ViewManager {
|
||||
method @NonNull public default android.view.WindowMetrics getCurrentWindowMetrics();
|
||||
method @Deprecated public android.view.Display getDefaultDisplay();
|
||||
method @NonNull public default android.view.WindowMetrics getMaximumWindowMetrics();
|
||||
method public void removeViewImmediate(android.view.View);
|
||||
}
|
||||
|
||||
@@ -54311,6 +54313,12 @@ package android.view {
|
||||
field @android.view.ViewDebug.ExportedProperty public int y;
|
||||
}
|
||||
|
||||
public final class WindowMetrics {
|
||||
ctor public WindowMetrics(@NonNull android.util.Size, @NonNull android.view.WindowInsets);
|
||||
method @NonNull public android.util.Size getSize();
|
||||
method @NonNull public android.view.WindowInsets getWindowInsets();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.view.accessibility {
|
||||
|
||||
@@ -32,6 +32,7 @@ import android.graphics.Region;
|
||||
import android.os.Bundle;
|
||||
import android.os.IRemoteCallback;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.view.DisplayCutout;
|
||||
import android.view.IApplicationToken;
|
||||
import android.view.IAppTransitionAnimationSpecsFuture;
|
||||
import android.view.IDockedStackListener;
|
||||
@@ -739,4 +740,12 @@ interface IWindowManager
|
||||
* Called when a remote process modifies insets on a display window container.
|
||||
*/
|
||||
void modifyDisplayWindowInsets(int displayId, in InsetsState state);
|
||||
|
||||
/**
|
||||
* Called to get the expected window insets.
|
||||
* TODO(window-context): Remove when new insets flag is available.
|
||||
*/
|
||||
void getWindowInsets(in WindowManager.LayoutParams attrs, int displayId,
|
||||
out Rect outContentInsets, out Rect outStableInsets,
|
||||
out DisplayCutout.ParcelableWrapper displayCutout);
|
||||
}
|
||||
|
||||
@@ -436,6 +436,49 @@ public interface WindowManager extends ViewManager {
|
||||
*/
|
||||
public void removeViewImmediate(View view);
|
||||
|
||||
/**
|
||||
* Returns the {@link WindowMetrics} according to the current system state.
|
||||
* <p>
|
||||
* The metrics describe the size of the area the window would occupy with
|
||||
* {@link LayoutParams#MATCH_PARENT MATCH_PARENT} width and height, and the {@link WindowInsets}
|
||||
* such a window would have.
|
||||
* <p>
|
||||
* The value of this is based on the <b>current</b> windowing state of the system.
|
||||
*
|
||||
* For example, for activities in multi-window mode, the metrics returned are based on the
|
||||
* current bounds that the user has selected for the {@link android.app.Activity Activity}'s
|
||||
* task.
|
||||
*
|
||||
* @see #getMaximumWindowMetrics()
|
||||
* @see WindowMetrics
|
||||
*/
|
||||
default @NonNull WindowMetrics getCurrentWindowMetrics() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the largets {@link WindowMetrics} an app may expect in the current system state.
|
||||
* <p>
|
||||
* The metrics describe the size of the largest potential area the window might occupy with
|
||||
* {@link LayoutParams#MATCH_PARENT MATCH_PARENT} width and height, and the {@link WindowInsets}
|
||||
* such a window would have.
|
||||
* <p>
|
||||
* The value of this is based on the largest <b>potential</b> windowing state of the system.
|
||||
*
|
||||
* For example, for activities in multi-window mode, the metrics returned are based on the
|
||||
* what the bounds would be if the user expanded the {@link android.app.Activity Activity}'s
|
||||
* task to cover the entire screen.
|
||||
*
|
||||
* Note that this might still be smaller than the size of the physical display if certain areas
|
||||
* of the display are not available to windows created in this {@link Context}.
|
||||
*
|
||||
* @see #getMaximumWindowMetrics()
|
||||
* @see WindowMetrics
|
||||
*/
|
||||
default @NonNull WindowMetrics getMaximumWindowMetrics() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to asynchronously request Keyboard Shortcuts from the focused window.
|
||||
*
|
||||
|
||||
@@ -17,12 +17,17 @@
|
||||
package android.view;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ResourcesManager;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Size;
|
||||
|
||||
import com.android.internal.os.IResultReceiver;
|
||||
|
||||
@@ -62,6 +67,10 @@ public final class WindowManagerImpl implements WindowManager {
|
||||
|
||||
private IBinder mDefaultToken;
|
||||
|
||||
private boolean mIsViewAdded;
|
||||
private View mLastView;
|
||||
private WindowManager.LayoutParams mLastParams;
|
||||
|
||||
public WindowManagerImpl(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -93,6 +102,9 @@ public final class WindowManagerImpl implements WindowManager {
|
||||
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
|
||||
applyDefaultToken(params);
|
||||
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
|
||||
mIsViewAdded = true;
|
||||
mLastView = view;
|
||||
mLastParams = (WindowManager.LayoutParams) params;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -201,4 +213,71 @@ public final class WindowManagerImpl implements WindowManager {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindowMetrics getCurrentWindowMetrics() {
|
||||
final Context context = mParentWindow != null ? mParentWindow.getContext() : mContext;
|
||||
final Rect bound = getCurrentBounds(context);
|
||||
|
||||
return new WindowMetrics(toSize(bound), computeWindowInsets());
|
||||
}
|
||||
|
||||
private static Rect getCurrentBounds(Context context) {
|
||||
synchronized (ResourcesManager.getInstance()) {
|
||||
return context.getResources().getConfiguration().windowConfiguration.getBounds();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindowMetrics getMaximumWindowMetrics() {
|
||||
return new WindowMetrics(toSize(getMaximumBounds()), computeWindowInsets());
|
||||
}
|
||||
|
||||
private Size toSize(Rect frame) {
|
||||
return new Size(frame.width(), frame.height());
|
||||
}
|
||||
|
||||
private Rect getMaximumBounds() {
|
||||
// TODO(b/128338354): Current maximum bound is display size, but it should be displayArea
|
||||
// bound after displayArea feature is finished.
|
||||
final Display display = mContext.getDisplay();
|
||||
final Point displaySize = new Point();
|
||||
display.getRealSize(displaySize);
|
||||
return new Rect(0, 0, displaySize.x, displaySize.y);
|
||||
}
|
||||
|
||||
private WindowInsets computeWindowInsets() {
|
||||
// TODO(window-context): This can only be properly implemented
|
||||
// once we flip the new insets mode flag.
|
||||
if (mParentWindow != null) {
|
||||
if (mParentWindow.getDecorView().isAttachedToWindow()) {
|
||||
return mParentWindow.getDecorView().getViewRootImpl()
|
||||
.getWindowInsets(true /* forceConstruct */);
|
||||
}
|
||||
return getWindowInsetsFromServer(mParentWindow.getAttributes());
|
||||
}
|
||||
if (mIsViewAdded) {
|
||||
return mLastView.getViewRootImpl().getWindowInsets(true /* forceConstruct */);
|
||||
} else {
|
||||
return getWindowInsetsFromServer(new WindowManager.LayoutParams());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private WindowInsets getWindowInsetsFromServer(WindowManager.LayoutParams attrs) {
|
||||
try {
|
||||
final Rect systemWindowInsets = new Rect();
|
||||
final Rect stableInsets = new Rect();
|
||||
final DisplayCutout.ParcelableWrapper displayCutout =
|
||||
new DisplayCutout.ParcelableWrapper();
|
||||
WindowManagerGlobal.getWindowManagerService().getWindowInsets(attrs,
|
||||
mContext.getDisplayId(), systemWindowInsets, stableInsets, displayCutout);
|
||||
return new WindowInsets.Builder()
|
||||
.setSystemWindowInsets(Insets.of(systemWindowInsets))
|
||||
.setStableInsets(Insets.of(stableInsets))
|
||||
.setDisplayCutout(displayCutout.get()).build();
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
58
core/java/android/view/WindowMetrics.java
Normal file
58
core/java/android/view/WindowMetrics.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.view;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.util.Size;
|
||||
|
||||
/**
|
||||
* Metrics about a Window, consisting of the size and {@link WindowInsets}.
|
||||
* <p>
|
||||
* This is usually obtained from {@link WindowManager#getCurrentWindowMetrics()} and
|
||||
* {@link WindowManager#getMaximumWindowMetrics()}.
|
||||
*
|
||||
* @see WindowInsets#getInsets(int)
|
||||
* @see WindowManager#getCurrentWindowMetrics()
|
||||
* @see WindowManager#getMaximumWindowMetrics()
|
||||
*/
|
||||
public final class WindowMetrics {
|
||||
private final @NonNull Size mSize;
|
||||
private final @NonNull WindowInsets mWindowInsets;
|
||||
|
||||
public WindowMetrics(@NonNull Size size, @NonNull WindowInsets windowInsets) {
|
||||
mSize = size;
|
||||
mWindowInsets = windowInsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the window.
|
||||
*
|
||||
* @return window size in pixel.
|
||||
*/
|
||||
public @NonNull Size getSize() {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link WindowInsets} of the window.
|
||||
*
|
||||
* @return the {@link WindowInsets} of the window.
|
||||
*/
|
||||
public @NonNull WindowInsets getWindowInsets() {
|
||||
return mWindowInsets;
|
||||
}
|
||||
}
|
||||
@@ -7927,4 +7927,33 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
return mDisplayWindowSettings.shouldShowImeLocked(displayContent)
|
||||
|| mForceDesktopModeOnExternalDisplays;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getWindowInsets(WindowManager.LayoutParams attrs,
|
||||
int displayId, Rect outContentInsets, Rect outStableInsets,
|
||||
DisplayCutout.ParcelableWrapper displayCutout) {
|
||||
synchronized (mGlobalLock) {
|
||||
final DisplayContent dc = mRoot.getDisplayContent(displayId);
|
||||
final WindowToken windowToken = dc.getWindowToken(attrs.token);
|
||||
final ActivityRecord activity;
|
||||
if (windowToken != null && windowToken.asActivityRecord() != null) {
|
||||
activity = windowToken.asActivityRecord();
|
||||
} else {
|
||||
activity = null;
|
||||
}
|
||||
final Rect taskBounds = new Rect();
|
||||
final boolean floatingStack;
|
||||
if (activity != null && activity.getTask() != null) {
|
||||
final Task task = activity.getTask();
|
||||
task.getBounds(taskBounds);
|
||||
floatingStack = task.isFloating();
|
||||
} else {
|
||||
floatingStack = false;
|
||||
}
|
||||
final DisplayFrames displayFrames = dc.mDisplayFrames;
|
||||
final DisplayPolicy policy = dc.getDisplayPolicy();
|
||||
policy.getLayoutHintLw(attrs, taskBounds, displayFrames, floatingStack,
|
||||
new Rect(), outContentInsets, outStableInsets, displayCutout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user