1 /* 2 * Copyright (C) 2020 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 package android.window; 17 18 import static android.view.WindowManagerImpl.createWindowContextWindowManager; 19 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.UiContext; 23 import android.content.ComponentCallbacks; 24 import android.content.ComponentCallbacksController; 25 import android.content.Context; 26 import android.content.ContextWrapper; 27 import android.content.res.Configuration; 28 import android.os.Bundle; 29 import android.view.Display; 30 import android.view.WindowManager; 31 32 import com.android.internal.annotations.VisibleForTesting; 33 34 import java.lang.ref.Reference; 35 36 /** 37 * {@link WindowContext} is a context for non-activity windows such as 38 * {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} windows or system 39 * windows. Its resources and configuration are adjusted to the area of the display that will be 40 * used when a new window is added via {@link android.view.WindowManager#addView}. 41 * 42 * @see Context#createWindowContext(int, Bundle) 43 * @hide 44 */ 45 @UiContext 46 public class WindowContext extends ContextWrapper implements WindowProvider { 47 private final WindowManager mWindowManager; 48 @WindowManager.LayoutParams.WindowType 49 private final int mType; 50 @Nullable 51 private final Bundle mOptions; 52 private final ComponentCallbacksController mCallbacksController = 53 new ComponentCallbacksController(); 54 private final WindowContextController mController; 55 56 /** 57 * Default implementation of {@link WindowContext} 58 * <p> 59 * Note that the users should call {@link Context#createWindowContext(Display, int, Bundle)} 60 * to create a {@link WindowContext} instead of using this constructor 61 * </p><p> 62 * Example usage: 63 * <pre class="prettyprint"> 64 * Bundle options = new Bundle(); 65 * options.put(KEY_ROOT_DISPLAY_AREA_ID, displayAreaInfo.rootDisplayAreaId); 66 * Context windowContext = context.createWindowContext(display, windowType, options); 67 * </pre></p> 68 * 69 * @param base Base {@link Context} for this new instance. 70 * @param type Window type to be used with this context. 71 * @param options A bundle used to pass window-related options. 72 * @see DisplayAreaInfo#rootDisplayAreaId 73 */ WindowContext(@onNull Context base, int type, @Nullable Bundle options)74 public WindowContext(@NonNull Context base, int type, @Nullable Bundle options) { 75 super(base); 76 77 mType = type; 78 mOptions = options; 79 mWindowManager = createWindowContextWindowManager(this); 80 WindowTokenClient token = (WindowTokenClient) getWindowContextToken(); 81 mController = new WindowContextController(token); 82 83 Reference.reachabilityFence(this); 84 } 85 86 /** 87 * Attaches this {@link WindowContext} to the {@link com.android.server.wm.DisplayArea} 88 * specified by {@code mType}, {@link #getDisplayId() display ID} and {@code mOptions} 89 * to receive configuration changes. 90 */ attachToDisplayArea()91 public void attachToDisplayArea() { 92 mController.attachToDisplayArea(mType, getDisplayId(), mOptions); 93 } 94 95 @Override getSystemService(String name)96 public Object getSystemService(String name) { 97 if (WINDOW_SERVICE.equals(name)) { 98 return mWindowManager; 99 } 100 return super.getSystemService(name); 101 } 102 103 @Override finalize()104 protected void finalize() throws Throwable { 105 release(); 106 super.finalize(); 107 } 108 109 /** Used for test to invoke because we can't invoke finalize directly. */ 110 @VisibleForTesting release()111 public void release() { 112 mController.detachIfNeeded(); 113 destroy(); 114 } 115 116 @Override destroy()117 public void destroy() { 118 try { 119 mCallbacksController.clearCallbacks(); 120 // Called to the base ContextImpl to do final clean-up. 121 getBaseContext().destroy(); 122 } finally { 123 Reference.reachabilityFence(this); 124 } 125 } 126 127 @Override registerComponentCallbacks(@onNull ComponentCallbacks callback)128 public void registerComponentCallbacks(@NonNull ComponentCallbacks callback) { 129 mCallbacksController.registerCallbacks(callback); 130 } 131 132 @Override unregisterComponentCallbacks(@onNull ComponentCallbacks callback)133 public void unregisterComponentCallbacks(@NonNull ComponentCallbacks callback) { 134 mCallbacksController.unregisterCallbacks(callback); 135 } 136 137 /** Dispatch {@link Configuration} to each {@link ComponentCallbacks}. */ dispatchConfigurationChanged(@onNull Configuration newConfig)138 void dispatchConfigurationChanged(@NonNull Configuration newConfig) { 139 mCallbacksController.dispatchConfigurationChanged(newConfig); 140 } 141 142 @Override getWindowType()143 public int getWindowType() { 144 return mType; 145 } 146 147 @Nullable 148 @Override getWindowContextOptions()149 public Bundle getWindowContextOptions() { 150 return mOptions; 151 } 152 } 153