1 /*
2  * Copyright (C) 2017 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 com.android.systemui.shared.system;
18 
19 import static android.view.Display.DEFAULT_DISPLAY;
20 import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
21 import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID;
22 import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
23 import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
24 
25 import android.app.WindowConfiguration;
26 import android.graphics.Rect;
27 import android.os.Handler;
28 import android.os.RemoteException;
29 import android.util.Log;
30 import android.view.SurfaceControl;
31 import android.view.WindowManager;
32 import android.view.WindowManagerGlobal;
33 
34 import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
35 import com.android.systemui.shared.recents.view.RecentsTransition;
36 import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener;
37 
38 public class WindowManagerWrapper {
39 
40     private static final String TAG = "WindowManagerWrapper";
41 
42     public static final int TRANSIT_UNSET = WindowManager.TRANSIT_UNSET;
43     public static final int TRANSIT_NONE = WindowManager.TRANSIT_NONE;
44     public static final int TRANSIT_ACTIVITY_OPEN = WindowManager.TRANSIT_ACTIVITY_OPEN;
45     public static final int TRANSIT_ACTIVITY_CLOSE = WindowManager.TRANSIT_ACTIVITY_CLOSE;
46     public static final int TRANSIT_TASK_OPEN = WindowManager.TRANSIT_TASK_OPEN;
47     public static final int TRANSIT_TASK_CLOSE = WindowManager.TRANSIT_TASK_CLOSE;
48     public static final int TRANSIT_TASK_TO_FRONT = WindowManager.TRANSIT_TASK_TO_FRONT;
49     public static final int TRANSIT_TASK_TO_BACK = WindowManager.TRANSIT_TASK_TO_BACK;
50     public static final int TRANSIT_WALLPAPER_CLOSE = WindowManager.TRANSIT_WALLPAPER_CLOSE;
51     public static final int TRANSIT_WALLPAPER_OPEN = WindowManager.TRANSIT_WALLPAPER_OPEN;
52     public static final int TRANSIT_WALLPAPER_INTRA_OPEN =
53             WindowManager.TRANSIT_WALLPAPER_INTRA_OPEN;
54     public static final int TRANSIT_WALLPAPER_INTRA_CLOSE =
55             WindowManager.TRANSIT_WALLPAPER_INTRA_CLOSE;
56     public static final int TRANSIT_TASK_OPEN_BEHIND = WindowManager.TRANSIT_TASK_OPEN_BEHIND;
57     public static final int TRANSIT_ACTIVITY_RELAUNCH = WindowManager.TRANSIT_ACTIVITY_RELAUNCH;
58     public static final int TRANSIT_DOCK_TASK_FROM_RECENTS =
59             WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
60     public static final int TRANSIT_KEYGUARD_GOING_AWAY = WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
61     public static final int TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER =
62             WindowManager.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
63     public static final int TRANSIT_KEYGUARD_OCCLUDE = WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
64     public static final int TRANSIT_KEYGUARD_UNOCCLUDE = WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
65 
66     public static final int NAV_BAR_POS_INVALID = NAV_BAR_INVALID;
67     public static final int NAV_BAR_POS_LEFT = NAV_BAR_LEFT;
68     public static final int NAV_BAR_POS_RIGHT = NAV_BAR_RIGHT;
69     public static final int NAV_BAR_POS_BOTTOM = NAV_BAR_BOTTOM;
70 
71     public static final int ACTIVITY_TYPE_STANDARD = WindowConfiguration.ACTIVITY_TYPE_STANDARD;
72 
73     public static final int WINDOWING_MODE_UNDEFINED = WindowConfiguration.WINDOWING_MODE_UNDEFINED;
74     public static final int WINDOWING_MODE_FULLSCREEN =
75             WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
76     public static final int WINDOWING_MODE_MULTI_WINDOW =
77             WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
78     public static final int WINDOWING_MODE_PINNED = WindowConfiguration.WINDOWING_MODE_PINNED;
79     public static final int WINDOWING_MODE_SPLIT_SCREEN_PRIMARY =
80             WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
81     public static final int WINDOWING_MODE_SPLIT_SCREEN_SECONDARY =
82             WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
83     public static final int WINDOWING_MODE_FREEFORM = WindowConfiguration.WINDOWING_MODE_FREEFORM;
84 
85     private static final WindowManagerWrapper sInstance = new WindowManagerWrapper();
86 
87     /**
88      * Forwarder to which we can add multiple pinned stack listeners. Each listener will receive
89      * updates from the window manager service.
90      */
91     private PinnedStackListenerForwarder mPinnedStackListenerForwarder =
92             new PinnedStackListenerForwarder();
93 
getInstance()94     public static WindowManagerWrapper getInstance() {
95         return sInstance;
96     }
97 
98     /**
99      * @return the stable insets for the primary display.
100      */
getStableInsets(Rect outStableInsets)101     public void getStableInsets(Rect outStableInsets) {
102         try {
103             WindowManagerGlobal.getWindowManagerService().getStableInsets(DEFAULT_DISPLAY,
104                     outStableInsets);
105         } catch (RemoteException e) {
106             Log.e(TAG, "Failed to get stable insets", e);
107         }
108     }
109 
110     /**
111      * Overrides a pending app transition.
112      */
overridePendingAppTransitionMultiThumbFuture( AppTransitionAnimationSpecsFuture animationSpecFuture, Runnable animStartedCallback, Handler animStartedCallbackHandler, boolean scaleUp, int displayId)113     public void overridePendingAppTransitionMultiThumbFuture(
114             AppTransitionAnimationSpecsFuture animationSpecFuture, Runnable animStartedCallback,
115             Handler animStartedCallbackHandler, boolean scaleUp, int displayId) {
116         try {
117             WindowManagerGlobal.getWindowManagerService()
118                     .overridePendingAppTransitionMultiThumbFuture(animationSpecFuture.getFuture(),
119                             RecentsTransition.wrapStartedListener(animStartedCallbackHandler,
120                                     animStartedCallback), scaleUp, displayId);
121         } catch (RemoteException e) {
122             Log.w(TAG, "Failed to override pending app transition (multi-thumbnail future): ", e);
123         }
124     }
125 
overridePendingAppTransitionRemote( RemoteAnimationAdapterCompat remoteAnimationAdapter, int displayId)126     public void overridePendingAppTransitionRemote(
127             RemoteAnimationAdapterCompat remoteAnimationAdapter, int displayId) {
128         try {
129             WindowManagerGlobal.getWindowManagerService().overridePendingAppTransitionRemote(
130                     remoteAnimationAdapter.getWrapped(), displayId);
131         } catch (RemoteException e) {
132             Log.w(TAG, "Failed to override pending app transition (remote): ", e);
133         }
134     }
135 
136     /**
137      * Enable or disable haptic feedback on the navigation bar buttons.
138      */
setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled)139     public void setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled) {
140         try {
141             WindowManagerGlobal.getWindowManagerService()
142                     .setNavBarVirtualKeyHapticFeedbackEnabled(enabled);
143         } catch (RemoteException e) {
144             Log.w(TAG, "Failed to enable or disable navigation bar button haptics: ", e);
145         }
146     }
147 
setRecentsVisibility(boolean visible)148     public void setRecentsVisibility(boolean visible) {
149         try {
150             WindowManagerGlobal.getWindowManagerService().setRecentsVisibility(visible);
151         } catch (RemoteException e) {
152             Log.w(TAG, "Failed to set recents visibility");
153         }
154     }
155 
setPipVisibility(final boolean visible)156     public void setPipVisibility(final boolean visible) {
157         try {
158             WindowManagerGlobal.getWindowManagerService().setPipVisibility(visible);
159         } catch (RemoteException e) {
160             Log.e(TAG, "Unable to reach window manager", e);
161         }
162     }
163 
164     /**
165      * @param displayId the id of display to check if there is a software navigation bar.
166      *
167      * @return whether there is a soft nav bar on specific display.
168      */
hasSoftNavigationBar(int displayId)169     public boolean hasSoftNavigationBar(int displayId) {
170         try {
171             return WindowManagerGlobal.getWindowManagerService().hasNavigationBar(displayId);
172         } catch (RemoteException e) {
173             return false;
174         }
175     }
176 
177     /**
178      * @return The side of the screen where navigation bar is positioned.
179      * @see #NAV_BAR_POS_RIGHT
180      * @see #NAV_BAR_POS_LEFT
181      * @see #NAV_BAR_POS_BOTTOM
182      * @see #NAV_BAR_POS_INVALID
183      */
getNavBarPosition(int displayId)184     public int getNavBarPosition(int displayId) {
185         try {
186             return WindowManagerGlobal.getWindowManagerService().getNavBarPosition(displayId);
187         } catch (RemoteException e) {
188             Log.w(TAG, "Failed to get nav bar position");
189         }
190         return NAV_BAR_POS_INVALID;
191     }
192 
193     /**
194      * Adds a pinned stack listener, which will receive updates from the window manager service
195      * along with any other pinned stack listeners that were added via this method.
196      */
addPinnedStackListener(PinnedStackListener listener)197     public void addPinnedStackListener(PinnedStackListener listener) throws RemoteException {
198         mPinnedStackListenerForwarder.addListener(listener);
199         WindowManagerGlobal.getWindowManagerService().registerPinnedStackListener(
200                 DEFAULT_DISPLAY, mPinnedStackListenerForwarder);
201     }
202 
203     /**
204      * Removes a pinned stack listener.
205      */
removePinnedStackListener(PinnedStackListener listener)206     public void removePinnedStackListener(PinnedStackListener listener) {
207         mPinnedStackListenerForwarder.removeListener(listener);
208     }
209 
210     /**
211      * Mirrors a specified display. The SurfaceControl returned is the root of the mirrored
212      * hierarchy.
213      *
214      * @param displayId The id of the display to mirror
215      * @return The SurfaceControl for the root of the mirrored hierarchy.
216      */
mirrorDisplay(final int displayId)217     public SurfaceControl mirrorDisplay(final int displayId) {
218         try {
219             SurfaceControl outSurfaceControl = new SurfaceControl();
220             WindowManagerGlobal.getWindowManagerService().mirrorDisplay(displayId,
221                     outSurfaceControl);
222             return outSurfaceControl;
223         } catch (RemoteException e) {
224             Log.e(TAG, "Unable to reach window manager", e);
225         }
226         return null;
227     }
228 }
229