Loading packages/SystemUI/res/layout/bubble_permission_view.xml +1 −1 Original line number Diff line number Diff line Loading @@ -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" Loading packages/SystemUI/res/values/dimens.xml +4 −0 Original line number Diff line number Diff line Loading @@ -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> packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +25 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 { Loading packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +48 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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)); Loading @@ -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); Loading @@ -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); Loading Loading @@ -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); } } /** Loading Loading @@ -332,7 +354,11 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList // Use notification view mNotifRow = mEntry.getRow(); if (mShowOnTop) { addView(mNotifRow); } else { addView(mNotifRow, mUseFooter ? 0 : 1); } } updateView(); } Loading @@ -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(); Loading @@ -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; } } Loading Loading @@ -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); Loading packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +36 −9 Original line number Diff line number Diff line Loading @@ -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( Loading Loading @@ -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); Loading Loading @@ -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; 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(); } } /** Loading Loading @@ -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(); } Loading Loading
packages/SystemUI/res/layout/bubble_permission_view.xml +1 −1 Original line number Diff line number Diff line Loading @@ -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" Loading
packages/SystemUI/res/values/dimens.xml +4 −0 Original line number Diff line number Diff line Loading @@ -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>
packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +25 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 { Loading
packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +48 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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)); Loading @@ -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); Loading @@ -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); Loading Loading @@ -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); } } /** Loading Loading @@ -332,7 +354,11 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList // Use notification view mNotifRow = mEntry.getRow(); if (mShowOnTop) { addView(mNotifRow); } else { addView(mNotifRow, mUseFooter ? 0 : 1); } } updateView(); } Loading @@ -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(); Loading @@ -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; } } Loading Loading @@ -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); Loading
packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +36 −9 Original line number Diff line number Diff line Loading @@ -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( Loading Loading @@ -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); Loading Loading @@ -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; 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(); } } /** Loading Loading @@ -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(); } Loading