diff options
6 files changed, 177 insertions, 6 deletions
| 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 eb7854e63a85..491959320ab7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java @@ -61,6 +61,7 @@ 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.phone.ongoingcall.OngoingCallLogger;  import com.android.systemui.statusbar.policy.RemoteInputUriController;  import com.android.systemui.tracing.ProtoTracer;  import com.android.systemui.util.DeviceConfigProxy; @@ -243,11 +244,12 @@ public interface StatusBarDependenciesModule {              SystemClock systemClock,              ActivityStarter activityStarter,              @Main Executor mainExecutor, -            IActivityManager iActivityManager) { +            IActivityManager iActivityManager, +            OngoingCallLogger logger) {          OngoingCallController ongoingCallController =                  new OngoingCallController(                          notifCollection, featureFlags, systemClock, activityStarter, mainExecutor, -                        iActivityManager); +                        iActivityManager, logger);          ongoingCallController.init();          return ongoingCallController;      } 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 2b51b56062bb..7b0d30b2409b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java @@ -325,11 +325,13 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue          // Show the ongoing call chip only if there is an ongoing call *and* notification icons          // are allowed. (The ongoing call chip occupies the same area as the notification icons,          // so if the icons are disabled then the call chip should be, too.) -        if (hasOngoingCall && !disableNotifications) { +        boolean showOngoingCallChip = hasOngoingCall && !disableNotifications; +        if (showOngoingCallChip) {              showOngoingCallChip(animate);          } else {              hideOngoingCallChip(animate);          } +        mOngoingCallController.notifyChipVisibilityChanged(showOngoingCallChip);      }      private boolean shouldHideNotificationIcons() { 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 index 6d1df5b5fa19..e9d256cc5ea8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt @@ -49,7 +49,8 @@ class OngoingCallController @Inject constructor(      private val systemClock: SystemClock,      private val activityStarter: ActivityStarter,      @Main private val mainExecutor: Executor, -    private val iActivityManager: IActivityManager +    private val iActivityManager: IActivityManager, +    private val logger: OngoingCallLogger  ) : CallbackController<OngoingCallListener> {      /** Null if there's no ongoing call. */ @@ -104,7 +105,7 @@ class OngoingCallController @Inject constructor(      /**       * Sets the chip view that will contain ongoing call information.       * -     * Should only be called from [CollapedStatusBarFragment]. +     * Should only be called from [CollapsedStatusBarFragment].       */      fun setChipView(chipView: ViewGroup) {          this.chipView = chipView @@ -113,6 +114,16 @@ class OngoingCallController @Inject constructor(          }      } + +    /** +     * Called when the chip's visibility may have changed. +     * +     * Should only be called from [CollapsedStatusBarFragment]. +     */ +    fun notifyChipVisibilityChanged(chipIsVisible: Boolean) { +        logger.logChipVisibilityChanged(chipIsVisible) +    } +      /**       * Returns true if there's an active ongoing call that should be displayed in a status bar chip.       */ @@ -150,6 +161,7 @@ class OngoingCallController @Inject constructor(              timeView.start()              currentChipView.setOnClickListener { +                logger.logChipClicked()                  activityStarter.postStartActivityDismissingKeyguard(                          currentOngoingCallInfo.intent, 0,                          ActivityLaunchAnimator.Controller.fromView(it)) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLogger.kt new file mode 100644 index 000000000000..177f21537ec9 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLogger.kt @@ -0,0 +1,58 @@ +/* + * 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 androidx.annotation.VisibleForTesting +import com.android.internal.logging.UiEvent +import com.android.internal.logging.UiEventLogger +import com.android.systemui.dagger.SysUISingleton +import javax.inject.Inject + +/** A class to log events for the ongoing call chip. */ +@SysUISingleton +class OngoingCallLogger @Inject constructor(private val logger: UiEventLogger) { + +    private var chipIsVisible: Boolean = false + +    /** Logs that the ongoing call chip was clicked. */ +    fun logChipClicked() { +        logger.log(OngoingCallEvents.ONGOING_CALL_CLICKED) +    } + +    /** +     * If needed, logs that the ongoing call chip's visibility has changed. +     * +     * For now, only logs when the chip changes from not visible to visible. +     */ +    fun logChipVisibilityChanged(chipIsVisible: Boolean) { +        if (chipIsVisible && chipIsVisible != this.chipIsVisible) { +            logger.log(OngoingCallEvents.ONGOING_CALL_VISIBLE) +        } +        this.chipIsVisible = chipIsVisible +    } + +    @VisibleForTesting +    enum class OngoingCallEvents(val metricId: Int) : UiEventLogger.UiEventEnum { +        @UiEvent(doc = "The ongoing call chip became visible") +        ONGOING_CALL_VISIBLE(813), + +        @UiEvent(doc = "The ongoing call chip was clicked") +        ONGOING_CALL_CLICKED(814); + +        override fun getId() = metricId +    } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt index 896e33073cc3..9a7ab2870905 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt @@ -29,6 +29,7 @@ import android.testing.TestableLooper  import android.view.LayoutInflater  import android.widget.LinearLayout  import androidx.test.filters.SmallTest +import com.android.internal.logging.testing.UiEventLoggerFake  import com.android.systemui.R  import com.android.systemui.SysuiTestCase  import com.android.systemui.plugins.ActivityStarter @@ -70,6 +71,7 @@ class OngoingCallControllerTest : SysuiTestCase() {      private val clock = FakeSystemClock()      private val mainExecutor = FakeExecutor(clock) +    private val uiEventLoggerFake = UiEventLoggerFake()      private lateinit var controller: OngoingCallController      private lateinit var notifCollectionListener: NotifCollectionListener @@ -99,7 +101,8 @@ class OngoingCallControllerTest : SysuiTestCase() {                  clock,                  mockActivityStarter,                  mainExecutor, -                mockIActivityManager) +                mockIActivityManager, +                OngoingCallLogger(uiEventLoggerFake))          controller.init()          controller.addCallback(mockOngoingCallListener)          controller.setChipView(chipView) @@ -256,6 +259,28 @@ class OngoingCallControllerTest : SysuiTestCase() {                  .onOngoingCallStateChanged(anyBoolean())      } +    @Test +    fun chipClicked_clickEventLogged() { +        notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry()) + +        chipView.performClick() + +        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1) +        assertThat(uiEventLoggerFake.eventId(0)) +                .isEqualTo(OngoingCallLogger.OngoingCallEvents.ONGOING_CALL_CLICKED.id) +    } + +    @Test +    fun notifyChipVisibilityChanged_visibleEventLogged() { +        controller.notifyChipVisibilityChanged(true) + +        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1) +        assertThat(uiEventLoggerFake.eventId(0)) +                .isEqualTo(OngoingCallLogger.OngoingCallEvents.ONGOING_CALL_VISIBLE.id) +    } +    // Other tests for notifyChipVisibilityChanged are in [OngoingCallLogger], since +    // [OngoingCallController.notifyChipVisibilityChanged] just delegates to that class. +      private fun createOngoingCallNotifEntry(): NotificationEntry {          val notificationEntryBuilder = NotificationEntryBuilder()          notificationEntryBuilder.modifyNotification(context).style = ongoingCallStyle diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLoggerTest.kt new file mode 100644 index 000000000000..ecec124e83e2 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLoggerTest.kt @@ -0,0 +1,72 @@ +/* + * 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 androidx.test.filters.SmallTest +import com.android.internal.logging.testing.UiEventLoggerFake +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import org.junit.Test + +@SmallTest +class OngoingCallLoggerTest : SysuiTestCase() { +    private val uiEventLoggerFake = UiEventLoggerFake() +    private val ongoingCallLogger = OngoingCallLogger(uiEventLoggerFake) + +    @Test +    fun logChipClicked_clickEventLogged() { +        ongoingCallLogger.logChipClicked() + +        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1) +        assertThat(uiEventLoggerFake.eventId(0)) +                .isEqualTo(OngoingCallLogger.OngoingCallEvents.ONGOING_CALL_CLICKED.id) +    } + +    @Test +    fun logChipVisibilityChanged_changeFromInvisibleToVisible_visibleEventLogged() { +        ongoingCallLogger.logChipVisibilityChanged(false) +        ongoingCallLogger.logChipVisibilityChanged(true) + +        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1) +        assertThat(uiEventLoggerFake.eventId(0)) +                .isEqualTo(OngoingCallLogger.OngoingCallEvents.ONGOING_CALL_VISIBLE.id) +    } + +    @Test +    fun logChipVisibilityChanged_changeFromVisibleToInvisible_eventNotLogged() { +        // Setting the chip to visible here will trigger a log +        ongoingCallLogger.logChipVisibilityChanged(true) +        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1) + +        ongoingCallLogger.logChipVisibilityChanged(false) + +        // Expect that there were no new logs +        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1) +    } + +    @Test +    fun logChipVisibilityChanged_visibleThenVisibleAgain_eventNotLogged() { +        // Setting the chip to visible here will trigger a log +        ongoingCallLogger.logChipVisibilityChanged(true) +        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1) + +        ongoingCallLogger.logChipVisibilityChanged(true) + +        // Expect that there were no new logs +        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1) +    } +} |