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