Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 452a02b8 authored by Liran Binyamin's avatar Liran Binyamin
Browse files

Wire BubbleSessionTracker

Log bubble sessions to analytics.

Bug: 438484702
Flag: EXEMPT metrics
Test: atest BubbleControllerTest
Change-Id: I360dd02331281719e10a7ff343a110cfc34d620e
parent 6488ab41
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -33,12 +33,15 @@ import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.android.internal.logging.InstanceIdSequence
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.internal.protolog.ProtoLog
import com.android.internal.statusbar.IStatusBarService
import com.android.wm.shell.Flags
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.bubbles.Bubbles.SysuiProxy
import com.android.wm.shell.bubbles.logging.BubbleSessionTracker
import com.android.wm.shell.bubbles.logging.BubbleSessionTrackerImpl
import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayImeController
@@ -94,6 +97,7 @@ class BubbleControllerBubbleBarTest {
    private lateinit var bubbleData: BubbleData
    private lateinit var mainExecutor: TestShellExecutor
    private lateinit var bgExecutor: TestShellExecutor
    private lateinit var sessionTracker: BubbleSessionTracker

    @Before
    fun setUp() {
@@ -106,6 +110,9 @@ class BubbleControllerBubbleBarTest {
        uiEventLoggerFake = UiEventLoggerFake()
        val bubbleLogger = BubbleLogger(uiEventLoggerFake)

        val instanceIdSequence = InstanceIdSequence(/* instanceIdMax= */ 10)
        sessionTracker = BubbleSessionTrackerImpl(instanceIdSequence, bubbleLogger)

        val deviceConfig =
            DeviceConfig(
                windowBounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
@@ -362,7 +369,7 @@ class BubbleControllerBubbleBarTest {
        addBubble("key", autoExpand = true)

        // 2 events: add bubble + expand
        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2)
        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(3)
        assertThat(uiEventLoggerFake.eventId(1))
            .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_EXPANDED.id)
    }
@@ -544,6 +551,7 @@ class BubbleControllerBubbleBarTest {
            { Optional.empty() },
            Optional.empty(),
            { false },
            sessionTracker,
        )
    }

+74 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import androidx.core.content.getSystemService
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.android.internal.logging.InstanceIdSequence
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.internal.protolog.ProtoLog
import com.android.internal.statusbar.IStatusBarService
@@ -61,6 +62,8 @@ import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.bubbles.Bubbles.BubbleExpandListener
import com.android.wm.shell.bubbles.Bubbles.DISMISS_USER_GESTURE
import com.android.wm.shell.bubbles.Bubbles.SysuiProxy
import com.android.wm.shell.bubbles.logging.BubbleSessionTracker
import com.android.wm.shell.bubbles.logging.BubbleSessionTrackerImpl
import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayImeController
@@ -148,6 +151,7 @@ class BubbleControllerTest(flags: FlagsParameterization) {
    private lateinit var displayController: DisplayController
    private lateinit var imeListener: ImeListener
    private lateinit var bubbleTransitions: BubbleTransitions
    private lateinit var sessionTracker: BubbleSessionTracker

    private var isStayAwakeOnFold = false

@@ -172,6 +176,8 @@ class BubbleControllerTest(flags: FlagsParameterization) {
        ProtoLog.init()

        bubbleLogger = BubbleLogger(uiEventLoggerFake)
        val instanceIdSequence = InstanceIdSequence(/* instanceIdMax= */ 10)
        sessionTracker = BubbleSessionTrackerImpl(instanceIdSequence, bubbleLogger)
        eduController = BubbleEducationController(context)

        mainExecutor = TestShellExecutor()
@@ -899,6 +905,73 @@ class BubbleControllerTest(flags: FlagsParameterization) {
            .that(overflowBubble.isInflated).isFalse()
    }

    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
    @Test
    fun bubbleBarSessionTracked() {
        // switch to bubble bar
        bubblePositioner.update(deviceConfigUnfolded)
        bubblePositioner.isShowingInBubbleBar = true
        getInstrumentation().runOnMainSync {
            bubbleController.setLauncherHasBubbleBar(true)
            bubbleController.registerBubbleStateListener(FakeBubblesStateListener())
        }

        val bubble = createBubble("key")
        bubble.setShouldAutoExpand(true)
        getInstrumentation().runOnMainSync {
            bubbleController.inflateAndAdd(
                bubble,
                /* suppressFlyout= */ true,
                /* showInShade= */ true
            )
        }

        assertThat(bubbleData.isExpanded).isTrue()

        val sessionStartEvent = uiEventLoggerFake.logs.single {
            it.eventId == BubbleLogger.Event.BUBBLE_BAR_SESSION_STARTED.id
        }

        getInstrumentation().runOnMainSync {
            bubbleController.collapseStack()
            mainExecutor.flushAll()
        }

        val sessionEndEvent = uiEventLoggerFake.logs.single {
            it.eventId == BubbleLogger.Event.BUBBLE_BAR_SESSION_ENDED.id
        }
        assertThat(sessionStartEvent.instanceId).isEqualTo(sessionEndEvent.instanceId)
    }

    @Test
    fun floatingBubbleSessionTracked() {
        val bubble = createBubble("key")
        bubble.setShouldAutoExpand(true)
        getInstrumentation().runOnMainSync {
            bubbleController.inflateAndAdd(
                bubble,
                /* suppressFlyout= */ true,
                /* showInShade= */ true
            )
        }

        assertThat(bubbleData.isExpanded).isTrue()

        val sessionStartEvent = uiEventLoggerFake.logs.single {
            it.eventId == BubbleLogger.Event.BUBBLE_SESSION_STARTED.id
        }

        getInstrumentation().runOnMainSync {
            bubbleController.collapseStack()
            mainExecutor.flushAll()
        }

        val sessionEndEvent = uiEventLoggerFake.logs.single {
            it.eventId == BubbleLogger.Event.BUBBLE_SESSION_ENDED.id
        }
        assertThat(sessionStartEvent.instanceId).isEqualTo(sessionEndEvent.instanceId)
    }

    private fun createBubble(key: String, taskId: Int = 0): Bubble {
        val icon = Icon.createWithResource(context.resources, R.drawable.bubble_ic_overflow_button)
        val shortcutInfo = ShortcutInfo.Builder(context, "fakeId").setIcon(icon).build()
@@ -991,6 +1064,7 @@ class BubbleControllerTest(flags: FlagsParameterization) {
                { Optional.of(splitScreenController) },
                Optional.of(unfoldProgressProvider),
                { isStayAwakeOnFold },
                sessionTracker,
            )
        bubbleController.setInflateSynchronously(true)
        bubbleController.onInit()
+7 −0
Original line number Diff line number Diff line
@@ -30,11 +30,14 @@ import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.internal.logging.InstanceIdSequence
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.internal.protolog.ProtoLog
import com.android.internal.statusbar.IStatusBarService
import com.android.launcher3.icons.BubbleIconFactory
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.bubbles.logging.BubbleSessionTracker
import com.android.wm.shell.bubbles.logging.BubbleSessionTrackerImpl
import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayImeController
@@ -78,6 +81,7 @@ class BubbleViewInfoTaskTest {
    private lateinit var bubbleLogger: BubbleLogger
    private lateinit var expandedViewManager: BubbleExpandedViewManager
    private lateinit var appInfoProvider: FakeBubbleAppInfoProvider
    private lateinit var sessionTracker: BubbleSessionTracker

    private val bubbleTaskViewFactory = BubbleTaskViewFactory {
        BubbleTaskView(mock<TaskView>(), directExecutor())
@@ -112,6 +116,8 @@ class BubbleViewInfoTaskTest {
            )
        bubblePositioner = BubblePositioner(context, windowManager)
        bubbleLogger = BubbleLogger(UiEventLoggerFake())
        val instanceIdSequence = InstanceIdSequence(/* instanceIdMax= */ 10)
        sessionTracker = BubbleSessionTrackerImpl(instanceIdSequence, bubbleLogger)
        val bubbleData =
            BubbleData(
                context,
@@ -171,6 +177,7 @@ class BubbleViewInfoTaskTest {
                { Optional.empty() },
                Optional.empty(),
                { false },
                sessionTracker,
            )

        // TODO: (b/371829099) - when optional overflow is no longer flagged we can enable this
+8 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.android.internal.logging.InstanceIdSequence
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.internal.protolog.ProtoLog
import com.android.internal.statusbar.IStatusBarService
@@ -56,6 +57,8 @@ import com.android.wm.shell.bubbles.FakeBubbleFactory
import com.android.wm.shell.bubbles.FakeBubbleTaskViewFactory
import com.android.wm.shell.bubbles.UiEventSubject.Companion.assertThat
import com.android.wm.shell.bubbles.animation.AnimatableScaleMatrix
import com.android.wm.shell.bubbles.logging.BubbleSessionTracker
import com.android.wm.shell.bubbles.logging.BubbleSessionTrackerImpl
import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayImeController
@@ -113,6 +116,7 @@ class BubbleBarLayerViewTest {
    private lateinit var bubbleLogger: BubbleLogger
    private lateinit var testBubblesList: MutableList<Bubble>
    private lateinit var dragZoneFactory: DragZoneFactory
    private lateinit var sessionTracker: BubbleSessionTracker

    @Before
    fun setUp() {
@@ -123,6 +127,9 @@ class BubbleBarLayerViewTest {
        uiEventLoggerFake = UiEventLoggerFake()
        bubbleLogger = BubbleLogger(uiEventLoggerFake)

        val instanceIdSequence = InstanceIdSequence(/* instanceIdMax= */ 10)
        sessionTracker = BubbleSessionTrackerImpl(instanceIdSequence, bubbleLogger)

        mainExecutor = TestShellExecutor()
        bgExecutor = TestShellExecutor()

@@ -249,6 +256,7 @@ class BubbleBarLayerViewTest {
            { Optional.empty() },
            Optional.empty(),
            { false },
            sessionTracker,
        )
    }

+19 −1
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ import com.android.wm.shell.bubbles.appinfo.BubbleAppInfoProvider;
import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
import com.android.wm.shell.bubbles.fold.BubblesFoldLockSettingsObserver;
import com.android.wm.shell.bubbles.fold.BubblesUnfoldListener;
import com.android.wm.shell.bubbles.logging.BubbleSessionTracker;
import com.android.wm.shell.bubbles.shortcut.BubbleShortcutHelper;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
@@ -237,6 +238,7 @@ public class BubbleController implements ConfigurationChangeListener,
    private final BubbleAppInfoProvider mAppInfoProvider;
    private final Lazy<Optional<SplitScreenController>> mSplitScreenController;
    private final BubblesFoldLockSettingsObserver mFoldLockSettingsObserver;
    private final BubbleSessionTracker mSessionTracker;

    // Used to post to main UI thread
    private final ShellExecutor mMainExecutor;
@@ -375,7 +377,8 @@ public class BubbleController implements ConfigurationChangeListener,
            BubbleAppInfoProvider appInfoProvider,
            Lazy<Optional<SplitScreenController>> splitScreenController,
            Optional<ShellUnfoldProgressProvider> unfoldProgressProvider,
            BubblesFoldLockSettingsObserver foldLockSettingsObserver) {
            BubblesFoldLockSettingsObserver foldLockSettingsObserver,
            BubbleSessionTracker sessionTracker) {
        mContext = context;
        mShellCommandHandler = shellCommandHandler;
        mShellController = shellController;
@@ -432,6 +435,7 @@ public class BubbleController implements ConfigurationChangeListener,
        mAppInfoProvider = appInfoProvider;
        mSplitScreenController = splitScreenController;
        mFoldLockSettingsObserver = foldLockSettingsObserver;
        mSessionTracker = sessionTracker;
        shellInit.addInitCallback(this::onInit, this);

        if (unfoldProgressProvider.isPresent() && Flags.enableBubbleBar()
@@ -2801,6 +2805,20 @@ public class BubbleController implements ConfigurationChangeListener,
                    mBubbleStateListener.onBubbleStateChange(bubbleBarUpdate);
                }
            }

            if (update.expandedChanged) {
                if (update.expanded) {
                    if (isShowingAsBubbleBar()) {
                        mSessionTracker.startBubbleBar();
                    } else {
                        mSessionTracker.startFloating();
                    }
                } else if (isShowingAsBubbleBar()) {
                    mSessionTracker.stopBubbleBar();
                } else {
                    mSessionTracker.stopFloating();
                }
            }
        }
    };

Loading