diff options
author | Charles Chen <charlesccchen@google.com> | 2020-12-22 09:44:53 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-12-22 09:44:53 +0000 |
commit | 465c67dfd52077d3e8cd93e007cd8c7c178985c7 (patch) | |
tree | 540988aa2251d64a09445806f3894e01d1db9477 | |
parent | bdfa53714d15132da684aac81db2e0c7a2823561 (diff) | |
parent | b63b92922ba80f7bce086f11bff2f103da9e7b38 (diff) |
Merge "Introduce #createWindowContext with display"
-rw-r--r-- | core/api/current.txt | 1 | ||||
-rw-r--r-- | core/java/android/app/ContextImpl.java | 18 | ||||
-rw-r--r-- | core/java/android/app/WindowContext.java | 22 | ||||
-rw-r--r-- | core/java/android/content/Context.java | 40 | ||||
-rw-r--r-- | core/java/android/content/ContextWrapper.java | 7 | ||||
-rw-r--r-- | test-mock/src/android/test/mock/MockContext.java | 5 |
6 files changed, 81 insertions, 12 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 016f9eed5c5d..2cde77e6914a 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -10134,6 +10134,7 @@ package android.content { method public abstract android.content.Context createDisplayContext(@NonNull android.view.Display); method public abstract android.content.Context createPackageContext(String, int) throws android.content.pm.PackageManager.NameNotFoundException; method @NonNull public android.content.Context createWindowContext(int, @Nullable android.os.Bundle); + method @NonNull public android.content.Context createWindowContext(@NonNull android.view.Display, int, @Nullable android.os.Bundle); method public abstract String[] databaseList(); method public abstract boolean deleteDatabase(String); method public abstract boolean deleteFile(String); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 124cf71edc9c..700d8ff36446 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -2468,8 +2468,9 @@ class ContextImpl extends Context { return context; } + @NonNull @Override - public @NonNull WindowContext createWindowContext(int type, Bundle options) { + public WindowContext createWindowContext(int type, @NonNull Bundle options) { if (getDisplay() == null) { throw new UnsupportedOperationException("WindowContext can only be created from " + "other visual contexts, such as Activity or one created with " @@ -2478,13 +2479,26 @@ class ContextImpl extends Context { return new WindowContext(this, type, options); } - ContextImpl createBaseWindowContext(IBinder token) { + @NonNull + @Override + public WindowContext createWindowContext(@NonNull Display display, int type, + @NonNull Bundle options) { + if (display == null) { + throw new IllegalArgumentException("Display must not be null"); + } + return new WindowContext(this, display, type, options); + } + + ContextImpl createBaseWindowContext(IBinder token, Display display) { ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag, 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; } diff --git a/core/java/android/app/WindowContext.java b/core/java/android/app/WindowContext.java index 5f72bac89d7b..14ed414da9d0 100644 --- a/core/java/android/app/WindowContext.java +++ b/core/java/android/app/WindowContext.java @@ -26,6 +26,7 @@ import android.content.ContextWrapper; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; +import android.view.Display; import android.view.IWindowManager; import android.view.WindowManagerGlobal; import android.view.WindowManagerImpl; @@ -59,13 +60,27 @@ 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 */); mWms = WindowManagerGlobal.getWindowManagerService(); mToken = new WindowTokenClient(); - final ContextImpl contextImpl = createBaseWindowContext(base, mToken); + final ContextImpl contextImpl = createBaseWindowContext(base, mToken, display); attachBaseContext(contextImpl); contextImpl.setOuterContext(this); @@ -93,9 +108,10 @@ public class WindowContext extends ContextWrapper { Reference.reachabilityFence(this); } - private static ContextImpl createBaseWindowContext(Context outer, IBinder token) { + private static ContextImpl createBaseWindowContext(Context outer, IBinder token, + Display display) { final ContextImpl contextImpl = ContextImpl.getImpl(outer); - return contextImpl.createBaseWindowContext(token); + return contextImpl.createBaseWindowContext(token, display); } @Override diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index ac576a80b5d2..abe7fdae0bf7 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -5989,22 +5989,22 @@ public abstract class Context { * Creating a window context is an expensive operation. Misuse of this API may lead to a huge * performance drop. The best practice is to use the same window context when possible. * An approach is to create one window context with specific window type and display and - * use it everywhere it's needed.. + * use it everywhere it's needed. * </p> * * @param type Window type in {@link WindowManager.LayoutParams} - * @param options Bundle used to pass window-related options. - * @return A {@link Context} that can be used to create windows. - * @throws UnsupportedOperationException if this is called on a non-UI context, such as - * {@link android.app.Application Application} or {@link android.app.Service Service}. + * @param options A bundle used to pass window-related options + * @return A {@link Context} that can be used to create + * non-{@link android.app.Activity activity} windows. * * @see #getSystemService(String) * @see #getSystemService(Class) * @see #WINDOW_SERVICE * @see #LAYOUT_INFLATER_SERVICE * @see #WALLPAPER_SERVICE - * @throws UnsupportedOperationException if this {@link Context} does not attach to a display or - * the current number of window contexts without adding any view by + * @throws UnsupportedOperationException if this {@link Context} does not attach to a display, + * such as {@link android.app.Application Application} or {@link android.app.Service Service}, + * or the current number of window contexts without adding any view by * {@link WindowManager#addView} <b>exceeds five</b>. */ @UiContext @@ -6014,6 +6014,32 @@ public abstract class Context { } /** + * A special version of {@link #createWindowContext(int, Bundle)} which also takes + * {@link Display}. The only difference between this API and + * {@link #createWindowContext(int, Bundle)} is that this API can create window context from + * any context even if the context which is not associated to a {@link Display} instance. + * + * @param display The {@link Display} to associate with + * @param type Window type in {@link WindowManager.LayoutParams} + * @param options A bundle used to pass window-related options. + * @return A {@link Context} that can be used to create + * non-{@link android.app.Activity activity} windows. + * @throws IllegalArgumentException if the {@link Display} is {@code null}. + * + * @see #getSystemService(String) + * @see #getSystemService(Class) + * @see #WINDOW_SERVICE + * @see #LAYOUT_INFLATER_SERVICE + * @see #WALLPAPER_SERVICE + */ + @UiContext + @NonNull + public Context createWindowContext(@NonNull Display display, @WindowType int type, + @Nullable Bundle options) { + throw new RuntimeException("Not implemented. Must override in a subclass."); + } + + /** * Return a new Context object for the current Context but attribute to a different tag. * In complex apps attribution tagging can be used to distinguish between separate logical * parts. diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 56da3cb0eb02..e450c08de280 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -988,6 +988,13 @@ public class ContextWrapper extends Context { } @Override + @NonNull + public Context createWindowContext(@NonNull Display display, @WindowType int type, + @Nullable Bundle options) { + return mBase.createWindowContext(display, type, options); + } + + @Override public @NonNull Context createAttributionContext(@Nullable String attributionTag) { return mBase.createAttributionContext(attributionTag); } diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java index cf3b03cae72e..f7cebd12fcff 100644 --- a/test-mock/src/android/test/mock/MockContext.java +++ b/test-mock/src/android/test/mock/MockContext.java @@ -817,6 +817,11 @@ public class MockContext extends Context { } @Override + public @NonNull Context createWindowContext(Display display, int type, Bundle options) { + throw new UnsupportedOperationException(); + } + + @Override public boolean isRestricted() { throw new UnsupportedOperationException(); } |