blob: 81400260084cca681d7d0ff6f5922fd1dd751877 [file] [log] [blame]
Adam Cohena6d04922014-10-23 17:28:30 -07001package com.android.launcher3;
2
Sunny Goyaled2d2bc2018-04-19 12:34:43 -07003import static com.android.launcher3.util.SystemUiController.FLAG_DARK_NAV;
4import static com.android.launcher3.util.SystemUiController.UI_STATE_ROOT_VIEW;
5
Sunny Goyal93264612015-11-23 11:47:50 -08006import android.annotation.TargetApi;
7import android.app.ActivityManager;
Adam Cohena6d04922014-10-23 17:28:30 -07008import android.content.Context;
Sunny Goyal0abb36f2015-06-23 10:53:59 -07009import android.graphics.Canvas;
10import android.graphics.Color;
11import android.graphics.Paint;
Adam Cohena6d04922014-10-23 17:28:30 -070012import android.graphics.Rect;
Tony Wickham12e8a342019-04-23 11:28:54 -070013import android.os.Build;
Adam Cohena6d04922014-10-23 17:28:30 -070014import android.util.AttributeSet;
Sunny Goyal93264612015-11-23 11:47:50 -080015import android.view.View;
Sunny Goyal4ffec482016-02-09 11:28:52 -080016import android.view.ViewDebug;
Sunny Goyal745df7c2019-04-03 15:25:00 -070017import android.view.WindowInsets;
Adam Cohena6d04922014-10-23 17:28:30 -070018
Tony Wickham12e8a342019-04-23 11:28:54 -070019import java.util.Collections;
20import java.util.List;
21
Adam Cohena6d04922014-10-23 17:28:30 -070022public class LauncherRootView extends InsettableFrameLayout {
Sunny Goyal0abb36f2015-06-23 10:53:59 -070023
Sunny Goyal07b69292018-01-08 14:19:34 -080024 private final Launcher mLauncher;
25
Sunny Goyal0abb36f2015-06-23 10:53:59 -070026 private final Paint mOpaquePaint;
Sunny Goyal9001b102018-05-07 11:09:13 -070027
Sunny Goyal4ffec482016-02-09 11:28:52 -080028 @ViewDebug.ExportedProperty(category = "launcher")
Sunny Goyal9001b102018-05-07 11:09:13 -070029 private final Rect mConsumedInsets = new Rect();
Sunny Goyal0abb36f2015-06-23 10:53:59 -070030
Sunny Goyal745df7c2019-04-03 15:25:00 -070031 @ViewDebug.ExportedProperty(category = "launcher")
Tony Wickham12e8a342019-04-23 11:28:54 -070032 private static final List<Rect> SYSTEM_GESTURE_EXCLUSION_RECT =
33 Collections.singletonList(new Rect());
34
Sunny Goyal93264612015-11-23 11:47:50 -080035 private View mAlignedView;
Sunny Goyal7185dd62018-03-14 17:51:49 -070036 private WindowStateListener mWindowStateListener;
Tony Wickham12e8a342019-04-23 11:28:54 -070037 @ViewDebug.ExportedProperty(category = "launcher")
38 private boolean mDisallowBackGesture;
Sunny Goyal93264612015-11-23 11:47:50 -080039
Adam Cohena6d04922014-10-23 17:28:30 -070040 public LauncherRootView(Context context, AttributeSet attrs) {
41 super(context, attrs);
Sunny Goyal0abb36f2015-06-23 10:53:59 -070042
43 mOpaquePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
44 mOpaquePaint.setColor(Color.BLACK);
45 mOpaquePaint.setStyle(Paint.Style.FILL);
Sunny Goyal07b69292018-01-08 14:19:34 -080046
47 mLauncher = Launcher.getLauncher(context);
Adam Cohena6d04922014-10-23 17:28:30 -070048 }
49
50 @Override
Sunny Goyal93264612015-11-23 11:47:50 -080051 protected void onFinishInflate() {
52 if (getChildCount() > 0) {
53 // LauncherRootView contains only one child, which should be aligned
54 // based on the horizontal insets.
55 mAlignedView = getChildAt(0);
56 }
57 super.onFinishInflate();
58 }
59
60 @TargetApi(23)
61 @Override
Adam Cohena6d04922014-10-23 17:28:30 -070062 protected boolean fitSystemWindows(Rect insets) {
Sunny Goyal9001b102018-05-07 11:09:13 -070063 mConsumedInsets.setEmpty();
64 boolean drawInsetBar = false;
Sunny Goyal8c48d8b2019-01-25 15:10:18 -080065 if (mLauncher.isInMultiWindowMode()
Sunny Goyal9001b102018-05-07 11:09:13 -070066 && (insets.left > 0 || insets.right > 0 || insets.bottom > 0)) {
67 mConsumedInsets.left = insets.left;
68 mConsumedInsets.right = insets.right;
69 mConsumedInsets.bottom = insets.bottom;
70 insets = new Rect(0, insets.top, 0, 0);
71 drawInsetBar = true;
72 } else if ((insets.right > 0 || insets.left > 0) &&
Sunny Goyal8c48d8b2019-01-25 15:10:18 -080073 getContext().getSystemService(ActivityManager.class).isLowRamDevice()) {
Sunny Goyal9001b102018-05-07 11:09:13 -070074 mConsumedInsets.left = insets.left;
75 mConsumedInsets.right = insets.right;
Sunny Goyal906c6b22017-08-18 00:35:52 -070076 insets = new Rect(0, insets.top, 0, insets.bottom);
Sunny Goyal9001b102018-05-07 11:09:13 -070077 drawInsetBar = true;
Sunny Goyal906c6b22017-08-18 00:35:52 -070078 }
Sunny Goyal9001b102018-05-07 11:09:13 -070079
Sunny Goyal07b69292018-01-08 14:19:34 -080080 mLauncher.getSystemUiController().updateUiState(
Sunny Goyal9001b102018-05-07 11:09:13 -070081 UI_STATE_ROOT_VIEW, drawInsetBar ? FLAG_DARK_NAV : 0);
Sunny Goyal93264612015-11-23 11:47:50 -080082
Sunny Goyal07b69292018-01-08 14:19:34 -080083 // Update device profile before notifying th children.
84 mLauncher.getDeviceProfile().updateInsets(insets);
Sunny Goyalce8809a2018-01-18 14:02:47 -080085 boolean resetState = !insets.equals(mInsets);
Sunny Goyal906c6b22017-08-18 00:35:52 -070086 setInsets(insets);
87
88 if (mAlignedView != null) {
Sunny Goyal9001b102018-05-07 11:09:13 -070089 // Apply margins on aligned view to handle consumed insets.
Sunny Goyal93264612015-11-23 11:47:50 -080090 MarginLayoutParams lp = (MarginLayoutParams) mAlignedView.getLayoutParams();
Sunny Goyal9001b102018-05-07 11:09:13 -070091 if (lp.leftMargin != mConsumedInsets.left || lp.rightMargin != mConsumedInsets.right ||
92 lp.bottomMargin != mConsumedInsets.bottom) {
93 lp.leftMargin = mConsumedInsets.left;
94 lp.rightMargin = mConsumedInsets.right;
95 lp.topMargin = mConsumedInsets.top;
96 lp.bottomMargin = mConsumedInsets.bottom;
Sunny Goyal93264612015-11-23 11:47:50 -080097 mAlignedView.setLayoutParams(lp);
98 }
99 }
Sunny Goyalce8809a2018-01-18 14:02:47 -0800100 if (resetState) {
Sunny Goyaled2d2bc2018-04-19 12:34:43 -0700101 mLauncher.getStateManager().reapplyState(true /* cancelCurrentAnimation */);
Sunny Goyalce8809a2018-01-18 14:02:47 -0800102 }
Sunny Goyal0abb36f2015-06-23 10:53:59 -0700103
Adam Cohena6d04922014-10-23 17:28:30 -0700104 return true; // I'll take it from here
105 }
Sunny Goyal0abb36f2015-06-23 10:53:59 -0700106
Jon Mirandade43a712018-01-18 11:35:10 -0800107 @Override
108 public void setInsets(Rect insets) {
Sunny Goyalf8d56fc2018-01-31 15:18:11 -0800109 // If the insets haven't changed, this is a no-op. Avoid unnecessary layout caused by
110 // modifying child layout params.
111 if (!insets.equals(mInsets)) {
112 super.setInsets(insets);
113 }
Jon Mirandade43a712018-01-18 11:35:10 -0800114 }
115
Sunny Goyal07b69292018-01-08 14:19:34 -0800116 public void dispatchInsets() {
Sunny Goyal34778042018-04-11 16:31:31 -0700117 mLauncher.getDeviceProfile().updateInsets(mInsets);
Sunny Goyalf8d56fc2018-01-31 15:18:11 -0800118 super.setInsets(mInsets);
Sunny Goyal07b69292018-01-08 14:19:34 -0800119 }
120
Sunny Goyal0abb36f2015-06-23 10:53:59 -0700121 @Override
122 protected void dispatchDraw(Canvas canvas) {
123 super.dispatchDraw(canvas);
124
125 // If the right inset is opaque, draw a black rectangle to ensure that is stays opaque.
Sunny Goyal9001b102018-05-07 11:09:13 -0700126 if (mConsumedInsets.right > 0) {
127 int width = getWidth();
128 canvas.drawRect(width - mConsumedInsets.right, 0, width, getHeight(), mOpaquePaint);
129 }
130 if (mConsumedInsets.left > 0) {
131 canvas.drawRect(0, 0, mConsumedInsets.left, getHeight(), mOpaquePaint);
132 }
133 if (mConsumedInsets.bottom > 0) {
134 int height = getHeight();
135 canvas.drawRect(0, height - mConsumedInsets.bottom, getWidth(), height, mOpaquePaint);
Sunny Goyal0abb36f2015-06-23 10:53:59 -0700136 }
137 }
Sunny Goyal7185dd62018-03-14 17:51:49 -0700138
139 public void setWindowStateListener(WindowStateListener listener) {
140 mWindowStateListener = listener;
141 }
142
143 @Override
144 public void onWindowFocusChanged(boolean hasWindowFocus) {
145 super.onWindowFocusChanged(hasWindowFocus);
146 if (mWindowStateListener != null) {
147 mWindowStateListener.onWindowFocusChanged(hasWindowFocus);
148 }
149 }
150
151 @Override
152 protected void onWindowVisibilityChanged(int visibility) {
153 super.onWindowVisibilityChanged(visibility);
154 if (mWindowStateListener != null) {
155 mWindowStateListener.onWindowVisibilityChanged(visibility);
156 }
157 }
158
Sunny Goyal745df7c2019-04-03 15:25:00 -0700159 @Override
160 public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
Sunny Goyalbfaa9762019-04-25 18:04:41 -0700161 mLauncher.getDragLayer().updateTouchExcludeRegion(insets);
Sunny Goyal745df7c2019-04-03 15:25:00 -0700162 return super.dispatchApplyWindowInsets(insets);
163 }
164
165 @Override
Tony Wickham12e8a342019-04-23 11:28:54 -0700166 protected void onLayout(boolean changed, int l, int t, int r, int b) {
167 super.onLayout(changed, l, t, r, b);
168 SYSTEM_GESTURE_EXCLUSION_RECT.get(0).set(l, t, r, b);
169 setDisallowBackGesture(mDisallowBackGesture);
170 }
171
172 @TargetApi(Build.VERSION_CODES.Q)
173 public void setDisallowBackGesture(boolean disallowBackGesture) {
174 if (!Utilities.ATLEAST_Q) {
175 return;
176 }
177 mDisallowBackGesture = disallowBackGesture;
178 setSystemGestureExclusionRects(mDisallowBackGesture
179 ? SYSTEM_GESTURE_EXCLUSION_RECT
180 : Collections.emptyList());
181 }
182
Sunny Goyal7185dd62018-03-14 17:51:49 -0700183 public interface WindowStateListener {
184
185 void onWindowFocusChanged(boolean hasFocus);
186
187 void onWindowVisibilityChanged(int visibility);
188 }
Adam Cohena6d04922014-10-23 17:28:30 -0700189}