Log DESKTOP_WINDOW_APP_HANDLE_TAP metrics
Bug: 341320112
Flag: EXEMPT adding logs
Test: verified logs with go/atomtester
Change-Id: I98ae1a52e3f3347c218116ca63f1be48e41b9623
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index c11d6fa..5f50868 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -28,6 +28,7 @@
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 @@
WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
FocusTransitionObserver focusTransitionObserver,
- DesktopModeEventLogger desktopModeEventLogger
+ DesktopModeEventLogger desktopModeEventLogger,
+ DesktopModeUiEventLogger desktopModeUiEventLogger
) {
if (!DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) {
return Optional.empty();
@@ -904,7 +906,7 @@
assistContentRequester, multiInstanceHelper, desktopTasksLimiter,
appHandleEducationController, appToWebEducationController,
windowDecorCaptionHandleRepository, activityOrientationChangeHandler,
- focusTransitionObserver, desktopModeEventLogger));
+ focusTransitionObserver, desktopModeEventLogger, desktopModeUiEventLogger));
}
@WMSingleton
@@ -1212,9 +1214,10 @@
@WMSingleton
@Provides
static DesktopModeUiEventLogger provideDesktopUiEventLogger(
- UiEventLogger uiEventLogger
+ UiEventLogger uiEventLogger,
+ PackageManager packageManager
) {
- return new DesktopModeUiEventLogger(uiEventLogger);
+ return new DesktopModeUiEventLogger(uiEventLogger, packageManager);
}
//
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
index dff56c1..5801c6a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
@@ -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 @@
/** 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 @@
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 @@
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 @@
@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
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 6f33399..f1b91cb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -107,6 +107,8 @@
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 @@
private final TaskPositionerFactory mTaskPositionerFactory;
private final FocusTransitionObserver mFocusTransitionObserver;
private final DesktopModeEventLogger mDesktopModeEventLogger;
+ private final DesktopModeUiEventLogger mDesktopModeUiEventLogger;
public DesktopModeWindowDecorViewModel(
Context context,
@@ -256,7 +259,8 @@
WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
FocusTransitionObserver focusTransitionObserver,
- DesktopModeEventLogger desktopModeEventLogger) {
+ DesktopModeEventLogger desktopModeEventLogger,
+ DesktopModeUiEventLogger desktopModeUiEventLogger) {
this(
context,
shellExecutor,
@@ -291,7 +295,8 @@
activityOrientationChangeHandler,
new TaskPositionerFactory(),
focusTransitionObserver,
- desktopModeEventLogger);
+ desktopModeEventLogger,
+ desktopModeUiEventLogger);
}
@VisibleForTesting
@@ -329,7 +334,8 @@
Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
TaskPositionerFactory taskPositionerFactory,
FocusTransitionObserver focusTransitionObserver,
- DesktopModeEventLogger desktopModeEventLogger) {
+ DesktopModeEventLogger desktopModeEventLogger,
+ DesktopModeUiEventLogger desktopModeUiEventLogger) {
mContext = context;
mMainExecutor = shellExecutor;
mMainHandler = mainHandler;
@@ -392,6 +398,7 @@
mTaskPositionerFactory = taskPositionerFactory;
mFocusTransitionObserver = focusTransitionObserver;
mDesktopModeEventLogger = desktopModeEventLogger;
+ mDesktopModeUiEventLogger = desktopModeUiEventLogger;
shellInit.addInitCallback(this::onInit, this);
}
@@ -802,6 +809,11 @@
} 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);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
index f935ac7..950217c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
@@ -26,6 +26,7 @@
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 @@
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 @@
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 @@
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 @@
info.isTopActivityTransparent = mIsTopActivityTransparent;
info.numActivities = mNumActivities;
info.lastActiveTime = mLastActiveTime;
+ info.userId = mUserId;
+ info.baseActivity = mBaseActivity;
return info;
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLoggerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLoggerTest.kt
index a8b2811..94698e2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLoggerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLoggerTest.kt
@@ -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 @@
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 @@
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"
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
index 91eaada..1670f2a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
@@ -55,6 +55,7 @@
import com.android.wm.shell.common.SyncTransactionQueue
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.DesktopRepository
import com.android.wm.shell.desktopmode.DesktopTasksController
import com.android.wm.shell.desktopmode.DesktopTasksLimiter
@@ -199,7 +200,8 @@
Optional.of(mockActivityOrientationChangeHandler),
mockTaskPositionerFactory,
mockFocusTransitionObserver,
- desktopModeEventLogger
+ desktopModeEventLogger,
+ mock<DesktopModeUiEventLogger>()
)
desktopModeWindowDecorViewModel.setSplitScreenController(mockSplitScreenController)
whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)