diff options
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/app/ContextImpl.java | 5 | ||||
| -rw-r--r-- | core/java/android/view/IWindowManager.aidl | 47 | ||||
| -rw-r--r-- | core/java/android/window/WindowContext.java | 13 | ||||
| -rw-r--r-- | core/java/android/window/WindowContextController.java | 69 |
4 files changed, 102 insertions, 32 deletions
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index ec7d159f707b..f7ea3815d567 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -2641,9 +2641,8 @@ class ContextImpl extends Context { // 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(); + // Step 5. Associate the WindowContext's token to a DisplayArea. + windowContext.attachToDisplayArea(); return windowContext; } diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index d0a3e4b86e2d..0f032e906991 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -786,29 +786,60 @@ interface IWindowManager void setDisplayHashThrottlingEnabled(boolean enable); /** - * Registers a listener for a {@link android.window.WindowContext} to handle configuration - * changes from the server side. + * Attaches a {@link android.window.WindowContext} to the DisplayArea specified by {@code type}, + * {@code displayId} and {@code options}. * <p> * Note that this API should be invoked after calling * {@link android.window.WindowTokenClient#attachContext(Context)} - * </p> + * </p><p> + * Generally, this API is used for initializing a {@link android.window.WindowContext} + * before obtaining a valid {@link com.android.server.wm.WindowToken}. A WindowToken is usually + * generated when calling {@link android.view.WindowManager#addView(View, LayoutParams)}, or + * obtained from {@link android.view.WindowManager.LayoutParams#token}. + * </p><p> + * In some cases, the WindowToken is passed from the server side because it is managed by the + * system server. {@link #attachWindowContextToWindowToken(IBinder, IBinder)} could be used in + * this case to attach the WindowContext to the WindowToken.</p> * - * @param clientToken the window context's token + * @param clientToken {@link android.window.WindowContext#getWindowContextToken() + * the WindowContext's token} * @param type Window type of the window context * @param displayId The display associated with the window context * @param options A bundle used to pass window-related options and choose the right DisplayArea * - * @return {@code true} if the listener was registered successfully. + * @return {@code true} if the WindowContext is attached to the DisplayArea successfully. */ - boolean registerWindowContextListener(IBinder clientToken, int type, int displayId, + boolean attachWindowContextToDisplayArea(IBinder clientToken, int type, int displayId, in Bundle options); /** - * Unregisters a listener which registered with {@link #registerWindowContextListener()}. + * Attaches a {@link android.window.WindowContext} to a {@code WindowToken}. + * <p> + * This API is used when we hold a valid WindowToken and want to associate with the token and + * receive its configuration updates. + * </p><p> + * Note that this API should be invoked after calling + * {@link android.window.WindowTokenClient#attachContext(Context)} + * </p> + * + * @param clientToken {@link android.window.WindowContext#getWindowContextToken() + * the WindowContext's token} + * @param token the WindowToken to attach + * + * @throws IllegalArgumentException if the {@code clientToken} have not been attached to + * the server or the WindowContext's type doesn't match WindowToken {@code token}'s type. + * + * @see #attachWindowContextToDisplayArea(IBinder, int, int, Bundle) + */ + void attachWindowContextToWindowToken(IBinder clientToken, IBinder token); + + /** + * Detaches {@link android.window.WindowContext} from the window manager node it's currently + * attached to. It is no-op if the WindowContext is not attached to a window manager node. * * @param clientToken the window context's token */ - void unregisterWindowContextListener(IBinder clientToken); + void detachWindowContextFromWindowContainer(IBinder clientToken); /** * Registers a listener, which is to be called whenever cross-window blur is enabled/disabled. diff --git a/core/java/android/window/WindowContext.java b/core/java/android/window/WindowContext.java index 375f4cf63c3b..901625b0732c 100644 --- a/core/java/android/window/WindowContext.java +++ b/core/java/android/window/WindowContext.java @@ -57,6 +57,8 @@ public class WindowContext extends ContextWrapper { * * @param base Base {@link Context} for this new instance. * @param type Window type to be used with this context. + * @param options A bundle used to pass window-related options. + * * @hide */ public WindowContext(@NonNull Context base, int type, @Nullable Bundle options) { @@ -72,11 +74,12 @@ public class WindowContext extends ContextWrapper { } /** - * Registers this {@link WindowContext} with {@link com.android.server.wm.WindowManagerService} - * to receive configuration changes of the associated {@link WindowManager} node. + * Attaches this {@link WindowContext} to the {@link com.android.server.wm.DisplayArea} + * specified by {@code mType}, {@link #getDisplayId() display ID} and {@code mOptions} + * to receive configuration changes. */ - public void registerWithServer() { - mController.registerListener(mType, getDisplayId(), mOptions); + public void attachToDisplayArea() { + mController.attachToDisplayArea(mType, getDisplayId(), mOptions); } @Override @@ -96,7 +99,7 @@ public class WindowContext extends ContextWrapper { /** Used for test to invoke because we can't invoke finalize directly. */ @VisibleForTesting public void release() { - mController.unregisterListenerIfNeeded(); + mController.detachIfNeeded(); destroy(); } diff --git a/core/java/android/window/WindowContextController.java b/core/java/android/window/WindowContextController.java index 61434145290f..88584f4b2571 100644 --- a/core/java/android/window/WindowContextController.java +++ b/core/java/android/window/WindowContextController.java @@ -29,22 +29,29 @@ import android.view.WindowManagerGlobal; import com.android.internal.annotations.VisibleForTesting; /** - * The controller to manage {@link WindowContext} listener, such as registering and unregistering - * the listener. + * The controller to manage {@link WindowContext}, such as attaching to a window manager node or + * detaching from the current attached node. The user must call + * {@link #attachToDisplayArea(int, int, Bundle)}, call {@link #attachToWindowToken(IBinder)} + * after that if necessary, and then call {@link #detachIfNeeded()} for release. * * @hide */ public class WindowContextController { private final IWindowManager mWms; + /** + * {@code true} to indicate that the {@code mToken} is associated with a + * {@link com.android.server.wm.DisplayArea}. Note that {@code mToken} is able to attach a + * WindowToken after this flag sets to {@code true}. + */ @VisibleForTesting - public boolean mListenerRegistered; + public boolean mAttachedToDisplayArea; @NonNull private final IBinder mToken; /** * Window Context Controller constructor * - * @param token The token to register to the window context listener. It is usually from + * @param token The token used to attach to a window manager node. It is usually from * {@link Context#getWindowContextToken()}. */ public WindowContextController(@NonNull IBinder token) { @@ -60,19 +67,21 @@ public class WindowContextController { } /** - * Registers the {@code mToken} to the window context listener. + * Attaches the {@code mToken} to a {@link com.android.server.wm.DisplayArea}. * * @param type The window type of the {@link WindowContext} * @param displayId The {@link Context#getDisplayId() ID of display} to associate with * @param options The window context launched option + * @throws IllegalStateException if the {@code mToken} has already been attached to a + * DisplayArea. */ - public void registerListener(@WindowType int type, int displayId, @Nullable Bundle options) { - if (mListenerRegistered) { - throw new UnsupportedOperationException("A Window Context can only register a listener" - + " once."); + public void attachToDisplayArea(@WindowType int type, int displayId, @Nullable Bundle options) { + if (mAttachedToDisplayArea) { + throw new IllegalStateException("A Window Context can be only attached to " + + "a DisplayArea once."); } try { - mListenerRegistered = mWms.registerWindowContextListener(mToken, type, displayId, + mAttachedToDisplayArea = mWms.attachWindowContextToDisplayArea(mToken, type, displayId, options); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -80,14 +89,42 @@ public class WindowContextController { } /** - * Unregisters the window context listener associated with the {@code mToken} if it has been - * registered. + * Switches to attach the window context to a window token. + * <p> + * Note that the context should have been attached to a + * {@link com.android.server.wm.DisplayArea} by {@link #attachToDisplayArea(int, int, Bundle)} + * before attaching to a window token, and the window token's type must match the window + * context's type. + * </p><p> + * A {@link WindowContext} can only attach to a specific window manager node, which is either a + * {@link com.android.server.wm.DisplayArea} by calling + * {@link #attachToDisplayArea(int, int, Bundle)} or the latest attached {@code windowToken} + * although this API is allowed to be called multiple times. + * </p> + * @throws IllegalStateException if the {@code mClientToken} has not yet attached to + * a {@link com.android.server.wm.DisplayArea} by + * {@link #attachToDisplayArea(int, int, Bundle)}. + * + * @see IWindowManager#attachWindowContextToWindowToken(IBinder, IBinder) */ - public void unregisterListenerIfNeeded() { - if (mListenerRegistered) { + public void attachToWindowToken(IBinder windowToken) { + if (!mAttachedToDisplayArea) { + throw new IllegalStateException("The Window Context should have been attached" + + " to a DisplayArea."); + } + try { + mWms.attachWindowContextToWindowToken(mToken, windowToken); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** Detaches the window context from the node it's currently associated with. */ + public void detachIfNeeded() { + if (mAttachedToDisplayArea) { try { - mWms.unregisterWindowContextListener(mToken); - mListenerRegistered = false; + mWms.detachWindowContextFromWindowContainer(mToken); + mAttachedToDisplayArea = false; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } |
