blob: ae0e7a7189d3e49d0bed99c124fded2a16ae66fb [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;
13import android.util.AttributeSet;
Sunny Goyal93264612015-11-23 11:47:50 -080014import android.view.View;
Sunny Goyal4ffec482016-02-09 11:28:52 -080015import android.view.ViewDebug;
Adam Cohena6d04922014-10-23 17:28:30 -070016
Jon Mirandade43a712018-01-18 11:35:10 -080017import com.android.launcher3.util.Themes;
18
Adam Cohena6d04922014-10-23 17:28:30 -070019public class LauncherRootView extends InsettableFrameLayout {
Sunny Goyal0abb36f2015-06-23 10:53:59 -070020
Sunny Goyal07b69292018-01-08 14:19:34 -080021 private final Launcher mLauncher;
22
Sunny Goyal0abb36f2015-06-23 10:53:59 -070023 private final Paint mOpaquePaint;
Sunny Goyal9001b102018-05-07 11:09:13 -070024
Sunny Goyal4ffec482016-02-09 11:28:52 -080025 @ViewDebug.ExportedProperty(category = "launcher")
Sunny Goyal9001b102018-05-07 11:09:13 -070026 private final Rect mConsumedInsets = new Rect();
Sunny Goyal0abb36f2015-06-23 10:53:59 -070027
Sunny Goyal93264612015-11-23 11:47:50 -080028 private View mAlignedView;
Sunny Goyal7185dd62018-03-14 17:51:49 -070029 private WindowStateListener mWindowStateListener;
Sunny Goyal93264612015-11-23 11:47:50 -080030
Adam Cohena6d04922014-10-23 17:28:30 -070031 public LauncherRootView(Context context, AttributeSet attrs) {
32 super(context, attrs);
Sunny Goyal0abb36f2015-06-23 10:53:59 -070033
34 mOpaquePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
35 mOpaquePaint.setColor(Color.BLACK);
36 mOpaquePaint.setStyle(Paint.Style.FILL);
Sunny Goyal07b69292018-01-08 14:19:34 -080037
38 mLauncher = Launcher.getLauncher(context);
Adam Cohena6d04922014-10-23 17:28:30 -070039 }
40
41 @Override
Sunny Goyal93264612015-11-23 11:47:50 -080042 protected void onFinishInflate() {
43 if (getChildCount() > 0) {
44 // LauncherRootView contains only one child, which should be aligned
45 // based on the horizontal insets.
46 mAlignedView = getChildAt(0);
47 }
48 super.onFinishInflate();
49 }
50
51 @TargetApi(23)
52 @Override
Adam Cohena6d04922014-10-23 17:28:30 -070053 protected boolean fitSystemWindows(Rect insets) {
Sunny Goyal9001b102018-05-07 11:09:13 -070054 mConsumedInsets.setEmpty();
55 boolean drawInsetBar = false;
56 if (mLauncher.isInMultiWindowModeCompat()
57 && (insets.left > 0 || insets.right > 0 || insets.bottom > 0)) {
58 mConsumedInsets.left = insets.left;
59 mConsumedInsets.right = insets.right;
60 mConsumedInsets.bottom = insets.bottom;
61 insets = new Rect(0, insets.top, 0, 0);
62 drawInsetBar = true;
63 } else if ((insets.right > 0 || insets.left > 0) &&
Sunny Goyal93264612015-11-23 11:47:50 -080064 (!Utilities.ATLEAST_MARSHMALLOW ||
Sunny Goyal9001b102018-05-07 11:09:13 -070065 getContext().getSystemService(ActivityManager.class).isLowRamDevice())) {
66 mConsumedInsets.left = insets.left;
67 mConsumedInsets.right = insets.right;
Sunny Goyal906c6b22017-08-18 00:35:52 -070068 insets = new Rect(0, insets.top, 0, insets.bottom);
Sunny Goyal9001b102018-05-07 11:09:13 -070069 drawInsetBar = true;
Sunny Goyal906c6b22017-08-18 00:35:52 -070070 }
Sunny Goyal9001b102018-05-07 11:09:13 -070071
Sunny Goyal07b69292018-01-08 14:19:34 -080072 mLauncher.getSystemUiController().updateUiState(
Sunny Goyal9001b102018-05-07 11:09:13 -070073 UI_STATE_ROOT_VIEW, drawInsetBar ? FLAG_DARK_NAV : 0);
Sunny Goyal93264612015-11-23 11:47:50 -080074
Sunny Goyal07b69292018-01-08 14:19:34 -080075 // Update device profile before notifying th children.
76 mLauncher.getDeviceProfile().updateInsets(insets);
Sunny Goyalce8809a2018-01-18 14:02:47 -080077 boolean resetState = !insets.equals(mInsets);
Sunny Goyal906c6b22017-08-18 00:35:52 -070078 setInsets(insets);
79
80 if (mAlignedView != null) {
Sunny Goyal9001b102018-05-07 11:09:13 -070081 // Apply margins on aligned view to handle consumed insets.
Sunny Goyal93264612015-11-23 11:47:50 -080082 MarginLayoutParams lp = (MarginLayoutParams) mAlignedView.getLayoutParams();
Sunny Goyal9001b102018-05-07 11:09:13 -070083 if (lp.leftMargin != mConsumedInsets.left || lp.rightMargin != mConsumedInsets.right ||
84 lp.bottomMargin != mConsumedInsets.bottom) {
85 lp.leftMargin = mConsumedInsets.left;
86 lp.rightMargin = mConsumedInsets.right;
87 lp.topMargin = mConsumedInsets.top;
88 lp.bottomMargin = mConsumedInsets.bottom;
Sunny Goyal93264612015-11-23 11:47:50 -080089 mAlignedView.setLayoutParams(lp);
90 }
91 }
Sunny Goyalce8809a2018-01-18 14:02:47 -080092 if (resetState) {
Sunny Goyaled2d2bc2018-04-19 12:34:43 -070093 mLauncher.getStateManager().reapplyState(true /* cancelCurrentAnimation */);
Sunny Goyalce8809a2018-01-18 14:02:47 -080094 }
Sunny Goyal0abb36f2015-06-23 10:53:59 -070095
Adam Cohena6d04922014-10-23 17:28:30 -070096 return true; // I'll take it from here
97 }
Sunny Goyal0abb36f2015-06-23 10:53:59 -070098
Jon Mirandade43a712018-01-18 11:35:10 -080099 @Override
100 public void setInsets(Rect insets) {
Sunny Goyalf8d56fc2018-01-31 15:18:11 -0800101 // If the insets haven't changed, this is a no-op. Avoid unnecessary layout caused by
102 // modifying child layout params.
103 if (!insets.equals(mInsets)) {
104 super.setInsets(insets);
105 }
Jon Mirandade43a712018-01-18 11:35:10 -0800106 setBackground(insets.top == 0 ? null
107 : Themes.getAttrDrawable(getContext(), R.attr.workspaceStatusBarScrim));
108 }
109
Sunny Goyal07b69292018-01-08 14:19:34 -0800110 public void dispatchInsets() {
Sunny Goyal34778042018-04-11 16:31:31 -0700111 mLauncher.getDeviceProfile().updateInsets(mInsets);
Sunny Goyalf8d56fc2018-01-31 15:18:11 -0800112 super.setInsets(mInsets);
Sunny Goyal07b69292018-01-08 14:19:34 -0800113 }
114
Sunny Goyal0abb36f2015-06-23 10:53:59 -0700115 @Override
116 protected void dispatchDraw(Canvas canvas) {
117 super.dispatchDraw(canvas);
118
119 // If the right inset is opaque, draw a black rectangle to ensure that is stays opaque.
Sunny Goyal9001b102018-05-07 11:09:13 -0700120 if (mConsumedInsets.right > 0) {
121 int width = getWidth();
122 canvas.drawRect(width - mConsumedInsets.right, 0, width, getHeight(), mOpaquePaint);
123 }
124 if (mConsumedInsets.left > 0) {
125 canvas.drawRect(0, 0, mConsumedInsets.left, getHeight(), mOpaquePaint);
126 }
127 if (mConsumedInsets.bottom > 0) {
128 int height = getHeight();
129 canvas.drawRect(0, height - mConsumedInsets.bottom, getWidth(), height, mOpaquePaint);
Sunny Goyal0abb36f2015-06-23 10:53:59 -0700130 }
131 }
Sunny Goyal7185dd62018-03-14 17:51:49 -0700132
133 public void setWindowStateListener(WindowStateListener listener) {
134 mWindowStateListener = listener;
135 }
136
137 @Override
138 public void onWindowFocusChanged(boolean hasWindowFocus) {
139 super.onWindowFocusChanged(hasWindowFocus);
140 if (mWindowStateListener != null) {
141 mWindowStateListener.onWindowFocusChanged(hasWindowFocus);
142 }
143 }
144
145 @Override
146 protected void onWindowVisibilityChanged(int visibility) {
147 super.onWindowVisibilityChanged(visibility);
148 if (mWindowStateListener != null) {
149 mWindowStateListener.onWindowVisibilityChanged(visibility);
150 }
151 }
152
153 public interface WindowStateListener {
154
155 void onWindowFocusChanged(boolean hasFocus);
156
157 void onWindowVisibilityChanged(int visibility);
158 }
Adam Cohena6d04922014-10-23 17:28:30 -0700159}