From 6a0fdd47e5dfa1787659ec2e933b7ceccca10463 Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Tue, 23 Mar 2021 20:05:12 +0000 Subject: [PATCH] [Ongoing Call Chip] Add feature flag + controller Bug: 183229367 Test: atest ran and manual Change-Id: I8f754f4d894999a4bd5c13db81324e9abe204747 --- core/java/android/app/Notification.java | 9 ++- packages/SystemUI/res/values/flags.xml | 2 + .../systemui/fragments/FragmentService.java | 4 ++ .../systemui/statusbar/FeatureFlags.java | 4 ++ .../dagger/StatusBarDependenciesModule.java | 14 ++++ .../NotifCollectionListener.java | 2 +- .../phone/CollapsedStatusBarFragment.java | 9 +++ .../systemui/statusbar/phone/StatusBar.java | 7 +- .../phone/dagger/StatusBarPhoneModule.java | 3 + .../ongoingcall/OngoingCallController.kt | 67 +++++++++++++++++++ .../phone/CollapsedStatusBarFragmentTest.java | 9 +++ .../statusbar/phone/StatusBarTest.java | 3 + 12 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 2fbea28f34d52..2fc019f3238e2 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -9186,9 +9186,12 @@ public class Notification implements Parcelable * */ public static class CallStyle extends Style { - private static final int CALL_TYPE_INCOMING = 1; - private static final int CALL_TYPE_ONGOING = 2; - private static final int CALL_TYPE_SCREENING = 3; + /** @hide */ + public static final int CALL_TYPE_INCOMING = 1; + /** @hide */ + public static final int CALL_TYPE_ONGOING = 2; + /** @hide */ + public static final int CALL_TYPE_SCREENING = 3; /** * This is a key used privately on the action.extras to give spacing priority diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml index 2f3fbe74d5fa6..6af982ddad728 100644 --- a/packages/SystemUI/res/values/flags.xml +++ b/packages/SystemUI/res/values/flags.xml @@ -50,4 +50,6 @@ false false + + false diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java index 0673879758ad5..37b8a2c953fe3 100644 --- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java +++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java @@ -23,6 +23,7 @@ import android.view.View; import com.android.systemui.Dumpable; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.qs.QSFragment; +import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment; import com.android.systemui.statusbar.policy.ConfigurationController; import java.io.FileDescriptor; @@ -128,6 +129,9 @@ public class FragmentService implements Dumpable { * Inject a QSFragment. */ QSFragment createQSFragment(); + + /** Inject a CollapsedStatusBarFragment. */ + CollapsedStatusBarFragment createCollapsedStatusBarFragment(); } private class FragmentHostState { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java index 90c3dfcee5bf0..b937dad269e94 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java @@ -98,4 +98,8 @@ public class FeatureFlags { public boolean isChargingRippleEnabled() { return mFlagReader.isEnabled(R.bool.flag_charging_ripple); } + + public boolean isOngoingCallStatusBarChipEnabled() { + return mFlagReader.isEnabled(R.bool.flag_ongoing_call_status_bar_chip); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java index efd0519d6608d..14c73b5cbb4c9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java @@ -49,6 +49,7 @@ import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.inflation.LowPriorityInflationHelper; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; +import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.ManagedProfileController; @@ -57,6 +58,7 @@ import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl; import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback; +import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import com.android.systemui.statusbar.policy.RemoteInputUriController; import com.android.systemui.tracing.ProtoTracer; import com.android.systemui.util.DeviceConfigProxy; @@ -226,4 +228,16 @@ public interface StatusBarDependenciesModule { @Binds StatusBarIconController provideStatusBarIconController( StatusBarIconControllerImpl controllerImpl); + + /** + */ + @Provides + @SysUISingleton + static OngoingCallController provideOngoingCallController( + CommonNotifCollection notifCollection, FeatureFlags featureFlags) { + OngoingCallController ongoingCallController = + new OngoingCallController(notifCollection, featureFlags); + ongoingCallController.init(); + return ongoingCallController; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionListener.java index 75d772e8a1c51..db0c1745f5657 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionListener.java @@ -57,7 +57,7 @@ public interface NotifCollectionListener { * Called whenever a notification with the same key as an existing notification is posted. By * the time this listener is called, the entry's SBN and Ranking will already have been updated. */ - default void onEntryUpdated(NotificationEntry entry) { + default void onEntryUpdated(@NonNull NotificationEntry entry) { } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java index 562d0ec06a633..d257b51b6770e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java @@ -37,6 +37,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager; +import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import com.android.systemui.statusbar.policy.EncryptionHelper; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.NetworkController; @@ -45,6 +46,8 @@ import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; + /** * Contains the collapsed status bar and handles hiding/showing based on disable flags * and keyguard state. Also manages lifecycle to make sure the views it contains are being @@ -72,6 +75,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue private DarkIconManager mDarkIconManager; private View mOperatorNameFrame; private CommandQueue mCommandQueue; + private OngoingCallController mOngoingCallController; private List mBlockedIcons = new ArrayList<>(); @@ -82,6 +86,11 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue } }; + @Inject + public CollapsedStatusBarFragment(OngoingCallController ongoingCallController) { + mOngoingCallController = ongoingCallController; + } + @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index d581c4b6f9b78..006e8bc90cfc4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -224,6 +224,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.phone.dagger.StatusBarComponent; import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule; +import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BrightnessMirrorController; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -423,6 +424,7 @@ public class StatusBar extends SystemUI implements DemoMode, private final DismissCallbackRegistry mDismissCallbackRegistry; private final DemoModeController mDemoModeController; private NotificationsController mNotificationsController; + private final OngoingCallController mOngoingCallController; // expanded notifications // the sliding/resizing panel within the notification window @@ -787,6 +789,7 @@ public class StatusBar extends SystemUI implements DemoMode, NotificationIconAreaController notificationIconAreaController, BrightnessSlider.Factory brightnessSliderFactory, WiredChargingRippleController chargingRippleAnimationController, + OngoingCallController ongoingCallController, FeatureFlags featureFlags) { super(context); mNotificationsController = notificationsController; @@ -866,6 +869,7 @@ public class StatusBar extends SystemUI implements DemoMode, mNotificationIconAreaController = notificationIconAreaController; mBrightnessSliderFactory = brightnessSliderFactory; mChargingRippleAnimationController = chargingRippleAnimationController; + mOngoingCallController = ongoingCallController; mFeatureFlags = featureFlags; mExpansionChangedListeners = new ArrayList<>(); @@ -1152,7 +1156,8 @@ public class StatusBar extends SystemUI implements DemoMode, checkBarModes(); }).getFragmentManager() .beginTransaction() - .replace(R.id.status_bar_container, new CollapsedStatusBarFragment(), + .replace(R.id.status_bar_container, + new CollapsedStatusBarFragment(mOngoingCallController), CollapsedStatusBarFragment.TAG) .commit(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java index 4f32712e81fa2..785d98ccd8dc9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java @@ -90,6 +90,7 @@ import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter; import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager; +import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; @@ -206,6 +207,7 @@ public interface StatusBarPhoneModule { NotificationIconAreaController notificationIconAreaController, BrightnessSlider.Factory brightnessSliderFactory, WiredChargingRippleController chargingRippleAnimationController, + OngoingCallController ongoingCallController, FeatureFlags featureFlags) { return new StatusBar( context, @@ -288,6 +290,7 @@ public interface StatusBarPhoneModule { notificationIconAreaController, brightnessSliderFactory, chargingRippleAnimationController, + ongoingCallController, featureFlags); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt new file mode 100644 index 0000000000000..60d3ea3a70937 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2021 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.systemui.statusbar.phone.ongoingcall + +import android.app.Notification +import android.app.Notification.CallStyle.CALL_TYPE_ONGOING +import android.util.Log +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.statusbar.FeatureFlags +import com.android.systemui.statusbar.notification.collection.NotificationEntry +import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection +import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener +import javax.inject.Inject + +/** + * A controller to handle the ongoing call chip in the collapsed status bar. + */ +@SysUISingleton +class OngoingCallController @Inject constructor( + private val notifCollection: CommonNotifCollection, + private val featureFlags: FeatureFlags +) { + + private val notifListener = object : NotifCollectionListener { + override fun onEntryUpdated(entry: NotificationEntry) { + if (isOngoingCallNotification(entry) && DEBUG) { + Log.d(TAG, "Ongoing call notification updated") + } + } + + override fun onEntryRemoved(entry: NotificationEntry, reason: Int) { + if (isOngoingCallNotification(entry) && DEBUG) { + Log.d(TAG, "Ongoing call notification removed") + } + } + } + + fun init() { + if (featureFlags.isOngoingCallStatusBarChipEnabled) { + notifCollection.addCollectionListener(notifListener) + } + } +} + +private fun isOngoingCallNotification(entry: NotificationEntry): Boolean { + val extras = entry.sbn.notification.extras + val callStyleTemplateName = Notification.CallStyle::class.java.name + return extras.getString(Notification.EXTRA_TEMPLATE) == callStyleTemplateName && + extras.getInt(Notification.EXTRA_CALL_TYPE, -1) == CALL_TYPE_ONGOING +} + +private const val TAG = "OngoingCallController" +private val DEBUG = Log.isLoggable(TAG, Log.DEBUG) 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 781f875fd8682..96cdaf98d964b 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 @@ -23,7 +23,10 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.when; +import android.app.Fragment; import android.app.StatusBarManager; +import android.content.Context; +import android.os.Bundle; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; import android.view.View; @@ -34,6 +37,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.R; import com.android.systemui.SysuiBaseFragmentTest; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import org.junit.Before; import org.junit.Test; @@ -157,4 +161,9 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { Mockito.verify(mStatusBarStateController).isDozing(); Mockito.verify(mNotificationAreaInner, atLeast(1)).setVisibility(eq(View.VISIBLE)); } + + @Override + protected Fragment instantiate(Context context, String className, Bundle arguments) { + return new CollapsedStatusBarFragment(mock(OngoingCallController.class)); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java index 781cde6c48b5a..2576d958b5fc3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java @@ -132,6 +132,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationListContain import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.phone.dagger.StatusBarComponent; +import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; @@ -263,6 +264,7 @@ public class StatusBarTest extends SysuiTestCase { @Mock private Lazy mNotificationShadeDepthControllerLazy; @Mock private BrightnessSlider.Factory mBrightnessSliderFactory; @Mock private WiredChargingRippleController mWiredChargingRippleController; + @Mock private OngoingCallController mOngoingCallController; @Mock private FeatureFlags mFeatureFlags; private ShadeController mShadeController; private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); @@ -427,6 +429,7 @@ public class StatusBarTest extends SysuiTestCase { mNotificationIconAreaController, mBrightnessSliderFactory, mWiredChargingRippleController, + mOngoingCallController, mFeatureFlags); when(mNotificationShadeWindowView.findViewById(R.id.lock_icon_container)).thenReturn(