1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.window; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.content.Context; 22 import android.os.Bundle; 23 import android.os.IBinder; 24 import android.view.IWindowManager; 25 import android.view.WindowManager.LayoutParams.WindowType; 26 27 import com.android.internal.annotations.VisibleForTesting; 28 29 /** 30 * The controller to manage {@link WindowContext}, such as attaching to a window manager node or 31 * detaching from the current attached node. The user must call 32 * {@link #attachToDisplayArea(int, int, Bundle)}, call {@link #attachToWindowToken(IBinder)} 33 * after that if necessary, and then call {@link #detachIfNeeded()} for release. 34 * 35 * @hide 36 */ 37 public class WindowContextController { 38 /** 39 * {@code true} to indicate that the {@code mToken} is associated with a 40 * {@link com.android.server.wm.DisplayArea}. Note that {@code mToken} is able to attach a 41 * WindowToken after this flag sets to {@code true}. 42 */ 43 @VisibleForTesting 44 public boolean mAttachedToDisplayArea; 45 @NonNull 46 private final WindowTokenClient mToken; 47 48 /** 49 * Window Context Controller constructor 50 * 51 * @param token The token used to attach to a window manager node. It is usually from 52 * {@link Context#getWindowContextToken()}. 53 */ WindowContextController(@onNull WindowTokenClient token)54 public WindowContextController(@NonNull WindowTokenClient token) { 55 mToken = token; 56 } 57 58 /** 59 * Attaches the {@code mToken} to a {@link com.android.server.wm.DisplayArea}. 60 * 61 * @param type The window type of the {@link WindowContext} 62 * @param displayId The {@link Context#getDisplayId() ID of display} to associate with 63 * @param options The window context launched option 64 * @throws IllegalStateException if the {@code mToken} has already been attached to a 65 * DisplayArea. 66 */ attachToDisplayArea(@indowType int type, int displayId, @Nullable Bundle options)67 public void attachToDisplayArea(@WindowType int type, int displayId, @Nullable Bundle options) { 68 if (mAttachedToDisplayArea) { 69 throw new IllegalStateException("A Window Context can be only attached to " 70 + "a DisplayArea once."); 71 } 72 mAttachedToDisplayArea = mToken.attachToDisplayArea(type, displayId, options); 73 } 74 75 /** 76 * Switches to attach the window context to a window token. 77 * <p> 78 * Note that the context should have been attached to a 79 * {@link com.android.server.wm.DisplayArea} by {@link #attachToDisplayArea(int, int, Bundle)} 80 * before attaching to a window token, and the window token's type must match the window 81 * context's type. 82 * </p><p> 83 * A {@link WindowContext} can only attach to a specific window manager node, which is either a 84 * {@link com.android.server.wm.DisplayArea} by calling 85 * {@link #attachToDisplayArea(int, int, Bundle)} or the latest attached {@code windowToken} 86 * although this API is allowed to be called multiple times. 87 * </p> 88 * @throws IllegalStateException if the {@code mClientToken} has not yet attached to 89 * a {@link com.android.server.wm.DisplayArea} by 90 * {@link #attachToDisplayArea(int, int, Bundle)}. 91 * 92 * @see WindowProviderService#attachToWindowToken(IBinder)) 93 * @see IWindowManager#attachWindowContextToWindowToken(IBinder, IBinder) 94 */ attachToWindowToken(IBinder windowToken)95 public void attachToWindowToken(IBinder windowToken) { 96 if (!mAttachedToDisplayArea) { 97 throw new IllegalStateException("The Window Context should have been attached" 98 + " to a DisplayArea."); 99 } 100 mToken.attachToWindowToken(windowToken); 101 } 102 103 /** Detaches the window context from the node it's currently associated with. */ detachIfNeeded()104 public void detachIfNeeded() { 105 if (mAttachedToDisplayArea) { 106 mToken.detachFromWindowContainerIfNeeded(); 107 mAttachedToDisplayArea = false; 108 } 109 } 110 } 111