summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/res/values/colors.xml2
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java75
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java115
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/HandleView.java42
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleViewTest.java67
6 files changed, 233 insertions, 74 deletions
diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml
index 171a6b2fe5fb..6f8a7666e5a8 100644
--- a/libs/WindowManager/Shell/res/values/colors.xml
+++ b/libs/WindowManager/Shell/res/values/colors.xml
@@ -30,6 +30,8 @@
<color name="bubbles_light">#FFFFFF</color>
<color name="bubbles_dark">@color/GM2_grey_800</color>
<color name="bubbles_icon_tint">@color/GM2_grey_700</color>
+ <color name="bubble_bar_expanded_view_handle_light">#EBffffff</color>
+ <color name="bubble_bar_expanded_view_handle_dark">#99000000</color>
<!-- PiP -->
<color name="pip_custom_close_bg">#D93025</color>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 2be34c90a661..aa05179ed113 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -229,7 +229,11 @@
<!-- Size of the bubble bar (height), should match transient_taskbar_size in Launcher. -->
<dimen name="bubblebar_size">72dp</dimen>
<!-- The size of the drag handle / menu shown along with a bubble bar expanded view. -->
- <dimen name="bubblebar_expanded_view_menu_size">16dp</dimen>
+ <dimen name="bubble_bar_expanded_view_handle_size">40dp</dimen>
+ <!-- The width of the drag handle shown along with a bubble bar expanded view. -->
+ <dimen name="bubble_bar_expanded_view_handle_width">128dp</dimen>
+ <!-- The height of the drag handle shown along with a bubble bar expanded view. -->
+ <dimen name="bubble_bar_expanded_view_handle_height">4dp</dimen>
<!-- Bottom and end margin for compat buttons. -->
<dimen name="compat_button_margin">24dp</dimen>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
index b8f049becb6f..da1a5572e53b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
@@ -16,6 +16,8 @@
package com.android.wm.shell.bubbles.bar;
+import android.annotation.ColorInt;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.TypedArray;
@@ -46,10 +48,10 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
private BubbleController mController;
private BubbleTaskViewHelper mBubbleTaskViewHelper;
- private HandleView mMenuView;
- private TaskView mTaskView;
+ private BubbleBarHandleView mHandleView = new BubbleBarHandleView(getContext());
+ private @Nullable TaskView mTaskView;
- private int mMenuHeight;
+ private int mHandleHeight;
private int mBackgroundColor;
private float mCornerRadius = 0f;
@@ -83,11 +85,9 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
super.onFinishInflate();
Context context = getContext();
setElevation(getResources().getDimensionPixelSize(R.dimen.bubble_elevation));
- mMenuHeight = context.getResources().getDimensionPixelSize(
- R.dimen.bubblebar_expanded_view_menu_size);
- mMenuView = new HandleView(context);
- addView(mMenuView);
-
+ mHandleHeight = context.getResources().getDimensionPixelSize(
+ R.dimen.bubble_bar_expanded_view_handle_size);
+ addView(mHandleView);
applyThemeAttrs();
setClipToOutline(true);
setOutlineProvider(new ViewOutlineProvider() {
@@ -114,7 +114,7 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
void applyThemeAttrs() {
boolean supportsRoundedCorners = ScreenDecorationsUtils.supportsRoundedCornersOnWindows(
mContext.getResources());
- final TypedArray ta = mContext.obtainStyledAttributes(new int[] {
+ final TypedArray ta = mContext.obtainStyledAttributes(new int[]{
android.R.attr.dialogCornerRadius,
android.R.attr.colorBackgroundFloating});
mCornerRadius = supportsRoundedCorners ? ta.getDimensionPixelSize(0, 0) : 0;
@@ -123,14 +123,12 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
ta.recycle();
- mMenuView.setCornerRadius(mCornerRadius);
- mMenuHeight = getResources().getDimensionPixelSize(
- R.dimen.bubblebar_expanded_view_menu_size);
+ mHandleHeight = getResources().getDimensionPixelSize(
+ R.dimen.bubble_bar_expanded_view_handle_size);
if (mTaskView != null) {
mTaskView.setCornerRadius(mCornerRadius);
- mTaskView.setElevation(150);
- updateMenuColor();
+ updateHandleAndBackgroundColor(true /* animated */);
}
}
@@ -138,10 +136,8 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
-
- // Add corner radius here so that the menu extends behind the rounded corners of TaskView.
- int menuViewHeight = Math.min((int) (mMenuHeight + mCornerRadius), height);
- measureChild(mMenuView, widthMeasureSpec, MeasureSpec.makeMeasureSpec(menuViewHeight,
+ int menuViewHeight = Math.min(mHandleHeight, height);
+ measureChild(mHandleView, widthMeasureSpec, MeasureSpec.makeMeasureSpec(menuViewHeight,
MeasureSpec.getMode(heightMeasureSpec)));
if (mTaskView != null) {
@@ -153,12 +149,12 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
// Drag handle above
- final int dragHandleBottom = t + mMenuView.getMeasuredHeight();
- mMenuView.layout(l, t, r, dragHandleBottom);
+ final int dragHandleBottom = t + mHandleView.getMeasuredHeight();
+ mHandleView.layout(l, t, r, dragHandleBottom);
if (mTaskView != null) {
- // Subtract radius so that the menu extends behind the rounded corners of TaskView.
- mTaskView.layout(l, (int) (dragHandleBottom - mCornerRadius), r,
+ mTaskView.layout(l, dragHandleBottom, r,
dragHandleBottom + mTaskView.getMeasuredHeight());
}
}
@@ -166,7 +162,7 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
@Override
public void onTaskCreated() {
setContentVisibility(true);
- updateMenuColor();
+ updateHandleAndBackgroundColor(false /* animated */);
}
@Override
@@ -218,16 +214,33 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
}
}
- /** Updates the menu bar to be the status bar color specified by the app. */
- private void updateMenuColor() {
+ /**
+ * Updates the background color to match with task view status/bg color, and sets handle color
+ * to contrast with the background
+ */
+ private void updateHandleAndBackgroundColor(boolean animated) {
if (mTaskView == null) return;
- ActivityManager.RunningTaskInfo info = mTaskView.getTaskInfo();
- final int taskBgColor = info.taskDescription.getStatusBarColor();
- final int color = Color.valueOf(taskBgColor == -1 ? Color.WHITE : taskBgColor).toArgb();
- if (color != -1) {
- mMenuView.setBackgroundColor(color);
+ final int color = getTaskViewColor();
+ final boolean isRegionDark = Color.luminance(color) <= 0.5;
+ mHandleView.updateHandleColor(isRegionDark, animated);
+ setBackgroundColor(color);
+ }
+
+ /**
+ * Retrieves task view status/nav bar color or background if available
+ *
+ * TODO (b/283075226): Update with color sampling when
+ * RegionSamplingHelper or alternative is available
+ */
+ private @ColorInt int getTaskViewColor() {
+ if (mTaskView == null || mTaskView.getTaskInfo() == null) return mBackgroundColor;
+ ActivityManager.TaskDescription taskDescription = mTaskView.getTaskInfo().taskDescription;
+ if (taskDescription.getStatusBarColor() != Color.TRANSPARENT) {
+ return taskDescription.getStatusBarColor();
+ } else if (taskDescription.getBackgroundColor() != Color.TRANSPARENT) {
+ return taskDescription.getBackgroundColor();
} else {
- mMenuView.setBackgroundColor(mBackgroundColor);
+ return mBackgroundColor;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
new file mode 100644
index 000000000000..e121aa45469d
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.bubbles.bar;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Outline;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+
+import androidx.annotation.ColorInt;
+import androidx.core.content.ContextCompat;
+
+import com.android.wm.shell.R;
+
+/**
+ * Handle view to show at the top of a bubble bar expanded view.
+ */
+public class BubbleBarHandleView extends View {
+ private static final long COLOR_CHANGE_DURATION = 120;
+
+ private final int mHandleWidth;
+ private final int mHandleHeight;
+ private final @ColorInt int mHandleLightColor;
+ private final @ColorInt int mHandleDarkColor;
+ private @Nullable ObjectAnimator mColorChangeAnim;
+
+ public BubbleBarHandleView(Context context) {
+ this(context, null);
+ }
+
+ public BubbleBarHandleView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public BubbleBarHandleView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public BubbleBarHandleView(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ Resources resources = context.getResources();
+ mHandleWidth = resources.getDimensionPixelSize(
+ R.dimen.bubble_bar_expanded_view_handle_width);
+ mHandleHeight = resources.getDimensionPixelSize(
+ R.dimen.bubble_bar_expanded_view_handle_height);
+ mHandleLightColor = ContextCompat.getColor(context,
+ R.color.bubble_bar_expanded_view_handle_light);
+ mHandleDarkColor = ContextCompat.getColor(context,
+ R.color.bubble_bar_expanded_view_handle_dark);
+
+ setClipToOutline(true);
+ setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ final int handleCenterX = view.getWidth() / 2;
+ final int handleCenterY = view.getHeight() / 2;
+ final float handleRadius = mHandleHeight / 2f;
+ Rect handleBounds = new Rect(
+ handleCenterX - mHandleWidth / 2,
+ handleCenterY - mHandleHeight / 2,
+ handleCenterX + mHandleWidth / 2,
+ handleCenterY + mHandleHeight / 2);
+ outline.setRoundRect(handleBounds, handleRadius);
+ }
+ });
+ }
+
+ /**
+ * Updates the handle color.
+ *
+ * @param isRegionDark Whether the background behind the handle is dark, and thus the handle
+ * should be light (and vice versa).
+ * @param animated Whether to animate the change, or apply it immediately.
+ */
+ public void updateHandleColor(boolean isRegionDark, boolean animated) {
+ int newColor = isRegionDark ? mHandleLightColor : mHandleDarkColor;
+ if (mColorChangeAnim != null) {
+ mColorChangeAnim.cancel();
+ }
+ if (animated) {
+ mColorChangeAnim = ObjectAnimator.ofArgb(this, "backgroundColor", newColor);
+ mColorChangeAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mColorChangeAnim = null;
+ }
+ });
+ mColorChangeAnim.setDuration(COLOR_CHANGE_DURATION);
+ mColorChangeAnim.start();
+ } else {
+ setBackgroundColor(newColor);
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/HandleView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/HandleView.java
deleted file mode 100644
index 9ee8a9d98aa1..000000000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/HandleView.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.wm.shell.bubbles.bar;
-
-import android.content.Context;
-import android.view.Gravity;
-import android.widget.LinearLayout;
-
-/**
- * Handle / menu view to show at the top of a bubble bar expanded view.
- */
-public class HandleView extends LinearLayout {
-
- // TODO(b/273307221): implement the manage menu in this view.
- public HandleView(Context context) {
- super(context);
- setOrientation(LinearLayout.HORIZONTAL);
- setGravity(Gravity.CENTER);
- }
-
- /**
- * The menu extends past the top of the TaskView because of the rounded corners. This means
- * to center content in the menu we must subtract the radius (i.e. the amount of space covered
- * by TaskView).
- */
- public void setCornerRadius(float radius) {
- setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), (int) radius);
- }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleViewTest.java
new file mode 100644
index 000000000000..d38b848fbb4d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleViewTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.bubbles.bar;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.drawable.ColorDrawable;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.core.content.ContextCompat;
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class BubbleBarHandleViewTest extends ShellTestCase {
+ private BubbleBarHandleView mHandleView;
+
+ @Before
+ public void setup() {
+ mHandleView = new BubbleBarHandleView(mContext);
+ }
+
+ @Test
+ public void testUpdateHandleColor_lightBg() {
+ mHandleView.updateHandleColor(false /* isRegionDark */, false /* animated */);
+
+ assertTrue(mHandleView.getClipToOutline());
+ assertTrue(mHandleView.getBackground() instanceof ColorDrawable);
+ ColorDrawable bgDrawable = (ColorDrawable) mHandleView.getBackground();
+ assertEquals(bgDrawable.getColor(),
+ ContextCompat.getColor(mContext, R.color.bubble_bar_expanded_view_handle_dark));
+ }
+
+ @Test
+ public void testUpdateHandleColor_darkBg() {
+ mHandleView.updateHandleColor(true /* isRegionDark */, false /* animated */);
+
+ assertTrue(mHandleView.getClipToOutline());
+ assertTrue(mHandleView.getBackground() instanceof ColorDrawable);
+ ColorDrawable bgDrawable = (ColorDrawable) mHandleView.getBackground();
+ assertEquals(bgDrawable.getColor(),
+ ContextCompat.getColor(mContext, R.color.bubble_bar_expanded_view_handle_light));
+ }
+}