blob: 49b380b41fb2c0bdacd233629a6967663c9d9da4 [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;
Adam Cohena6d04922014-10-23 17:28:30 -070017
Tony Wickham12e8a342019-04-23 11:28:54 -070018import java.util.Collections;
19import java.util.List;
20
Adam Cohena6d04922014-10-23 17:28:30 -070021public class LauncherRootView extends InsettableFrameLayout {
Sunny Goyal0abb36f2015-06-23 10:53:59 -070022
Sunny Goyal07b69292018-01-08 14:19:34 -080023 private final Launcher mLauncher;
24
Sunny Goyal0abb36f2015-06-23 10:53:59 -070025 private final Paint mOpaquePaint;
Sunny Goyal9001b102018-05-07 11:09:13 -070026
Sunny Goyal4ffec482016-02-09 11:28:52 -080027 @ViewDebug.ExportedProperty(category = "launcher")
Sunny Goyal9001b102018-05-07 11:09:13 -070028 private final Rect mConsumedInsets = new Rect();
Sunny Goyal0abb36f2015-06-23 10:53:59 -070029
Sunny Goyal745df7c2019-04-03 15:25:00 -070030 @ViewDebug.ExportedProperty(category = "launcher")
Tony Wickham12e8a342019-04-23 11:28:54 -070031 private static final List<Rect> SYSTEM_GESTURE_EXCLUSION_RECT =
32 Collections.singletonList(new Rect());
33
Sunny Goyal93264612015-11-23 11:47:50 -080034 private View mAlignedView;
Sunny Goyal7185dd62018-03-14 17:51:49 -070035 private WindowStateListener mWindowStateListener;
Tony Wickham12e8a342019-04-23 11:28:54 -070036 @ViewDebug.ExportedProperty(category = "launcher")
37 private boolean mDisallowBackGesture;
Sunny Goyal93264612015-11-23 11:47:50 -080038
Adam Cohena6d04922014-10-23 17:28:30 -070039 public LauncherRootView(Context context, AttributeSet attrs) {
40 super(context, attrs);
Sunny Goyal0abb36f2015-06-23 10:53:59 -070041
42 mOpaquePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
43 mOpaquePaint.setColor(Color.BLACK);
44 mOpaquePaint.setStyle(Paint.Style.FILL);
Sunny Goyal07b69292018-01-08 14:19:34 -080045
46 mLauncher = Launcher.getLauncher(context);
Adam Cohena6d04922014-10-23 17:28:30 -070047 }
48
49 @Override
Sunny Goyal93264612015-11-23 11:47:50 -080050 protected void onFinishInflate() {
51 if (getChildCount() > 0) {
52 // LauncherRootView contains only one child, which should be aligned
53 // based on the horizontal insets.
54 mAlignedView = getChildAt(0);
55 }
56 super.onFinishInflate();
57 }
58
59 @TargetApi(23)
60 @Override
Adam Cohena6d04922014-10-23 17:28:30 -070061 protected boolean fitSystemWindows(Rect insets) {
Sunny Goyal9001b102018-05-07 11:09:13 -070062 mConsumedInsets.setEmpty();
63 boolean drawInsetBar = false;
Sunny Goyal8c48d8b2019-01-25 15:10:18 -080064 if (mLauncher.isInMultiWindowMode()
Sunny Goyal9001b102018-05-07 11:09:13 -070065 && (insets.left > 0 || insets.right > 0 || insets.bottom > 0)) {
66 mConsumedInsets.left = insets.left;
67 mConsumedInsets.right = insets.right;
68 mConsumedInsets.bottom = insets.bottom;
69 insets = new Rect(0, insets.top, 0, 0);
70 drawInsetBar = true;
71 } else if ((insets.right > 0 || insets.left > 0) &&
Sunny Goyal8c48d8b2019-01-25 15:10:18 -080072 getContext().getSystemService(ActivityManager.class).isLowRamDevice()) {
Sunny Goyal9001b102018-05-07 11:09:13 -070073 mConsumedInsets.left = insets.left;
74 mConsumedInsets.right = insets.right;
Sunny Goyal906c6b22017-08-18 00:35:52 -070075 insets = new Rect(0, insets.top, 0, insets.bottom);
Sunny Goyal9001b102018-05-07 11:09:13 -070076 drawInsetBar = true;
Sunny Goyal906c6b22017-08-18 00:35:52 -070077 }
Sunny Goyal9001b102018-05-07 11:09:13 -070078
Sunny Goyal07b69292018-01-08 14:19:34 -080079 mLauncher.getSystemUiController().updateUiState(
Sunny Goyal9001b102018-05-07 11:09:13 -070080 UI_STATE_ROOT_VIEW, drawInsetBar ? FLAG_DARK_NAV : 0);
Sunny Goyal93264612015-11-23 11:47:50 -080081
Sunny Goyal07b69292018-01-08 14:19:34 -080082 // Update device profile before notifying th children.
Sunny Goyalae6e3182019-04-30 12:04:37 -070083 mLauncher.updateInsets(insets);
Sunny Goyalce8809a2018-01-18 14:02:47 -080084 boolean resetState = !insets.equals(mInsets);
Sunny Goyal906c6b22017-08-18 00:35:52 -070085 setInsets(insets);
86
87 if (mAlignedView != null) {
Sunny Goyal9001b102018-05-07 11:09:13 -070088 // Apply margins on aligned view to handle consumed insets.
Sunny Goyal93264612015-11-23 11:47:50 -080089 MarginLayoutParams lp = (MarginLayoutParams) mAlignedView.getLayoutParams();
Sunny Goyal9001b102018-05-07 11:09:13 -070090 if (lp.leftMargin != mConsumedInsets.left || lp.rightMargin != mConsumedInsets.right ||
91 lp.bottomMargin != mConsumedInsets.bottom) {
92 lp.leftMargin = mConsumedInsets.left;
93 lp.rightMargin = mConsumedInsets.right;
94 lp.topMargin = mConsumedInsets.top;
95 lp.bottomMargin = mConsumedInsets.bottom;
Sunny Goyal93264612015-11-23 11:47:50 -080096 mAlignedView.setLayoutParams(lp);
97 }
98 }
Sunny Goyalce8809a2018-01-18 14:02:47 -080099 if (resetState) {
Sunny Goyaled2d2bc2018-04-19 12:34:43 -0700100 mLauncher.getStateManager().reapplyState(true /* cancelCurrentAnimation */);
Sunny Goyalce8809a2018-01-18 14:02:47 -0800101 }
Sunny Goyal0abb36f2015-06-23 10:53:59 -0700102
Sunny Goyal2524b822019-05-17 16:33:37 -0700103 return false; // Let children get the full insets
Adam Cohena6d04922014-10-23 17:28:30 -0700104 }
Sunny Goyal0abb36f2015-06-23 10:53:59 -0700105
Jon Mirandade43a712018-01-18 11:35:10 -0800106 @Override
107 public void setInsets(Rect insets) {
Sunny Goyalf8d56fc2018-01-31 15:18:11 -0800108 // If the insets haven't changed, this is a no-op. Avoid unnecessary layout caused by
109 // modifying child layout params.
110 if (!insets.equals(mInsets)) {
111 super.setInsets(insets);
112 }
Jon Mirandade43a712018-01-18 11:35:10 -0800113 }
114
Sunny Goyal07b69292018-01-08 14:19:34 -0800115 public void dispatchInsets() {
Sunny Goyalae6e3182019-04-30 12:04:37 -0700116 mLauncher.updateInsets(mInsets);
Sunny Goyalf8d56fc2018-01-31 15:18:11 -0800117 super.setInsets(mInsets);
Sunny Goyal07b69292018-01-08 14:19:34 -0800118 }
119
Sunny Goyal0abb36f2015-06-23 10:53:59 -0700120 @Override
121 protected void dispatchDraw(Canvas canvas) {
122 super.dispatchDraw(canvas);
123
124 // If the right inset is opaque, draw a black rectangle to ensure that is stays opaque.
Sunny Goyal9001b102018-05-07 11:09:13 -0700125 if (mConsumedInsets.right > 0) {
126 int width = getWidth();
127 canvas.drawRect(width - mConsumedInsets.right, 0, width, getHeight(), mOpaquePaint);
128 }
129 if (mConsumedInsets.left > 0) {
130 canvas.drawRect(0, 0, mConsumedInsets.left, getHeight(), mOpaquePaint);
131 }
132 if (mConsumedInsets.bottom > 0) {
133 int height = getHeight();
134 canvas.drawRect(0, height - mConsumedInsets.bottom, getWidth(), height, mOpaquePaint);
Sunny Goyal0abb36f2015-06-23 10:53:59 -0700135 }
136 }
Sunny Goyal7185dd62018-03-14 17:51:49 -0700137
138 public void setWindowStateListener(WindowStateListener listener) {
139 mWindowStateListener = listener;
140 }
141
142 @Override
143 public void onWindowFocusChanged(boolean hasWindowFocus) {
144 super.onWindowFocusChanged(hasWindowFocus);
145 if (mWindowStateListener != null) {
146 mWindowStateListener.onWindowFocusChanged(hasWindowFocus);
147 }
148 }
149
150 @Override
151 protected void onWindowVisibilityChanged(int visibility) {
152 super.onWindowVisibilityChanged(visibility);
153 if (mWindowStateListener != null) {
154 mWindowStateListener.onWindowVisibilityChanged(visibility);
155 }
156 }
157
Sunny Goyal745df7c2019-04-03 15:25:00 -0700158 @Override
Tony Wickham12e8a342019-04-23 11:28:54 -0700159 protected void onLayout(boolean changed, int l, int t, int r, int b) {
160 super.onLayout(changed, l, t, r, b);
161 SYSTEM_GESTURE_EXCLUSION_RECT.get(0).set(l, t, r, b);
162 setDisallowBackGesture(mDisallowBackGesture);
163 }
164
165 @TargetApi(Build.VERSION_CODES.Q)
166 public void setDisallowBackGesture(boolean disallowBackGesture) {
167 if (!Utilities.ATLEAST_Q) {
168 return;
169 }
170 mDisallowBackGesture = disallowBackGesture;
171 setSystemGestureExclusionRects(mDisallowBackGesture
172 ? SYSTEM_GESTURE_EXCLUSION_RECT
173 : Collections.emptyList());
174 }
175
Sunny Goyal7185dd62018-03-14 17:51:49 -0700176 public interface WindowStateListener {
177
178 void onWindowFocusChanged(boolean hasFocus);
179
180 void onWindowVisibilityChanged(int visibility);
181 }
Adam Cohena6d04922014-10-23 17:28:30 -0700182}