• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.launcher3;
2 
3 import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
4 
5 import android.annotation.TargetApi;
6 import android.content.Context;
7 import android.graphics.Canvas;
8 import android.graphics.Rect;
9 import android.os.Build;
10 import android.util.AttributeSet;
11 import android.view.ViewDebug;
12 import android.view.WindowInsets;
13 
14 import com.android.launcher3.graphics.SysUiScrim;
15 import com.android.launcher3.statemanager.StatefulActivity;
16 import com.android.launcher3.util.window.WindowManagerProxy;
17 
18 import java.util.Collections;
19 import java.util.List;
20 
21 public class LauncherRootView extends InsettableFrameLayout {
22 
23     private final Rect mTempRect = new Rect();
24 
25     private final StatefulActivity mActivity;
26 
27     @ViewDebug.ExportedProperty(category = "launcher")
28     private static final List<Rect> SYSTEM_GESTURE_EXCLUSION_RECT =
29             Collections.singletonList(new Rect());
30 
31     private WindowStateListener mWindowStateListener;
32     @ViewDebug.ExportedProperty(category = "launcher")
33     private boolean mDisallowBackGesture;
34     @ViewDebug.ExportedProperty(category = "launcher")
35     private boolean mForceHideBackArrow;
36 
37     private final SysUiScrim mSysUiScrim;
38 
LauncherRootView(Context context, AttributeSet attrs)39     public LauncherRootView(Context context, AttributeSet attrs) {
40         super(context, attrs);
41         mActivity = StatefulActivity.fromContext(context);
42         mSysUiScrim = new SysUiScrim(this);
43     }
44 
handleSystemWindowInsets(Rect insets)45     private void handleSystemWindowInsets(Rect insets) {
46         // Update device profile before notifying the children.
47         mActivity.getDeviceProfile().updateInsets(insets);
48         boolean resetState = !insets.equals(mInsets);
49         setInsets(insets);
50 
51         if (resetState) {
52             mActivity.getStateManager().reapplyState(true /* cancelCurrentAnimation */);
53         }
54     }
55 
56     @Override
onApplyWindowInsets(WindowInsets insets)57     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
58         mActivity.handleConfigurationChanged(mActivity.getResources().getConfiguration());
59 
60         insets = WindowManagerProxy.INSTANCE.get(getContext())
61                 .normalizeWindowInsets(getContext(), insets, mTempRect);
62         handleSystemWindowInsets(mTempRect);
63         return insets;
64     }
65 
66     @Override
setInsets(Rect insets)67     public void setInsets(Rect insets) {
68         // If the insets haven't changed, this is a no-op. Avoid unnecessary layout caused by
69         // modifying child layout params.
70         if (!insets.equals(mInsets)) {
71             super.setInsets(insets);
72             mSysUiScrim.onInsetsChanged(insets);
73         }
74     }
75 
dispatchInsets()76     public void dispatchInsets() {
77         mActivity.getDeviceProfile().updateInsets(mInsets);
78         super.setInsets(mInsets);
79     }
80 
setWindowStateListener(WindowStateListener listener)81     public void setWindowStateListener(WindowStateListener listener) {
82         mWindowStateListener = listener;
83     }
84 
85     @Override
onWindowFocusChanged(boolean hasWindowFocus)86     public void onWindowFocusChanged(boolean hasWindowFocus) {
87         super.onWindowFocusChanged(hasWindowFocus);
88         if (mWindowStateListener != null) {
89             mWindowStateListener.onWindowFocusChanged(hasWindowFocus);
90         }
91     }
92 
93     @Override
onWindowVisibilityChanged(int visibility)94     protected void onWindowVisibilityChanged(int visibility) {
95         super.onWindowVisibilityChanged(visibility);
96         if (mWindowStateListener != null) {
97             mWindowStateListener.onWindowVisibilityChanged(visibility);
98         }
99     }
100 
101     @Override
dispatchDraw(Canvas canvas)102     protected void dispatchDraw(Canvas canvas) {
103         mSysUiScrim.draw(canvas);
104         super.dispatchDraw(canvas);
105     }
106 
107     @Override
onLayout(boolean changed, int l, int t, int r, int b)108     protected void onLayout(boolean changed, int l, int t, int r, int b) {
109         super.onLayout(changed, l, t, r, b);
110         SYSTEM_GESTURE_EXCLUSION_RECT.get(0).set(l, t, r, b);
111         setDisallowBackGesture(mDisallowBackGesture);
112         mSysUiScrim.setSize(r - l, b - t);
113     }
114 
115     @TargetApi(Build.VERSION_CODES.Q)
setForceHideBackArrow(boolean forceHideBackArrow)116     public void setForceHideBackArrow(boolean forceHideBackArrow) {
117         this.mForceHideBackArrow = forceHideBackArrow;
118         setDisallowBackGesture(mDisallowBackGesture);
119     }
120 
121     @TargetApi(Build.VERSION_CODES.Q)
setDisallowBackGesture(boolean disallowBackGesture)122     public void setDisallowBackGesture(boolean disallowBackGesture) {
123         if (!Utilities.ATLEAST_Q || SEPARATE_RECENTS_ACTIVITY.get()) {
124             return;
125         }
126         mDisallowBackGesture = disallowBackGesture;
127         setSystemGestureExclusionRects((mForceHideBackArrow || mDisallowBackGesture)
128                 ? SYSTEM_GESTURE_EXCLUSION_RECT
129                 : Collections.emptyList());
130     }
131 
getSysUiScrim()132     public SysUiScrim getSysUiScrim() {
133         return mSysUiScrim;
134     }
135 
136     public interface WindowStateListener {
137 
onWindowFocusChanged(boolean hasFocus)138         void onWindowFocusChanged(boolean hasFocus);
139 
onWindowVisibilityChanged(int visibility)140         void onWindowVisibilityChanged(int visibility);
141     }
142 }
143