• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import com.android.window.flags.Flags;
34 
35 import java.lang.ref.Reference;
36 
37 /**
38  * {@link WindowContext} is a context for non-activity windows such as
39  * {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} windows or system
40  * windows. Its resources and configuration are adjusted to the area of the display that will be
41  * used when a new window is added via {@link android.view.WindowManager#addView}.
42  *
43  * @see Context#createWindowContext(int, Bundle)
44  * @hide
45  */
46 @UiContext
47 public class WindowContext extends ContextWrapper implements WindowProvider,
48         ConfigurationDispatcher {
49     private final WindowManager mWindowManager;
50     @WindowManager.LayoutParams.WindowType
51     private final int mType;
52     @Nullable
53     private final Bundle mOptions;
54     private final ComponentCallbacksController mCallbacksController =
55             new ComponentCallbacksController();
56     private final WindowContextController mController;
57 
58     /**
59      * Default implementation of {@link WindowContext}
60      * <p>
61      * Note that the users should call {@link Context#createWindowContext(Display, int, Bundle)}
62      * to create a {@link WindowContext} instead of using this constructor
63      * </p><p>
64      * Example usage:
65      * <pre class="prettyprint">
66      * Bundle options = new Bundle();
67      * options.put(KEY_ROOT_DISPLAY_AREA_ID, displayAreaInfo.rootDisplayAreaId);
68      * Context windowContext = context.createWindowContext(display, windowType, options);
69      * </pre></p>
70      *
71      * @param base    Base {@link Context} for this new instance.
72      * @param type    Window type to be used with this context.
73      * @param options A bundle used to pass window-related options.
74      * @see DisplayAreaInfo#rootDisplayAreaId
75      */
WindowContext(@onNull Context base, int type, @Nullable Bundle options)76     public WindowContext(@NonNull Context base, int type, @Nullable Bundle options) {
77         super(base);
78 
79         mType = type;
80         mOptions = options;
81         mWindowManager = createWindowContextWindowManager(this);
82         WindowTokenClient token = (WindowTokenClient) getWindowContextToken();
83         mController = new WindowContextController(token);
84 
85         Reference.reachabilityFence(this);
86     }
87 
88     /**
89      * Attaches this {@link WindowContext} to the {@link com.android.server.wm.DisplayArea}
90      * specified by {@code mType}, {@link #getDisplayId() display ID} and {@code mOptions}
91      * to receive configuration changes.
92      */
attachToDisplayArea()93     public void attachToDisplayArea() {
94         mController.attachToDisplayArea(mType, getDisplayId(), mOptions);
95     }
96 
97     /**
98      * Moves this context to another display.
99      * <p>
100      * Note that this re-parents all the previously attached windows. Resources associated with this
101      * context will have the correct value and configuration for the new display after this is
102      * called.
103      */
reparentToDisplay(int displayId)104     public void reparentToDisplay(int displayId) {
105         if (Flags.reparentWindowTokenApi()) {
106             if (displayId == getDisplayId()) {
107                 return;
108             }
109             super.updateDisplay(displayId);
110             mController.reparentToDisplayArea(mType, displayId, mOptions);
111         }
112     }
113 
114     @Override
getSystemService(String name)115     public Object getSystemService(String name) {
116         if (WINDOW_SERVICE.equals(name)) {
117             return mWindowManager;
118         }
119         return super.getSystemService(name);
120     }
121 
122     @Override
finalize()123     protected void finalize() throws Throwable {
124         release();
125         super.finalize();
126     }
127 
128     /** Used for test to invoke because we can't invoke finalize directly. */
129     @VisibleForTesting
release()130     public void release() {
131         mController.detachIfNeeded();
132         destroy();
133     }
134 
135     @Override
destroy()136     public void destroy() {
137         try {
138             mCallbacksController.clearCallbacks();
139             // Called to the base ContextImpl to do final clean-up.
140             getBaseContext().destroy();
141         } finally {
142             Reference.reachabilityFence(this);
143         }
144     }
145 
146     @Override
registerComponentCallbacks(@onNull ComponentCallbacks callback)147     public void registerComponentCallbacks(@NonNull ComponentCallbacks callback) {
148         mCallbacksController.registerCallbacks(callback);
149     }
150 
151     @Override
unregisterComponentCallbacks(@onNull ComponentCallbacks callback)152     public void unregisterComponentCallbacks(@NonNull ComponentCallbacks callback) {
153         mCallbacksController.unregisterCallbacks(callback);
154     }
155 
156     /** Dispatch {@link Configuration} to each {@link ComponentCallbacks}. */
157     @Override
dispatchConfigurationChanged(@onNull Configuration newConfig)158     public void dispatchConfigurationChanged(@NonNull Configuration newConfig) {
159         mCallbacksController.dispatchConfigurationChanged(newConfig);
160     }
161 
162     @Override
getWindowType()163     public int getWindowType() {
164         return mType;
165     }
166 
167     @Nullable
168     @Override
getWindowContextOptions()169     public Bundle getWindowContextOptions() {
170         return mOptions;
171     }
172 
173     @Override
shouldReportPrivateChanges()174     public boolean shouldReportPrivateChanges() {
175         // Always dispatch config changes to WindowContext.
176         return true;
177     }
178 }
179