1 /*
2  * Copyright (C) 2006 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.view;
18 
19 import android.annotation.NonNull;
20 import android.compat.annotation.UnsupportedAppUsage;
21 import android.content.Context;
22 import android.graphics.Region;
23 import android.os.Bundle;
24 import android.os.IBinder;
25 import android.os.RemoteException;
26 
27 import com.android.internal.os.IResultReceiver;
28 
29 import java.util.List;
30 
31 /**
32  * Provides low-level communication with the system window manager for
33  * operations that are bound to a particular context, display or parent window.
34  * Instances of this object are sensitive to the compatibility info associated
35  * with the running application.
36  *
37  * This object implements the {@link ViewManager} interface,
38  * allowing you to add any View subclass as a top-level window on the screen.
39  * Additional window manager specific layout parameters are defined for
40  * control over how windows are displayed.  It also implements the {@link WindowManager}
41  * interface, allowing you to control the displays attached to the device.
42  *
43  * <p>Applications will not normally use WindowManager directly, instead relying
44  * on the higher-level facilities in {@link android.app.Activity} and
45  * {@link android.app.Dialog}.
46  *
47  * <p>Even for low-level window manager access, it is almost never correct to use
48  * this class.  For example, {@link android.app.Activity#getWindowManager}
49  * provides a window manager for adding windows that are associated with that
50  * activity -- the window manager will not normally allow you to add arbitrary
51  * windows that are not associated with an activity.
52  *
53  * @see WindowManager
54  * @see WindowManagerGlobal
55  * @hide
56  */
57 public final class WindowManagerImpl implements WindowManager {
58     @UnsupportedAppUsage
59     private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
60     private final Context mContext;
61     private final Window mParentWindow;
62 
63     private IBinder mDefaultToken;
64 
WindowManagerImpl(Context context)65     public WindowManagerImpl(Context context) {
66         this(context, null);
67     }
68 
WindowManagerImpl(Context context, Window parentWindow)69     private WindowManagerImpl(Context context, Window parentWindow) {
70         mContext = context;
71         mParentWindow = parentWindow;
72     }
73 
createLocalWindowManager(Window parentWindow)74     public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
75         return new WindowManagerImpl(mContext, parentWindow);
76     }
77 
createPresentationWindowManager(Context displayContext)78     public WindowManagerImpl createPresentationWindowManager(Context displayContext) {
79         return new WindowManagerImpl(displayContext, mParentWindow);
80     }
81 
82     /**
83      * Sets the window token to assign when none is specified by the client or
84      * available from the parent window.
85      *
86      * @param token The default token to assign.
87      */
setDefaultToken(IBinder token)88     public void setDefaultToken(IBinder token) {
89         mDefaultToken = token;
90     }
91 
92     @Override
addView(@onNull View view, @NonNull ViewGroup.LayoutParams params)93     public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
94         applyDefaultToken(params);
95         mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
96     }
97 
98     @Override
updateViewLayout(@onNull View view, @NonNull ViewGroup.LayoutParams params)99     public void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
100         applyDefaultToken(params);
101         mGlobal.updateViewLayout(view, params);
102     }
103 
applyDefaultToken(@onNull ViewGroup.LayoutParams params)104     private void applyDefaultToken(@NonNull ViewGroup.LayoutParams params) {
105         // Only use the default token if we don't have a parent window.
106         if (mDefaultToken != null && mParentWindow == null) {
107             if (!(params instanceof WindowManager.LayoutParams)) {
108                 throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
109             }
110 
111             // Only use the default token if we don't already have a token.
112             final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
113             if (wparams.token == null) {
114                 wparams.token = mDefaultToken;
115             }
116         }
117     }
118 
119     @Override
removeView(View view)120     public void removeView(View view) {
121         mGlobal.removeView(view, false);
122     }
123 
124     @Override
removeViewImmediate(View view)125     public void removeViewImmediate(View view) {
126         mGlobal.removeView(view, true);
127     }
128 
129     @Override
requestAppKeyboardShortcuts( final KeyboardShortcutsReceiver receiver, int deviceId)130     public void requestAppKeyboardShortcuts(
131             final KeyboardShortcutsReceiver receiver, int deviceId) {
132         IResultReceiver resultReceiver = new IResultReceiver.Stub() {
133             @Override
134             public void send(int resultCode, Bundle resultData) throws RemoteException {
135                 List<KeyboardShortcutGroup> result =
136                         resultData.getParcelableArrayList(PARCEL_KEY_SHORTCUTS_ARRAY);
137                 receiver.onKeyboardShortcutsReceived(result);
138             }
139         };
140         try {
141             WindowManagerGlobal.getWindowManagerService()
142                 .requestAppKeyboardShortcuts(resultReceiver, deviceId);
143         } catch (RemoteException e) {
144         }
145     }
146 
147     @Override
getDefaultDisplay()148     public Display getDefaultDisplay() {
149         return mContext.getDisplay();
150     }
151 
152     @Override
getCurrentImeTouchRegion()153     public Region getCurrentImeTouchRegion() {
154         try {
155             return WindowManagerGlobal.getWindowManagerService().getCurrentImeTouchRegion();
156         } catch (RemoteException e) {
157         }
158         return null;
159     }
160 
161     @Override
setShouldShowWithInsecureKeyguard(int displayId, boolean shouldShow)162     public void setShouldShowWithInsecureKeyguard(int displayId, boolean shouldShow) {
163         try {
164             WindowManagerGlobal.getWindowManagerService()
165                     .setShouldShowWithInsecureKeyguard(displayId, shouldShow);
166         } catch (RemoteException e) {
167         }
168     }
169 
170     @Override
setShouldShowSystemDecors(int displayId, boolean shouldShow)171     public void setShouldShowSystemDecors(int displayId, boolean shouldShow) {
172         try {
173             WindowManagerGlobal.getWindowManagerService()
174                     .setShouldShowSystemDecors(displayId, shouldShow);
175         } catch (RemoteException e) {
176         }
177     }
178 
179     @Override
shouldShowSystemDecors(int displayId)180     public boolean shouldShowSystemDecors(int displayId) {
181         try {
182             return WindowManagerGlobal.getWindowManagerService().shouldShowSystemDecors(displayId);
183         } catch (RemoteException e) {
184         }
185         return false;
186     }
187 
188     @Override
setShouldShowIme(int displayId, boolean shouldShow)189     public void setShouldShowIme(int displayId, boolean shouldShow) {
190         try {
191             WindowManagerGlobal.getWindowManagerService().setShouldShowIme(displayId, shouldShow);
192         } catch (RemoteException e) {
193         }
194     }
195 
196     @Override
shouldShowIme(int displayId)197     public boolean shouldShowIme(int displayId) {
198         try {
199             return WindowManagerGlobal.getWindowManagerService().shouldShowIme(displayId);
200         } catch (RemoteException e) {
201         }
202         return false;
203     }
204 }
205