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.view;
17 
18 import static android.view.View.SYSTEM_UI_FLAG_VISIBLE;
19 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
20 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
21 
22 import android.app.ResourcesManager;
23 import android.content.Context;
24 import android.content.res.Configuration;
25 import android.graphics.Point;
26 import android.graphics.Rect;
27 import android.graphics.Region;
28 import android.os.IBinder;
29 import android.os.RemoteException;
30 import android.util.DisplayMetrics;
31 import android.view.Display.Mode;
32 
33 import com.android.ide.common.rendering.api.ILayoutLog;
34 import com.android.layoutlib.bridge.Bridge;
35 
36 public class WindowManagerImpl implements WindowManager {
37 
38     private final Context mContext;
39     private final DisplayMetrics mMetrics;
40     private final Display mDisplay;
41 
WindowManagerImpl(Context context, DisplayMetrics metrics)42     public WindowManagerImpl(Context context, DisplayMetrics metrics) {
43         mContext = context;
44         mMetrics = metrics;
45 
46         DisplayInfo info = new DisplayInfo();
47         info.logicalHeight = mMetrics.heightPixels;
48         info.logicalWidth = mMetrics.widthPixels;
49         info.supportedModes = new Mode[] {
50                 new Mode(0, mMetrics.widthPixels, mMetrics.heightPixels, 60f)
51         };
52         info.logicalDensityDpi = mMetrics.densityDpi;
53         mDisplay = new Display(null, Display.DEFAULT_DISPLAY, info,
54                 DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
55     }
56 
createLocalWindowManager(Window parentWindow)57     public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
58         Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
59                 "The preview does not support multiple windows.",
60                 null, null, null);
61         return this;
62     }
63 
createPresentationWindowManager(Context displayContext)64     public WindowManagerImpl createPresentationWindowManager(Context displayContext) {
65         Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
66                 "The preview does not support multiple windows.",
67                 null, null, null);
68         return this;
69     }
70 
71     /**
72      * Sets the window token to assign when none is specified by the client or
73      * available from the parent window.
74      *
75      * @param token The default token to assign.
76      */
setDefaultToken(IBinder token)77     public void setDefaultToken(IBinder token) {
78 
79     }
80 
81     @Override
getDefaultDisplay()82     public Display getDefaultDisplay() {
83         return mDisplay;
84     }
85 
86 
87     @Override
addView(View arg0, android.view.ViewGroup.LayoutParams arg1)88     public void addView(View arg0, android.view.ViewGroup.LayoutParams arg1) {
89         // pass
90     }
91 
92     @Override
removeView(View arg0)93     public void removeView(View arg0) {
94         // pass
95     }
96 
97     @Override
updateViewLayout(View arg0, android.view.ViewGroup.LayoutParams arg1)98     public void updateViewLayout(View arg0, android.view.ViewGroup.LayoutParams arg1) {
99         // pass
100     }
101 
102 
103     @Override
removeViewImmediate(View arg0)104     public void removeViewImmediate(View arg0) {
105         // pass
106     }
107 
108     @Override
requestAppKeyboardShortcuts( KeyboardShortcutsReceiver receiver, int deviceId)109     public void requestAppKeyboardShortcuts(
110             KeyboardShortcutsReceiver receiver, int deviceId) {
111     }
112 
113     @Override
getCurrentImeTouchRegion()114     public Region getCurrentImeTouchRegion() {
115         return null;
116     }
117 
118     @Override
setShouldShowWithInsecureKeyguard(int displayId, boolean shouldShow)119     public void setShouldShowWithInsecureKeyguard(int displayId, boolean shouldShow) {
120         // pass
121     }
122 
123     @Override
setShouldShowSystemDecors(int displayId, boolean shouldShow)124     public void setShouldShowSystemDecors(int displayId, boolean shouldShow) {
125         // pass
126     }
127 
128     @Override
setDisplayImePolicy(int displayId, int imePolicy)129     public void setDisplayImePolicy(int displayId, int imePolicy) {
130         // pass
131     }
132 
133     @Override
getCurrentWindowMetrics()134     public WindowMetrics getCurrentWindowMetrics() {
135         final Rect bound = getCurrentBounds(mContext);
136 
137         return new WindowMetrics(bound, computeWindowInsets());
138     }
139 
getCurrentBounds(Context context)140     private static Rect getCurrentBounds(Context context) {
141         synchronized (ResourcesManager.getInstance()) {
142             return context.getResources().getConfiguration().windowConfiguration.getBounds();
143         }
144     }
145 
146     @Override
getMaximumWindowMetrics()147     public WindowMetrics getMaximumWindowMetrics() {
148         return new WindowMetrics(getMaximumBounds(), computeWindowInsets());
149     }
150 
getMaximumBounds()151     private Rect getMaximumBounds() {
152         final Point displaySize = new Point();
153         mDisplay.getRealSize(displaySize);
154         return new Rect(0, 0, displaySize.x, displaySize.y);
155     }
156 
computeWindowInsets()157     private WindowInsets computeWindowInsets() {
158         try {
159             final InsetsState insetsState = new InsetsState();
160             final boolean alwaysConsumeSystemBars =
161                     WindowManagerGlobal.getWindowManagerService().getWindowInsets(
162                             new WindowManager.LayoutParams(), mContext.getDisplayId(), insetsState);
163             final Configuration config = mContext.getResources().getConfiguration();
164             final boolean isScreenRound = config.isScreenRound();
165             final int windowingMode = config.windowConfiguration.getWindowingMode();
166             return insetsState.calculateInsets(getCurrentBounds(mContext),
167                     null /* ignoringVisibilityState*/, isScreenRound, alwaysConsumeSystemBars,
168                     SOFT_INPUT_ADJUST_NOTHING, 0, SYSTEM_UI_FLAG_VISIBLE, TYPE_APPLICATION,
169                     windowingMode, null /* typeSideMap */);
170         } catch (RemoteException ignore) {
171         }
172         return null;
173     }
174 }
175