summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mady Mellor <madym@google.com> 2019-02-22 22:30:05 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-02-22 22:30:05 +0000
commit01dd1a233ddae45ef8731ca1d50ea0349910aa6c (patch)
treed6dc3e217d21e47c71bee401ad6ab651526c9b97
parent8e8180a66a6d3e16789666edcc0f20b662e0d825 (diff)
parent44ee2fec72daf8cdea8a3f5c7f6e74a54cb663f4 (diff)
Merge "Allow bubbles to be displayed at the bottom of the screen"
-rw-r--r--packages/SystemUI/res/layout/bubble_permission_view.xml2
-rw-r--r--packages/SystemUI/res/values/dimens.xml4
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java51
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java6
7 files changed, 135 insertions, 22 deletions
diff --git a/packages/SystemUI/res/layout/bubble_permission_view.xml b/packages/SystemUI/res/layout/bubble_permission_view.xml
index 7fbb78a6feee..c9d8a9128d7c 100644
--- a/packages/SystemUI/res/layout/bubble_permission_view.xml
+++ b/packages/SystemUI/res/layout/bubble_permission_view.xml
@@ -17,7 +17,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="@dimen/bubble_permission_height"
android:animateLayoutChanges="true"
android:orientation="vertical"
android:paddingStart="@dimen/bubble_expanded_header_horizontal_padding"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1f6e3c2ff876..536bc4edf341 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1045,4 +1045,8 @@
<dimen name="bubble_header_icon_size">48dp</dimen>
<!-- Size of the app icon shown in the bubble permission view -->
<dimen name="bubble_permission_icon_size">24dp</dimen>
+ <!-- Space between the pointer triangle and the bubble expanded view -->
+ <dimen name="bubble_pointer_margin">8dp</dimen>
+ <!-- Height of the permission prompt shown with bubbles -->
+ <dimen name="bubble_permission_height">120dp</dimen>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 4eea9f883f81..471619e897c5 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -80,16 +80,21 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe
// Enables some subset of notifs to automatically become bubbles
private static final boolean DEBUG_ENABLE_AUTO_BUBBLE = false;
- // Secure settings flags
- // Feature level flag
+ /** Flag to enable or disable the entire feature */
private static final String ENABLE_BUBBLES = "experiment_enable_bubbles";
- // Auto bubble flags set whether different notification types should be presented as a bubble
+ /** Auto bubble flags set whether different notif types should be presented as a bubble */
private static final String ENABLE_AUTO_BUBBLE_MESSAGES = "experiment_autobubble_messaging";
private static final String ENABLE_AUTO_BUBBLE_ONGOING = "experiment_autobubble_ongoing";
private static final String ENABLE_AUTO_BUBBLE_ALL = "experiment_autobubble_all";
- // Use an activity view for an auto-bubbled notification if it has an appropriate content intent
+
+ /** Use an activityView for an auto-bubbled notifs if it has an appropriate content intent */
private static final String ENABLE_BUBBLE_CONTENT_INTENT = "experiment_bubble_content_intent";
+ /** Whether the row of bubble circles are anchored to the top or bottom of the screen. */
+ private static final String ENABLE_BUBBLES_AT_TOP = "experiment_enable_top_bubbles";
+ /** Flag to position the header below the activity view */
+ private static final String ENABLE_BUBBLE_FOOTER = "experiment_enable_bubble_footer";
+
private final Context mContext;
private final NotificationEntryManager mNotificationEntryManager;
private final IActivityTaskManager mActivityTaskManager;
@@ -548,6 +553,22 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe
ENABLE_BUBBLES, 1) != 0;
}
+ /**
+ * Whether bubbles should be positioned at the top of the screen or not.
+ */
+ public static boolean showBubblesAtTop(Context context) {
+ return Settings.Secure.getInt(context.getContentResolver(),
+ ENABLE_BUBBLES_AT_TOP, 0) != 0;
+ }
+
+ /**
+ * Whether the bubble chrome should display as a footer or not (in which case it's a header).
+ */
+ public static boolean useFooter(Context context) {
+ return Settings.Secure.getInt(context.getContentResolver(),
+ ENABLE_BUBBLE_FOOTER, 0) != 0;
+ }
+
/** PinnedStackListener that dispatches IME visibility updates to the stack. */
private class BubblesImeListener extends IPinnedStackListener.Stub {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 7884800611aa..b635033ea771 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -70,8 +70,13 @@ import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
public class BubbleExpandedView extends LinearLayout implements View.OnClickListener {
private static final String TAG = "BubbleExpandedView";
+ // Configurable via bubble settings; just for testing
+ private boolean mUseFooter;
+ private boolean mShowOnTop;
+
// The triangle pointing to the expanded view
private View mPointerView;
+ private int mPointerMargin;
// Header
private View mHeaderView;
@@ -90,6 +95,8 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
private int mMinHeight;
private int mHeaderHeight;
+ private int mBubbleHeight;
+ private int mPermissionHeight;
private NotificationEntry mEntry;
private PackageManager mPm;
@@ -150,6 +157,7 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
mPm = context.getPackageManager();
mMinHeight = getResources().getDimensionPixelSize(
R.dimen.bubble_expanded_default_height);
+ mPointerMargin = getResources().getDimensionPixelSize(R.dimen.bubble_pointer_margin);
try {
mNotificationManagerService = INotificationManager.Stub.asInterface(
ServiceManager.getServiceOrThrow(Context.NOTIFICATION_SERVICE));
@@ -172,8 +180,11 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
int bgColor = ta.getColor(0, Color.WHITE);
ta.recycle();
+ mShowOnTop = BubbleController.showBubblesAtTop(getContext());
+ mUseFooter = BubbleController.useFooter(getContext());
+
ShapeDrawable triangleDrawable = new ShapeDrawable(
- TriangleShape.create(width, height, true /* pointUp */));
+ TriangleShape.create(width, height, mShowOnTop /* pointUp */));
triangleDrawable.setTint(bgColor);
mPointerView.setBackground(triangleDrawable);
@@ -195,6 +206,8 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
mHeaderHeight = getContext().getResources().getDimensionPixelSize(
R.dimen.bubble_expanded_header_height);
+ mPermissionHeight = getContext().getResources().getDimensionPixelSize(
+ R.dimen.bubble_permission_height);
mHeaderView = findViewById(R.id.header_layout);
mDeepLinkIcon = findViewById(R.id.deep_link_button);
mSettingsIcon = findViewById(R.id.settings_button);
@@ -226,6 +239,15 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
activityView.setForwardedInsets(Insets.of(0, 0, 0, insetsBottom));
return view.onApplyWindowInsets(insets);
});
+
+ if (!mShowOnTop) {
+ removeView(mPointerView);
+ if (mUseFooter) {
+ removeView(viewWrapper);
+ addView(viewWrapper);
+ }
+ addView(mPointerView);
+ }
}
/**
@@ -332,7 +354,11 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
// Use notification view
mNotifRow = mEntry.getRow();
- addView(mNotifRow);
+ if (mShowOnTop) {
+ addView(mNotifRow);
+ } else {
+ addView(mNotifRow, mUseFooter ? 0 : 1);
+ }
}
updateView();
}
@@ -345,6 +371,17 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
return true;
}
+ /**
+ * @return total height that the expanded view occupies.
+ */
+ int getExpandedSize() {
+ int chromeHeight = mPermissionView.getVisibility() != View.VISIBLE
+ ? mHeaderHeight
+ : mPermissionHeight;
+ return mBubbleHeight + mPointerView.getHeight() + mPointerMargin
+ + chromeHeight;
+ }
+
void updateHeight() {
if (usingActivityView()) {
Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
@@ -358,12 +395,19 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
? data.getDesiredHeight()
: mMinHeight;
}
- int max = mStackView.getMaxExpandedHeight() - mHeaderHeight;
+ int chromeHeight = mPermissionView.getVisibility() != View.VISIBLE
+ ? mHeaderHeight
+ : mPermissionHeight;
+ int max = mStackView.getMaxExpandedHeight() - chromeHeight - mPointerView.getHeight()
+ - mPointerMargin;
int height = Math.min(desiredHeight, max);
height = Math.max(height, mMinHeight);
LayoutParams lp = (LayoutParams) mActivityView.getLayoutParams();
lp.height = height;
+ mBubbleHeight = height;
mActivityView.setLayoutParams(lp);
+ } else {
+ mBubbleHeight = mNotifRow != null ? mNotifRow.getIntrinsicHeight() : mMinHeight;
}
}
@@ -412,6 +456,7 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
} else if (mOnBubbleBlockedListener != null) {
mOnBubbleBlockedListener.onBubbleBlocked(mEntry);
}
+ mStackView.onExpandedHeightChanged();
logBubbleClickEvent(mEntry.notification,
allowed ? StatsLog.BUBBLE_UICHANGED__ACTION__PERMISSION_OPT_IN :
StatsLog.BUBBLE_UICHANGED__ACTION__PERMISSION_OPT_OUT);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index e20be8e552df..167bf47664e0 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -173,7 +173,7 @@ public class BubbleStackView extends FrameLayout {
int elevation = res.getDimensionPixelSize(R.dimen.bubble_elevation);
mStackAnimationController = new StackAnimationController();
- mExpandedAnimationController = new ExpandedAnimationController();
+ mExpandedAnimationController = new ExpandedAnimationController(mDisplaySize);
mBubbleContainer = new PhysicsAnimationLayout(context);
mBubbleContainer.setMaxRenderedChildren(
@@ -513,8 +513,7 @@ public class BubbleStackView extends FrameLayout {
final float yStart = Math.min(
mStackAnimationController.getStackPosition().y,
mExpandedAnimateYDistance);
- final float yDest = getStatusBarHeight()
- + mExpandedBubble.iconView.getHeight() + mBubblePadding;
+ final float yDest = getYPositionForExpandedView();
if (shouldExpand) {
mExpandedViewContainer.setTranslationX(xStart);
@@ -668,13 +667,39 @@ public class BubbleStackView extends FrameLayout {
* y position when the bubbles are expanded as well as the bounds of the dismiss target.
*/
int getMaxExpandedHeight() {
+ boolean showOnTop = BubbleController.showBubblesAtTop(getContext());
int expandedY = (int) mExpandedAnimationController.getExpandedY();
- int bubbleContainerHeight = mBubbleContainer.getChildAt(0) != null
- ? mBubbleContainer.getChildAt(0).getHeight()
- : 0;
- // PIP dismiss view uses FLAG_LAYOUT_IN_SCREEN so we need to subtract the bottom inset
- int pipDismissHeight = mPipDismissHeight - getBottomInset();
- return mDisplaySize.y - expandedY - mBubbleSize - pipDismissHeight;
+ if (showOnTop) {
+ // PIP dismiss view uses FLAG_LAYOUT_IN_SCREEN so we need to subtract the bottom inset
+ int pipDismissHeight = mPipDismissHeight - getBottomInset();
+ return mDisplaySize.y - expandedY - mBubbleSize - pipDismissHeight;
+ } else {
+ return expandedY - getStatusBarHeight();
+ }
+ }
+
+ /**
+ * Calculates the y position of the expanded view when it is expanded.
+ */
+ float getYPositionForExpandedView() {
+ boolean showOnTop = BubbleController.showBubblesAtTop(getContext());
+ if (showOnTop) {
+ return getStatusBarHeight() + mBubbleSize + mBubblePadding;
+ } else {
+ return mExpandedAnimationController.getExpandedY()
+ - mExpandedBubble.expandedView.getExpandedSize() - mBubblePadding;
+ }
+ }
+
+ /**
+ * Called when the height of the currently expanded view has changed (not via an
+ * update to the bubble's desired height but for some other reason, e.g. permission view
+ * goes away).
+ */
+ void onExpandedHeightChanged() {
+ if (mIsExpanded) {
+ requestUpdate();
+ }
}
/**
@@ -751,6 +776,8 @@ public class BubbleStackView extends FrameLayout {
mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE);
if (mIsExpanded) {
+ final float y = getYPositionForExpandedView();
+ mExpandedViewContainer.setTranslationY(y);
mExpandedBubble.expandedView.updateView();
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
index f0d9be1e484a..f7896b0b1201 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
@@ -17,6 +17,7 @@
package com.android.systemui.bubbles.animation;
import android.content.res.Resources;
+import android.graphics.Point;
import android.graphics.PointF;
import android.view.View;
import android.view.WindowInsets;
@@ -25,6 +26,7 @@ import androidx.dynamicanimation.animation.DynamicAnimation;
import androidx.dynamicanimation.animation.SpringForce;
import com.android.systemui.R;
+import com.android.systemui.bubbles.BubbleController;
import com.google.android.collect.Sets;
@@ -61,6 +63,14 @@ public class ExpandedAnimationController
private float mBubbleSizePx;
/** Height of the status bar. */
private float mStatusBarHeight;
+ /** Size of display. */
+ private Point mDisplaySize;
+ /** Size of dismiss target at bottom of screen. */
+ private float mPipDismissHeight;
+
+ public ExpandedAnimationController(Point displaySize) {
+ mDisplaySize = displaySize;
+ }
/**
* Whether the individual bubble has been dragged out of the row of bubbles far enough to cause
@@ -88,6 +98,7 @@ public class ExpandedAnimationController
mBubbleSizePx = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
mStatusBarHeight =
res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
+ mPipDismissHeight = res.getDimensionPixelSize(R.dimen.pip_dismiss_gradient_height);
}
/**
@@ -204,16 +215,19 @@ public class ExpandedAnimationController
/** The Y value of the row of expanded bubbles. */
public float getExpandedY() {
+ boolean showOnTop = mLayout != null
+ && BubbleController.showBubblesAtTop(mLayout.getContext());
final WindowInsets insets = mLayout != null ? mLayout.getRootWindowInsets() : null;
- if (insets != null) {
+ if (showOnTop && insets != null) {
return mBubblePaddingPx + Math.max(
mStatusBarHeight,
insets.getDisplayCutout() != null
? insets.getDisplayCutout().getSafeInsetTop()
: 0);
+ } else {
+ int bottomInset = insets != null ? insets.getSystemWindowInsetBottom() : 0;
+ return mDisplaySize.y - mBubbleSizePx - (mPipDismissHeight - bottomInset);
}
-
- return mBubblePaddingPx;
}
/** Runs the given Runnable after all translation-related animations have ended. */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java
index 3bd582f955af..b4059c5db3b6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java
@@ -19,6 +19,7 @@ package com.android.systemui.bubbles.animation;
import static org.junit.Assert.assertEquals;
import android.content.res.Resources;
+import android.graphics.Point;
import android.graphics.PointF;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
@@ -40,7 +41,8 @@ import org.mockito.Spy;
public class ExpandedAnimationControllerTest extends PhysicsAnimationLayoutTestCase {
@Spy
- private ExpandedAnimationController mExpandedController = new ExpandedAnimationController();
+ private ExpandedAnimationController mExpandedController =
+ new ExpandedAnimationController(new Point(500, 1000) /* displaySize */);
private int mStackOffset;
private float mBubblePadding;
@@ -167,7 +169,7 @@ public class ExpandedAnimationControllerTest extends PhysicsAnimationLayoutTestC
assertEquals(mBubblePadding + (i * (mBubbleSize + mBubblePadding)),
mLayout.getChildAt(i).getTranslationX(),
2f);
- assertEquals(mBubblePadding + mCutoutInsetSize,
+ assertEquals(mExpandedController.getExpandedY(),
mLayout.getChildAt(i).getTranslationY(), 2f);
if (i < mMaxRenderedBubbles) {