Merge "Move WindowContext module to window package" into sc-dev

This commit is contained in:
Charles Chen
2021-03-24 07:45:41 +00:00
committed by Android (Google) Code Review
17 changed files with 197 additions and 113 deletions

View File

@@ -2328,7 +2328,7 @@ public final class ActivityThread extends ClientTransactionHandler
}
@UnsupportedAppUsage
final Handler getHandler() {
public Handler getHandler() {
return mH;
}

View File

@@ -19,10 +19,12 @@ package android.app;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.StrictMode.vmIncorrectContextUseEnabled;
import static android.view.WindowManager.LayoutParams.WindowType;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiContext;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.AutofillOptions;
import android.content.BroadcastReceiver;
@@ -87,6 +89,8 @@ import android.util.Slog;
import android.view.Display;
import android.view.DisplayAdjustments;
import android.view.autofill.AutofillManager.AutofillClient;
import android.window.WindowContext;
import android.window.WindowTokenClient;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
@@ -2563,23 +2567,63 @@ class ContextImpl extends Context {
@NonNull
@Override
public WindowContext createWindowContext(int type, @NonNull Bundle options) {
public WindowContext createWindowContext(@WindowType int type,
@Nullable Bundle options) {
if (getDisplay() == null) {
throw new UnsupportedOperationException("WindowContext can only be created from "
+ "other visual contexts, such as Activity or one created with "
+ "Context#createDisplayContext(Display)");
throw new UnsupportedOperationException("Please call this API with context associated"
+ " with a display instance, such as Activity or context created via"
+ " Context#createDisplayContext(Display), or try to invoke"
+ " Context#createWindowContext(Display, int, Bundle)");
}
return new WindowContext(this, type, options);
return createWindowContextInternal(getDisplay(), type, options);
}
@NonNull
@Override
public WindowContext createWindowContext(@NonNull Display display, int type,
@NonNull Bundle options) {
public WindowContext createWindowContext(@NonNull Display display, @WindowType int type,
@Nullable Bundle options) {
if (display == null) {
throw new IllegalArgumentException("Display must not be null");
}
return new WindowContext(this, display, type, options);
return createWindowContextInternal(display, type, options);
}
/**
* The internal implementation of {@link Context#createWindowContext(int, Bundle)} and
* {@link Context#createWindowContext(Display, int, Bundle)}.
*
* @param display The {@link Display} instance to be associated with.
*
* @see Context#createWindowContext(Display, int, Bundle)
* @see Context#createWindowContext(int, Bundle)
*/
private WindowContext createWindowContextInternal(@NonNull Display display,
@WindowType int type, @Nullable Bundle options) {
// Step 1. Create a WindowTokenClient to associate with the WindowContext's Resources
// instance and it will be later used to receive configuration updates from the
// server side.
final WindowTokenClient windowTokenClient = new WindowTokenClient();
// Step 2. Create the base context of the window context, it will also create a Resources
// associated with the WindowTokenClient and set the token to the base context.
final ContextImpl windowContextBase = createWindowContextBase(windowTokenClient, display);
// Step 3. Create a WindowContext instance and set it as the outer context of the base
// context to make the service obtained by #getSystemService(String) able to query
// the WindowContext's WindowManager instead of the default one.
final WindowContext windowContext = new WindowContext(windowContextBase, type, options);
windowContextBase.setOuterContext(windowContext);
// Step 4. Attach the WindowContext to the WindowTokenClient. In this way, when there's a
// configuration update from the server side, the update will then apply to
// WindowContext's resources.
windowTokenClient.attachContext(windowContext);
// Step 5. Register the window context's token to the server side to associate with a
// window manager node.
windowContext.registerWithServer();
return windowContext;
}
@NonNull
@@ -2588,40 +2632,65 @@ class ContextImpl extends Context {
if (display == null) {
throw new IllegalArgumentException("Display must not be null");
}
final ContextImpl tokenContext = createBaseWindowContext(token, display);
tokenContext.setResources(createWindowContextResources());
final ContextImpl tokenContext = createWindowContextBase(token, display);
tokenContext.setResources(createWindowContextResources(tokenContext));
return tokenContext;
}
ContextImpl createBaseWindowContext(IBinder token, Display display) {
ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
/**
* Creates the base {@link Context} for UI context to associate with a non-{@link Activity}
* window.
*
* @param token The token to associate with {@link Resources}
* @param display The {@link Display} to associate with.
*
* @see #createWindowContext(Display, int, Bundle)
* @see #createTokenContext(IBinder, Display)
*/
@UiContext
ContextImpl createWindowContextBase(@NonNull IBinder token, @NonNull Display display) {
ContextImpl baseContext = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
mSplitName, token, mUser, mFlags, mClassLoader, null);
// Window contexts receive configurations directly from the server and as such do not
// need to override their display in ResourcesManager.
context.mForceDisplayOverrideInResources = false;
context.mContextType = CONTEXT_TYPE_WINDOW_CONTEXT;
if (display != null) {
context.mDisplay = display;
}
return context;
baseContext.mForceDisplayOverrideInResources = false;
baseContext.mContextType = CONTEXT_TYPE_WINDOW_CONTEXT;
baseContext.mDisplay = display;
final Resources windowContextResources = createWindowContextResources(baseContext);
baseContext.setResources(windowContextResources);
return baseContext;
}
Resources createWindowContextResources() {
final String resDir = mPackageInfo.getResDir();
final String[] splitResDirs = mPackageInfo.getSplitResDirs();
final String[] legacyOverlayDirs = mPackageInfo.getOverlayDirs();
final String[] overlayPaths = mPackageInfo.getOverlayPaths();
final String[] libDirs = mPackageInfo.getApplicationInfo().sharedLibraryFiles;
final int displayId = getDisplayId();
final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
? mPackageInfo.getCompatibilityInfo()
: CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
final List<ResourcesLoader> loaders = mResources.getLoaders();
/**
* Creates the {@link Resources} to associate with the {@link WindowContext}'s token.
*
* When there's a {@link Configuration} update, this Resources instance will be updated to match
* the new configuration.
*
* @see WindowTokenClient
* @see #getWindowContextToken()
*/
private static Resources createWindowContextResources(@NonNull ContextImpl windowContextBase) {
final LoadedApk packageInfo = windowContextBase.mPackageInfo;
final ClassLoader classLoader = windowContextBase.mClassLoader;
final IBinder token = windowContextBase.getWindowContextToken();
return mResourcesManager.createBaseTokenResources(mToken, resDir, splitResDirs,
legacyOverlayDirs, overlayPaths, libDirs, displayId, null /* overrideConfig */,
compatInfo, mClassLoader, loaders);
final String resDir = packageInfo.getResDir();
final String[] splitResDirs = packageInfo.getSplitResDirs();
final String[] legacyOverlayDirs = packageInfo.getOverlayDirs();
final String[] overlayPaths = packageInfo.getOverlayPaths();
final String[] libDirs = packageInfo.getApplicationInfo().sharedLibraryFiles;
final int displayId = windowContextBase.getDisplayId();
final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
? packageInfo.getCompatibilityInfo()
: CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
final List<ResourcesLoader> loaders = windowContextBase.mResources.getLoaders();
return windowContextBase.mResourcesManager.createBaseTokenResources(token, resDir,
splitResDirs, legacyOverlayDirs, overlayPaths, libDirs, displayId,
null /* overrideConfig */, compatInfo, classLoader, loaders);
}
@NonNull
@@ -3114,6 +3183,14 @@ class ContextImpl extends Context {
return result;
}
@Override
public void destroy() {
// The final clean-up is to release BroadcastReceiver registrations. It is called in
// ActivityThread for Activity and Service. For the context, such as WindowContext,
// without lifecycle concept, it should be called once the context is released.
scheduleFinalCleanup(getClass().getName(), getOuterContext().getClass().getSimpleName());
}
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

View File

@@ -39,13 +39,13 @@ import android.os.IBinder;
import android.os.Process;
import android.os.Trace;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.view.Display;
import android.view.DisplayAdjustments;
import android.window.WindowContext;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
@@ -61,7 +61,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.WeakHashMap;
@@ -168,7 +167,7 @@ public class ResourcesManager {
/**
* Class containing the base configuration override and set of resources associated with an
* Activity or {@link WindowContext}.
* {@link Activity} or a {@link WindowContext}.
*/
private static class ActivityResources {
/**

View File

@@ -81,6 +81,7 @@ import android.view.WindowManager.LayoutParams.WindowType;
import android.view.autofill.AutofillManager.AutofillClient;
import android.view.contentcapture.ContentCaptureManager.ContentCaptureClient;
import android.view.textclassifier.TextClassificationManager;
import android.window.WindowContext;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.compat.IPlatformCompatNative;
@@ -6793,4 +6794,15 @@ public abstract class Context {
public boolean isUiContext() {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
/**
* Called when a {@link Context} is going to be released.
* This method can be overridden to perform the final cleanups, such as release
* {@link BroadcastReceiver} registrations.
*
* @see WindowContext#destroy()
*
* @hide
*/
public void destroy() { }
}

View File

@@ -777,11 +777,11 @@ interface IWindowManager
VerifiedDisplayHash verifyDisplayHash(in DisplayHash displayHash);
/**
* Registers a listener for a {@link android.app.WindowContext} to handle configuration changes
* from the server side.
* Registers a listener for a {@link android.window.WindowContext} to handle configuration
* changes from the server side.
* <p>
* Note that this API should be invoked after calling
* {@link android.app.WindowTokenClient#attachContext(WindowContext)}
* {@link android.window.WindowTokenClient#attachContext(Context)}
* </p>
*
* @param clientToken the window context's token

View File

@@ -2942,7 +2942,7 @@ public interface WindowManager extends ViewManager {
public IBinder token = null;
/**
* The token of {@link android.app.WindowContext}. It is usually a
* The token of {@link android.window.WindowContext}. It is usually a
* {@link android.app.WindowTokenClient} and is used for associating the params with an
* existing node in the WindowManager hierarchy and getting the corresponding
* {@link Configuration} and {@link android.content.res.Resources} values with updates

View File

@@ -36,6 +36,7 @@ import android.graphics.Region;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.window.WindowContext;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.IResultReceiver;
@@ -110,7 +111,7 @@ public final class WindowManagerImpl implements WindowManager {
return new WindowManagerImpl(displayContext, mParentWindow, mWindowContextToken);
}
/** Creates a {@link WindowManager} for a {@link android.app.WindowContext}. */
/** Creates a {@link WindowManager} for a {@link WindowContext}. */
public static WindowManager createWindowContextWindowManager(Context context) {
final IBinder clientToken = context.getWindowContextToken();
return new WindowManagerImpl(context, null /* parentWindow */, clientToken);

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app;
package android.window;
import static android.view.WindowManagerImpl.createWindowContextWindowManager;
@@ -28,7 +28,6 @@ import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.Display;
import android.view.IWindowManager;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
@@ -50,7 +49,9 @@ import java.lang.ref.Reference;
public class WindowContext extends ContextWrapper {
private final WindowManager mWindowManager;
private final IWindowManager mWms;
private final WindowTokenClient mToken;
private final @NonNull IBinder mToken;
private final @WindowManager.LayoutParams.WindowType int mType;
private final @Nullable Bundle mOptions;
private boolean mListenerRegistered;
private final ComponentCallbacksController mCallbacksController =
new ComponentCallbacksController();
@@ -64,47 +65,28 @@ public class WindowContext extends ContextWrapper {
* @hide
*/
public WindowContext(@NonNull Context base, int type, @Nullable Bundle options) {
this(base, null /* display */, type, options);
}
/**
* Default constructor. Will generate a {@link WindowTokenClient} and attach this context to
* the token.
*
* @param base Base {@link Context} for this new instance.
* @param display the {@link Display} to override.
* @param type Window type to be used with this context.
* @hide
*/
public WindowContext(@NonNull Context base, @Nullable Display display, int type,
@Nullable Bundle options) {
// Correct base context will be built once the token is resolved, so passing 'null' here.
super(null /* base */);
super(base);
mType = type;
mOptions = options;
mWms = WindowManagerGlobal.getWindowManagerService();
mToken = new WindowTokenClient();
final ContextImpl contextImpl = createBaseWindowContext(base, mToken, display);
attachBaseContext(contextImpl);
contextImpl.setOuterContext(this);
mToken.attachContext(this);
mToken = getWindowContextToken();
mWindowManager = createWindowContextWindowManager(this);
try {
mListenerRegistered = mWms.registerWindowContextListener(mToken, type, getDisplayId(),
options);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
Reference.reachabilityFence(this);
}
private static ContextImpl createBaseWindowContext(Context outer, IBinder token,
Display display) {
final ContextImpl contextImpl = ContextImpl.getImpl(outer);
return contextImpl.createBaseWindowContext(token, display);
/**
* Registers this {@link WindowContext} with {@link com.android.server.wm.WindowManagerService}
* to receive configuration changes of the associated {@link WindowManager} node.
*/
public void registerWithServer() {
try {
mListenerRegistered = mWms.registerWindowContextListener(mToken, mType, getDisplayId(),
mOptions);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@Override
@@ -135,10 +117,11 @@ public class WindowContext extends ContextWrapper {
destroy();
}
void destroy() {
@Override
public void destroy() {
mCallbacksController.clearCallbacks();
final ContextImpl impl = (ContextImpl) getBaseContext();
impl.scheduleFinalCleanup(getClass().getName(), "WindowContext");
// Called to the base ContextImpl to do final clean-up.
getBaseContext().destroy();
Reference.reachabilityFence(this);
}

View File

@@ -13,9 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app;
package android.window;
import android.annotation.NonNull;
import android.app.ActivityThread;
import android.app.IWindowToken;
import android.app.ResourcesManager;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
@@ -25,18 +28,22 @@ import android.view.WindowManagerGlobal;
import java.lang.ref.WeakReference;
/**
* Client implementation of {@link IWindowToken}. It can receive configuration change callbacks from
* server when window token config is updated or when it is moved between displays, and update the
* resources associated with this token on the client side. This will make sure that
* {@link WindowContext} instances will have updated resources and configuration.
* This class is used to receive {@link Configuration} changes from the associated window manager
* node on the server side, and apply the change to the {@link Context#getResources() associated
* Resources} of the attached {@link Context}. It is also used as
* {@link Context#getWindowContextToken() the token of non-Activity UI Contexts}.
*
* @see WindowContext
* @see android.view.IWindowManager#registerWindowContextListener(IBinder, int, int, Bundle)
*
* @hide
*/
public class WindowTokenClient extends IWindowToken.Stub {
/**
* Attached {@link Context} for this window token to update configuration and resources.
* Initialized by {@link #attachContext(WindowContext)}.
* Initialized by {@link #attachContext(Context)}.
*/
private WeakReference<WindowContext> mContextRef = null;
private WeakReference<Context> mContextRef = null;
private final ResourcesManager mResourcesManager = ResourcesManager.getInstance();
@@ -50,18 +57,16 @@ public class WindowTokenClient extends IWindowToken.Stub {
* @param context context to be attached
* @throws IllegalStateException if attached context has already existed.
*/
void attachContext(@NonNull WindowContext context) {
public void attachContext(@NonNull Context context) {
if (mContextRef != null) {
throw new IllegalStateException("Context is already attached.");
}
mContextRef = new WeakReference<>(context);
final ContextImpl impl = ContextImpl.getImpl(context);
impl.setResources(impl.createWindowContextResources());
}
@Override
public void onConfigurationChanged(Configuration newConfig, int newDisplayId) {
final WindowContext context = mContextRef.get();
final Context context = mContextRef.get();
if (context == null) {
return;
}
@@ -72,8 +77,10 @@ public class WindowTokenClient extends IWindowToken.Stub {
if (displayChanged || configChanged) {
// TODO(ag/9789103): update resource manager logic to track non-activity tokens
mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId);
ActivityThread.currentActivityThread().getHandler().post(
() -> context.dispatchConfigurationChanged(newConfig));
if (context instanceof WindowContext) {
ActivityThread.currentActivityThread().getHandler().post(
() -> ((WindowContext) context).dispatchConfigurationChanged(newConfig));
}
}
if (displayChanged) {
context.updateDisplay(newDisplayId);
@@ -82,7 +89,7 @@ public class WindowTokenClient extends IWindowToken.Stub {
@Override
public void onWindowTokenRemoved() {
final WindowContext context = mContextRef.get();
final Context context = mContextRef.get();
if (context != null) {
context.destroy();
mContextRef.clear();

View File

@@ -73,17 +73,17 @@ public class WindowMetricsTest {
// Check get metrics do not crash.
WindowMetrics currentMetrics = mWm.getCurrentWindowMetrics();
WindowMetrics maxMetrics = mWm.getMaximumWindowMetrics();
verifyMetricsSanity(currentMetrics, maxMetrics);
verifyMetricsValidity(currentMetrics, maxMetrics);
mWm.removeViewImmediate(view);
// Check get metrics do not crash.
currentMetrics = mWm.getCurrentWindowMetrics();
maxMetrics = mWm.getMaximumWindowMetrics();
verifyMetricsSanity(currentMetrics, maxMetrics);
verifyMetricsValidity(currentMetrics, maxMetrics);
}, 0);
}
private static void verifyMetricsSanity(WindowMetrics currentMetrics,
private static void verifyMetricsValidity(WindowMetrics currentMetrics,
WindowMetrics maxMetrics) {
Rect currentBounds = currentMetrics.getBounds();
Rect maxBounds = maxMetrics.getBounds();

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package android.app;
package android.window;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -24,6 +24,9 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.app.Activity;
import android.app.EmptyActivity;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.hardware.display.DisplayManager;
@@ -142,8 +145,8 @@ public class WindowContextTest {
* {@link WindowManager.LayoutParams#token}.
*
* The window context token should be overridden to
* {@link android.view.WindowManager.LayoutParams} and the {@link Activity}'s token must
* not be removed regardless of the release of window context.
* {@link android.view.WindowManager.LayoutParams} and the {@link Activity}'s token must not be
* removed regardless of release of window context.
*/
@Test
public void testCreateWindowContext_AttachActivity_TokenNotRemovedAfterRelease()

View File

@@ -38,7 +38,6 @@ import android.app.ActivityOptions;
import android.app.ExitTransitionCoordinator;
import android.app.ExitTransitionCoordinator.ExitTransitionCallbacks;
import android.app.Notification;
import android.app.WindowContext;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -74,6 +73,7 @@ import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
import android.window.WindowContext;
import com.android.internal.app.ChooserActivity;
import com.android.internal.logging.UiEventLogger;

View File

@@ -33,6 +33,7 @@ import android.os.RemoteException;
import android.util.ArrayMap;
import android.view.View;
import android.view.WindowManager.LayoutParams.WindowType;
import android.window.WindowContext;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
@@ -40,22 +41,21 @@ import com.android.internal.protolog.common.ProtoLog;
import java.util.Objects;
/**
* A controller to register/unregister {@link WindowContainerListener} for
* {@link android.app.WindowContext}.
* A controller to register/unregister {@link WindowContainerListener} for {@link WindowContext}.
*
* <ul>
* <li>When a {@link android.app.WindowContext} is created, it registers the listener via
* <li>When a {@link WindowContext} is created, it registers the listener via
* {@link WindowManagerService#registerWindowContextListener(IBinder, int, int, Bundle)}
* automatically.</li>
* <li>When the {@link android.app.WindowContext} adds the first window to the screen via
* <li>When the {@link WindowContext} adds the first window to the screen via
* {@link android.view.WindowManager#addView(View, android.view.ViewGroup.LayoutParams)},
* {@link WindowManagerService} then updates the {@link WindowContextListenerImpl} to listen
* to corresponding {@link WindowToken} via this controller.</li>
* <li>When the {@link android.app.WindowContext} is GCed, it unregisters the previously
* <li>When the {@link WindowContext} is GCed, it unregisters the previously
* registered listener via
* {@link WindowManagerService#unregisterWindowContextListener(IBinder)}.
* {@link WindowManagerService} is also responsible for removing the
* {@link android.app.WindowContext} created {@link WindowToken}.</li>
* {@link WindowContext} created {@link WindowToken}.</li>
* </ul>
* <p>Note that the listener may be removed earlier than the
* {@link #unregisterWindowContainerListener(IBinder)} if the listened {@link WindowContainer} was

View File

@@ -2708,7 +2708,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
/**
* Registers a listener for a {@link android.app.WindowContext} to subscribe to configuration
* Registers a listener for a {@link android.window.WindowContext} to subscribe to configuration
* changes of a {@link DisplayArea}.
*
* @param clientToken the window context's token

View File

@@ -54,6 +54,7 @@ import android.view.DisplayInfo;
import android.view.InsetsState;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.WindowContext;
import com.android.internal.protolog.common.ProtoLog;
import com.android.server.policy.WindowManagerPolicy;
@@ -109,7 +110,7 @@ class WindowToken extends WindowContainer<WindowState> {
private FixedRotationTransformState mFixedRotationTransformState;
/**
* When set to {@code true}, this window token is created from {@link android.app.WindowContext}
* When set to {@code true}, this window token is created from {@link WindowContext}
*/
private final boolean mFromClientToken;

View File

@@ -38,6 +38,7 @@ import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
import android.window.WindowContext;
import androidx.test.filters.SmallTest;
@@ -208,7 +209,7 @@ public class WindowTokenTests extends WindowTestsBase {
/**
* Test that {@link android.view.SurfaceControl} should not be created for the
* {@link WindowToken} which was created for {@link android.app.WindowContext} initially, the
* {@link WindowToken} which was created for {@link WindowContext} initially, the
* surface should be create after addWindow for this token.
*/
@Test

View File

@@ -59,7 +59,7 @@ public final class FrameworksTestsFilter extends SelectTest {
"android.view.RoundedCornersTest",
"android.view.WindowMetricsTest",
"android.view.PendingInsetsControllerTest",
"android.app.WindowContextTest",
"android.window.WindowContextTest",
"android.window.WindowMetricsHelperTest",
"android.app.activity.ActivityThreadTest"
};