diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java index bc6547f6898fe..2cbd788d0a304 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java @@ -58,6 +58,7 @@ public interface SensorManagerPlugin extends Plugin { public static final int TYPE_WAKE_LOCK_SCREEN = 1; public static final int TYPE_WAKE_DISPLAY = 2; public static final int TYPE_SWIPE = 3; + public static final int TYPE_STATUS = 4; private int mType; diff --git a/packages/SystemUI/res/layout/center_icon_area.xml b/packages/SystemUI/res/layout/center_icon_area.xml new file mode 100644 index 0000000000000..21279e12fb4a6 --- /dev/null +++ b/packages/SystemUI/res/layout/center_icon_area.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml index 7a43c6d2051b5..4fae3c500a456 100644 --- a/packages/SystemUI/res/layout/status_bar.xml +++ b/packages/SystemUI/res/layout/status_bar.xml @@ -102,6 +102,14 @@ android:gravity="center_horizontal|center_vertical" /> + + updateIsolatedIconLocation(true /* requireUpdate */)); mStackScroller = stackScroller; @@ -238,11 +242,17 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener, mHeadsUpStatusBarView.setVisibility(View.VISIBLE); show(mHeadsUpStatusBarView); hide(mClockView, View.INVISIBLE); + if (mCenteredIconView.getVisibility() != View.GONE) { + hide(mCenteredIconView, View.INVISIBLE); + } if (mOperatorNameView != null) { hide(mOperatorNameView, View.INVISIBLE); } } else { show(mClockView); + if (mCenteredIconView.getVisibility() != View.GONE) { + show(mCenteredIconView); + } if (mOperatorNameView != null) { show(mOperatorNameView); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java index 02ee2433d251d..bb490f52b045f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java @@ -33,6 +33,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import java.util.ArrayList; +import java.util.Objects; import java.util.function.Function; /** @@ -66,11 +67,15 @@ public class NotificationIconAreaController implements DarkReceiver, private int mIconSize; private int mIconHPadding; private int mIconTint = Color.WHITE; + private int mCenteredIconTint = Color.WHITE; private StatusBar mStatusBar; protected View mNotificationIconArea; private NotificationIconContainer mNotificationIcons; private NotificationIconContainer mShelfIcons; + protected View mCenteredIconArea; + private NotificationIconContainer mCenteredIcon; + private StatusBarIconView mCenteredIconView; private final Rect mTintArea = new Rect(); private ViewGroup mNotificationScrollLayout; private Context mContext; @@ -124,6 +129,9 @@ public class NotificationIconAreaController implements DarkReceiver, mNotificationIcons = mNotificationIconArea.findViewById(R.id.notificationIcons); mNotificationScrollLayout = mStatusBar.getNotificationScrollLayout(); + + mCenteredIconArea = layoutInflater.inflate(R.layout.center_icon_area, null); + mCenteredIcon = mCenteredIconArea.findViewById(R.id.centeredIcon); } public void setupShelf(NotificationShelf shelf) { @@ -142,6 +150,10 @@ public class NotificationIconAreaController implements DarkReceiver, View child = mShelfIcons.getChildAt(i); child.setLayoutParams(params); } + for (int i = 0; i < mCenteredIcon.getChildCount(); i++) { + View child = mCenteredIcon.getChildAt(i); + child.setLayoutParams(params); + } } @NonNull @@ -166,6 +178,13 @@ public class NotificationIconAreaController implements DarkReceiver, return mNotificationIconArea; } + /** + * Returns the view that represents the centered notification area. + */ + public View getCenteredNotificationAreaView() { + return mCenteredIconArea; + } + /** * See {@link com.android.systemui.statusbar.policy.DarkIconDispatcher#setIconsDarkArea}. * Sets the color that should be used to tint any icons in the notification area. @@ -179,6 +198,7 @@ public class NotificationIconAreaController implements DarkReceiver, } else { mTintArea.set(tintArea); } + if (mNotificationIconArea != null) { if (DarkIconDispatcher.isInArea(tintArea, mNotificationIconArea)) { mIconTint = iconTint; @@ -187,6 +207,14 @@ public class NotificationIconAreaController implements DarkReceiver, mIconTint = iconTint; } + if (mCenteredIconArea != null) { + if (DarkIconDispatcher.isInArea(tintArea, mCenteredIconArea)) { + mCenteredIconTint = iconTint; + } + } else { + mCenteredIconTint = iconTint; + } + applyNotificationIconsTint(); } @@ -196,7 +224,13 @@ public class NotificationIconAreaController implements DarkReceiver, protected boolean shouldShowNotificationIcon(NotificationEntry entry, boolean showAmbient, boolean showLowPriority, boolean hideDismissed, - boolean hideRepliedMessages, boolean hideCurrentMedia) { + boolean hideRepliedMessages, boolean hideCurrentMedia, boolean hideCenteredIcon) { + + final boolean isCenteredNotificationIcon = entry.centeredIcon != null + && Objects.equals(entry.centeredIcon, mCenteredIconView); + if (hideCenteredIcon == isCenteredNotificationIcon) { + return false; + } if (mEntryManager.getNotificationData().isAmbient(entry.key) && !showAmbient) { return false; } @@ -229,26 +263,41 @@ public class NotificationIconAreaController implements DarkReceiver, * Updates the notifications with the given list of notifications to display. */ public void updateNotificationIcons() { - updateStatusBarIcons(); updateShelfIcons(); + updateCenterIcon(); applyNotificationIconsTint(); } private void updateShelfIcons() { updateIconsForLayout(entry -> entry.expandedIcon, mShelfIcons, - true /* showAmbient */, !mFullyDark /* showLowPriority */, - false /* hideDismissed */, mFullyDark /* hideRepliedMessages */, - mFullyDark /* hideCurrentMedia */); + true /* showAmbient */, + !mFullyDark /* showLowPriority */, + false /* hideDismissed */, + mFullyDark /* hideRepliedMessages */, + mFullyDark /* hideCurrentMedia */, + true /* hide centered icon */); } public void updateStatusBarIcons() { updateIconsForLayout(entry -> entry.icon, mNotificationIcons, - false /* showAmbient */, mShowLowPriority /* showLowPriority */, + false /* showAmbient */, + mShowLowPriority /* showLowPriority */, true /* hideDismissed */, true /* hideRepliedMessages */, - false /* hideCurrentMedia */); + false /* hideCurrentMedia */, + true /* hide centered icon */); + } + + private void updateCenterIcon() { + updateIconsForLayout(entry -> entry.centeredIcon, mCenteredIcon, + false /* showAmbient */, + !mFullyDark /* showLowPriority */, + false /* hideDismissed */, + false /* hideRepliedMessages */, + mFullyDark /* hideCurrentMedia */, + false /* hide centered icon */); } @VisibleForTesting @@ -267,7 +316,8 @@ public class NotificationIconAreaController implements DarkReceiver, */ private void updateIconsForLayout(Function function, NotificationIconContainer hostLayout, boolean showAmbient, boolean showLowPriority, - boolean hideDismissed, boolean hideRepliedMessages, boolean hideCurrentMedia) { + boolean hideDismissed, boolean hideRepliedMessages, boolean hideCurrentMedia, + boolean hideCenteredIcon) { ArrayList toShow = new ArrayList<>( mNotificationScrollLayout.getChildCount()); @@ -277,8 +327,11 @@ public class NotificationIconAreaController implements DarkReceiver, if (view instanceof ExpandableNotificationRow) { NotificationEntry ent = ((ExpandableNotificationRow) view).getEntry(); if (shouldShowNotificationIcon(ent, showAmbient, showLowPriority, hideDismissed, - hideRepliedMessages, hideCurrentMedia)) { - toShow.add(function.apply(ent)); + hideRepliedMessages, hideCurrentMedia, hideCenteredIcon)) { + StatusBarIconView iconView = function.apply(ent); + if (iconView != null) { + toShow.add(iconView); + } } } } @@ -368,32 +421,54 @@ public class NotificationIconAreaController implements DarkReceiver, /** * Applies {@link #mIconTint} to the notification icons. + * Applies {@link #mCenteredIconTint} to the center notification icon. */ private void applyNotificationIconsTint() { for (int i = 0; i < mNotificationIcons.getChildCount(); i++) { final StatusBarIconView iv = (StatusBarIconView) mNotificationIcons.getChildAt(i); if (iv.getWidth() != 0) { - updateTintForIcon(iv); + updateTintForIcon(iv, mIconTint); } else { - iv.executeOnLayout(() -> updateTintForIcon(iv)); + iv.executeOnLayout(() -> updateTintForIcon(iv, mIconTint)); + } + } + + for (int i = 0; i < mCenteredIcon.getChildCount(); i++) { + final StatusBarIconView iv = (StatusBarIconView) mCenteredIcon.getChildAt(i); + if (iv.getWidth() != 0) { + updateTintForIcon(iv, mCenteredIconTint); + } else { + iv.executeOnLayout(() -> updateTintForIcon(iv, mCenteredIconTint)); } } } - private void updateTintForIcon(StatusBarIconView v) { + private void updateTintForIcon(StatusBarIconView v, int tint) { boolean isPreL = Boolean.TRUE.equals(v.getTag(R.id.icon_is_pre_L)); int color = StatusBarIconView.NO_COLOR; boolean colorize = !isPreL || NotificationUtils.isGrayscale(v, mContrastColorUtil); if (colorize) { - color = DarkIconDispatcher.getTint(mTintArea, v, mIconTint); + color = DarkIconDispatcher.getTint(mTintArea, v, tint); } v.setStaticDrawableColor(color); - v.setDecorColor(mIconTint); + v.setDecorColor(tint); } public void setDark(boolean dark) { mNotificationIcons.setDark(dark, false, 0); mShelfIcons.setDark(dark, false, 0); + mCenteredIcon.setDark(dark, false, 0); + } + + /** + * Shows the icon view given in the center. + */ + public void showIconCentered(NotificationEntry entry) { + StatusBarIconView icon = entry == null ? null : entry.centeredIcon; + if (!Objects.equals(mCenteredIconView, icon)) { + mCenteredIconView = icon; + updateNotificationIcons(); + } } public void showIconIsolated(StatusBarIconView icon, boolean animated) { @@ -415,6 +490,8 @@ public class NotificationIconAreaController implements DarkReceiver, if (mDarkAmount == 0 && !mStatusBarStateController.isDozing()) { mNotificationIcons.setTranslationX(0); mNotificationIcons.setTranslationY(0); + mCenteredIcon.setTranslationX(0); + mCenteredIcon.setTranslationY(0); return; } @@ -423,6 +500,8 @@ public class NotificationIconAreaController implements DarkReceiver, int translationY = getBurnInOffset(mBurnInOffset, false /* xAxis */) + yOffset; mNotificationIcons.setTranslationX(translationX); mNotificationIcons.setTranslationY(translationY); + mCenteredIcon.setTranslationX(translationX); + mCenteredIcon.setTranslationY(translationY); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 7a3d03fec025b..ce1d6384b7c09 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -73,6 +73,8 @@ public class PhoneStatusBarView extends PanelBar { private DarkReceiver mBattery; private int mLastOrientation; @Nullable + private View mCenterIconSpace; + @Nullable private View mCutoutSpace; @Nullable private DisplayCutout mDisplayCutout; @@ -105,6 +107,7 @@ public class PhoneStatusBarView extends PanelBar { mBarTransitions.init(); mBattery = findViewById(R.id.battery); mCutoutSpace = findViewById(R.id.cutout_space_view); + mCenterIconSpace = findViewById(R.id.centered_icon_area); updateResources(); } @@ -312,10 +315,12 @@ public class PhoneStatusBarView extends PanelBar { if (mDisplayCutout == null || mDisplayCutout.isEmpty() || mLastOrientation != ORIENTATION_PORTRAIT || cornerCutoutMargins != null) { + mCenterIconSpace.setVisibility(View.VISIBLE); mCutoutSpace.setVisibility(View.GONE); return; } + mCenterIconSpace.setVisibility(View.GONE); mCutoutSpace.setVisibility(View.VISIBLE); LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mCutoutSpace.getLayoutParams(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java index 33af96f1f13fa..88ed80ae65c49 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java @@ -49,6 +49,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { private NotificationIconAreaController mMockNotificiationAreaController; private View mNotificationAreaInner; + private View mCenteredNotificationAreaView; private StatusBarStateController mStatusBarStateController; public CollapsedStatusBarFragmentTest() { @@ -66,10 +67,14 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES); mMockNotificiationAreaController = mock(NotificationIconAreaController.class); mNotificationAreaInner = mock(View.class); + mCenteredNotificationAreaView = mock(View.class); when(statusBar.getPanel()).thenReturn(mock(NotificationPanelView.class)); when(mNotificationAreaInner.animate()).thenReturn(mock(ViewPropertyAnimator.class)); when(mMockNotificiationAreaController.getNotificationInnerAreaView()).thenReturn( mNotificationAreaInner); + when(mCenteredNotificationAreaView.animate()).thenReturn(mock(ViewPropertyAnimator.class)); + when(mMockNotificiationAreaController.getCenteredNotificationAreaView()).thenReturn( + mCenteredNotificationAreaView); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java index 44df237d70c8f..0479b4a01dc99 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java @@ -74,7 +74,8 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase { mStackScroller, mPanelView, new View(mContext), - mOperatorNameView); + mOperatorNameView, + new View(mContext)); mHeadsUpAppearanceController.setExpandedHeight(0.0f, 0.0f); } @@ -147,6 +148,7 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase { mStackScroller, mPanelView, new View(mContext), + new View(mContext), new View(mContext)); newController.readFrom(mHeadsUpAppearanceController);