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

Commit 1f3f4ac5 authored by Jorge Gil's avatar Jorge Gil
Browse files

Log DESKTOP_WINDOW_APP_HANDLE_TAP metrics

Bug: 341320112
Flag: EXEMPT adding logs
Test: verified logs with go/atomtester
Change-Id: I98ae1a52e3f3347c218116ca63f1be48e41b9623
parent 9563acf6
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.annotation.Nullable;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.hardware.input.InputManager;
import android.os.Handler;
import android.os.UserManager;
@@ -891,7 +892,8 @@ public abstract class WMShellModule {
            WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
            Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
            FocusTransitionObserver focusTransitionObserver,
            DesktopModeEventLogger desktopModeEventLogger
            DesktopModeEventLogger desktopModeEventLogger,
            DesktopModeUiEventLogger desktopModeUiEventLogger
    ) {
        if (!DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) {
            return Optional.empty();
@@ -904,7 +906,7 @@ public abstract class WMShellModule {
                assistContentRequester, multiInstanceHelper, desktopTasksLimiter,
                appHandleEducationController, appToWebEducationController,
                windowDecorCaptionHandleRepository, activityOrientationChangeHandler,
                focusTransitionObserver, desktopModeEventLogger));
                focusTransitionObserver, desktopModeEventLogger, desktopModeUiEventLogger));
    }

    @WMSingleton
@@ -1212,9 +1214,10 @@ public abstract class WMShellModule {
    @WMSingleton
    @Provides
    static DesktopModeUiEventLogger provideDesktopUiEventLogger(
            UiEventLogger uiEventLogger
            UiEventLogger uiEventLogger,
            PackageManager packageManager
    ) {
        return new DesktopModeUiEventLogger(uiEventLogger);
        return new DesktopModeUiEventLogger(uiEventLogger, packageManager);
    }

    //
+24 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.wm.shell.desktopmode

import android.app.ActivityManager.RunningTaskInfo
import android.content.pm.PackageManager
import com.android.internal.logging.InstanceId
import com.android.internal.logging.InstanceIdSequence
import com.android.internal.logging.UiEvent
@@ -27,6 +29,7 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
/** Log Aster UIEvents for desktop windowing mode. */
class DesktopModeUiEventLogger(
    private val uiEventLogger: UiEventLogger,
    private val packageManager: PackageManager,
) {
    private val instanceIdSequence = InstanceIdSequence(Integer.MAX_VALUE)

@@ -45,6 +48,17 @@ class DesktopModeUiEventLogger(
        uiEventLogger.log(event, uid, packageName)
    }

    /** Logs an event for a CUI on a particular task. */
    fun log(taskInfo: RunningTaskInfo, event: DesktopUiEventEnum) {
        val packageName = taskInfo.baseActivity?.packageName
        if (packageName == null) {
            logD("Skip logging due to null base activity")
            return
        }
        val uid = getUid(packageName, taskInfo.userId)
        log(uid, packageName, event)
    }

    /** Retrieves a new instance id for a new interaction. */
    fun getNewInstanceId(): InstanceId = instanceIdSequence.newInstanceId()

@@ -70,6 +84,12 @@ class DesktopModeUiEventLogger(
        uiEventLogger.logWithInstanceId(event, uid, packageName, instanceId)
    }

    private fun getUid(packageName: String, userId: Int): Int = try {
        packageManager.getApplicationInfoAsUser(packageName, /* flags= */ 0, userId).uid
    } catch (e: PackageManager.NameNotFoundException) {
        INVALID_PACKAGE_UID
    }

    private fun logD(msg: String, vararg arguments: Any?) {
        ProtoLog.d(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
    }
@@ -84,12 +104,15 @@ class DesktopModeUiEventLogger(
        @UiEvent(doc = "Tap on the window header maximize button in desktop windowing mode")
        DESKTOP_WINDOW_MAXIMIZE_BUTTON_TAP(1723),
        @UiEvent(doc = "Double tap on window header to maximize it in desktop windowing mode")
        DESKTOP_WINDOW_HEADER_DOUBLE_TAP_TO_MAXIMIZE(1724);
        DESKTOP_WINDOW_HEADER_DOUBLE_TAP_TO_MAXIMIZE(1724),
        @UiEvent(doc = "Tap on the window Handle to open the Handle Menu")
        DESKTOP_WINDOW_APP_HANDLE_TAP(1998);

        override fun getId(): Int = mId
    }

    companion object {
        private const val TAG = "DesktopModeUiEventLogger"
        private const val INVALID_PACKAGE_UID = -1
    }
}
+15 −3
Original line number Diff line number Diff line
@@ -107,6 +107,8 @@ import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.compatui.CompatUIController;
import com.android.wm.shell.desktopmode.DesktopActivityOrientationChangeHandler;
import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger;
import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum;
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator;
import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.DesktopTasksController;
@@ -227,6 +229,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
    private final TaskPositionerFactory mTaskPositionerFactory;
    private final FocusTransitionObserver mFocusTransitionObserver;
    private final DesktopModeEventLogger mDesktopModeEventLogger;
    private final DesktopModeUiEventLogger mDesktopModeUiEventLogger;

    public DesktopModeWindowDecorViewModel(
            Context context,
@@ -256,7 +259,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
            WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
            Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
            FocusTransitionObserver focusTransitionObserver,
            DesktopModeEventLogger desktopModeEventLogger) {
            DesktopModeEventLogger desktopModeEventLogger,
            DesktopModeUiEventLogger desktopModeUiEventLogger) {
        this(
                context,
                shellExecutor,
@@ -291,7 +295,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
                activityOrientationChangeHandler,
                new TaskPositionerFactory(),
                focusTransitionObserver,
                desktopModeEventLogger);
                desktopModeEventLogger,
                desktopModeUiEventLogger);
    }

    @VisibleForTesting
@@ -329,7 +334,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
            Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
            TaskPositionerFactory taskPositionerFactory,
            FocusTransitionObserver focusTransitionObserver,
            DesktopModeEventLogger desktopModeEventLogger) {
            DesktopModeEventLogger desktopModeEventLogger,
            DesktopModeUiEventLogger desktopModeUiEventLogger) {
        mContext = context;
        mMainExecutor = shellExecutor;
        mMainHandler = mainHandler;
@@ -392,6 +398,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
        mTaskPositionerFactory = taskPositionerFactory;
        mFocusTransitionObserver = focusTransitionObserver;
        mDesktopModeEventLogger = desktopModeEventLogger;
        mDesktopModeUiEventLogger = desktopModeUiEventLogger;

        shellInit.addInitCallback(this::onInit, this);
    }
@@ -802,6 +809,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
            } else if (id == R.id.back_button) {
                mTaskOperations.injectBackKey(mDisplayId);
            } else if (id == R.id.caption_handle || id == R.id.open_menu_button) {
                if (id == R.id.caption_handle && !decoration.mTaskInfo.isFreeform()) {
                    // Clicking the App Handle.
                    mDesktopModeUiEventLogger.log(decoration.mTaskInfo,
                            DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_TAP);
                }
                if (!decoration.isHandleMenuActive()) {
                    moveTaskToFront(decoration.mTaskInfo);
                    openHandleMenu(mTaskId);
+19 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.mock;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.WindowConfiguration;
import android.content.ComponentName;
import android.content.Intent;
import android.graphics.Point;
import android.graphics.Rect;
@@ -42,7 +43,9 @@ public final class TestRunningTaskInfoBuilder {
    private int mParentTaskId = INVALID_TASK_ID;
    private int mUid = INVALID_TASK_ID;
    private int mTaskId = INVALID_TASK_ID;
    private int mUserId = -1;
    private Intent mBaseIntent = new Intent();
    private ComponentName mBaseActivity = null;
    private @WindowConfiguration.ActivityType int mActivityType = ACTIVITY_TYPE_STANDARD;
    private @WindowConfiguration.WindowingMode int mWindowingMode = WINDOWING_MODE_UNDEFINED;
    private int mDisplayId = Display.DEFAULT_DISPLAY;
@@ -87,6 +90,12 @@ public final class TestRunningTaskInfoBuilder {
        return this;
    }

    /** Sets the task info's user id. */
    public TestRunningTaskInfoBuilder setUserId(int userId) {
        mUserId = userId;
        return this;
    }

    /**
     * Set {@link ActivityManager.RunningTaskInfo#baseIntent} for the task info, by default
     * an empty intent is assigned
@@ -96,6 +105,14 @@ public final class TestRunningTaskInfoBuilder {
        return this;
    }

    /**
     * Set {@link ActivityManager.RunningTaskInfo#baseActivity} for the task info.
     */
    public TestRunningTaskInfoBuilder setBaseActivity(@NonNull ComponentName activity) {
        mBaseActivity = activity;
        return this;
    }

    public TestRunningTaskInfoBuilder setActivityType(
            @WindowConfiguration.ActivityType int activityType) {
        mActivityType = activityType;
@@ -164,6 +181,8 @@ public final class TestRunningTaskInfoBuilder {
        info.isTopActivityTransparent = mIsTopActivityTransparent;
        info.numActivities = mNumActivities;
        info.lastActiveTime = mLastActiveTime;
        info.userId = mUserId;
        info.baseActivity = mBaseActivity;
        return info;
    }
}
+26 −1
Original line number Diff line number Diff line
@@ -17,16 +17,22 @@
package com.android.wm.shell.desktopmode


import android.content.ComponentName
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.internal.logging.InstanceId
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.TestRunningTaskInfoBuilder
import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.DESKTOP_WINDOW_EDGE_DRAG_RESIZE
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever

/**
 * Test class for [DesktopModeUiEventLogger]
@@ -39,11 +45,12 @@ class DesktopModeUiEventLoggerTest : ShellTestCase() {
    private lateinit var uiEventLoggerFake: UiEventLoggerFake
    private lateinit var logger: DesktopModeUiEventLogger

    private val mockPackageManager: PackageManager = mock<PackageManager>()

    @Before
    fun setUp() {
        uiEventLoggerFake = UiEventLoggerFake()
        logger = DesktopModeUiEventLogger(uiEventLoggerFake)
        logger = DesktopModeUiEventLogger(uiEventLoggerFake, mockPackageManager)
    }

    @Test
@@ -100,10 +107,28 @@ class DesktopModeUiEventLoggerTest : ShellTestCase() {
        assertThat(uiEventLoggerFake[0].packageName).isEqualTo(PACKAGE_NAME)
    }

    @Test
    fun logWithTaskInfo_eventLogged() {
        val event =
            DESKTOP_WINDOW_EDGE_DRAG_RESIZE
        val taskInfo = TestRunningTaskInfoBuilder()
            .setUserId(USER_ID)
            .setBaseActivity(ComponentName(PACKAGE_NAME, "test"))
            .build()
        whenever(mockPackageManager.getApplicationInfoAsUser(PACKAGE_NAME, /* flags= */ 0, USER_ID))
            .thenReturn(ApplicationInfo().apply { uid = UID })
        logger.log(taskInfo, event)
        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(event.id)
        assertThat(uiEventLoggerFake[0].instanceId).isNull()
        assertThat(uiEventLoggerFake[0].uid).isEqualTo(UID)
        assertThat(uiEventLoggerFake[0].packageName).isEqualTo(PACKAGE_NAME)
    }

    companion object {
        private val INSTANCE_ID = InstanceId.fakeInstanceId(0)
        private const val UID = 10
        private const val USER_ID = 2
        private const val PACKAGE_NAME = "com.foo"
    }
}
Loading