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