Merge "Fixing UserHandle for AppTarget Event from Launcher." into main
diff --git a/quickstep/src/com/android/launcher3/model/AppEventProducer.java b/quickstep/src/com/android/launcher3/model/AppEventProducer.java
index 17c39af..7209bd8 100644
--- a/quickstep/src/com/android/launcher3/model/AppEventProducer.java
+++ b/quickstep/src/com/android/launcher3/model/AppEventProducer.java
@@ -72,12 +72,13 @@
import com.android.launcher3.logging.StatsLogManager.EventEnum;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutRequest;
+import com.android.launcher3.util.UserIconInfo;
import com.android.quickstep.logging.StatsLogCompatManager.StatsLogConsumer;
+import com.android.systemui.shared.system.SysUiStatsLog;
import java.util.Locale;
import java.util.Optional;
import java.util.function.ObjIntConsumer;
-import java.util.function.Predicate;
/**
* Utility class to track stats log and emit corresponding app events
@@ -188,14 +189,13 @@
}
@Nullable
- private AppTarget toAppTarget(LauncherAtom.ItemInfo info) {
- UserHandle userHandle = Process.myUserHandle();
- if (info.getIsWork()) {
- userHandle = UserCache.INSTANCE.get(mContext).getUserProfiles().stream()
- .filter(((Predicate<UserHandle>) userHandle::equals).negate())
- .findAny()
- .orElse(null);
- }
+ AppTarget toAppTarget(LauncherAtom.ItemInfo info) {
+ int iconInfoType = getIconInfoTypeFromItemInfo(info);
+ UserCache userCache = UserCache.getInstance(mContext);
+ UserHandle userHandle = userCache.getUserProfiles().stream()
+ .filter(user -> userCache.getUserInfo(user).type == iconInfoType)
+ .findFirst()
+ .orElse(null);
if (userHandle == null) {
return null;
}
@@ -328,4 +328,16 @@
return TextUtils.isEmpty(componentNameString)
? null : ComponentName.unflattenFromString(componentNameString);
}
+
+ private int getIconInfoTypeFromItemInfo(LauncherAtom.ItemInfo info) {
+ int userType = info.getUserType();
+ return switch (userType) {
+ case SysUiStatsLog.LAUNCHER_UICHANGED__USER_TYPE__TYPE_WORK -> UserIconInfo.TYPE_WORK;
+ case SysUiStatsLog.LAUNCHER_UICHANGED__USER_TYPE__TYPE_CLONED ->
+ UserIconInfo.TYPE_CLONED;
+ case SysUiStatsLog.LAUNCHER_UICHANGED__USER_TYPE__TYPE_PRIVATE ->
+ UserIconInfo.TYPE_PRIVATE;
+ default -> UserIconInfo.TYPE_MAIN;
+ };
+ }
}
diff --git a/quickstep/tests/src/com/android/launcher3/model/AppEventProducerTest.java b/quickstep/tests/src/com/android/launcher3/model/AppEventProducerTest.java
new file mode 100644
index 0000000..d6c1447
--- /dev/null
+++ b/quickstep/tests/src/com/android/launcher3/model/AppEventProducerTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2023 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.launcher3.model;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS;
+import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import android.app.prediction.AppTarget;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Process;
+import android.os.UserHandle;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.launcher3.logger.LauncherAtom;
+import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.pm.UserCache;
+import com.android.launcher3.util.ActivityContextWrapper;
+import com.android.launcher3.util.UserIconInfo;
+import com.android.launcher3.util.rule.StaticMockitoRule;
+import com.android.systemui.shared.system.SysUiStatsLog;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Arrays;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AppEventProducerTest {
+
+ private static final UserHandle MAIN_HANDLE = Process.myUserHandle();
+ private static final UserHandle PRIVATE_HANDLE = new UserHandle(11);
+
+ private static final UserIconInfo MAIN_ICON_INFO =
+ new UserIconInfo(MAIN_HANDLE, UserIconInfo.TYPE_MAIN);
+ private static final UserIconInfo PRIVATE_ICON_INFO =
+ new UserIconInfo(PRIVATE_HANDLE, UserIconInfo.TYPE_PRIVATE);
+
+ private Context mContext;
+ private AppEventProducer mAppEventProducer;
+ @Mock
+ private UserCache mUserCache;
+
+ @Rule
+ public final StaticMockitoRule mStaticMockitoRule = new StaticMockitoRule(UserCache.class);
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = new ActivityContextWrapper(getApplicationContext());
+ when(UserCache.getInstance(any(Context.class))).thenReturn(mUserCache);
+ mAppEventProducer = new AppEventProducer(mContext, null);
+ }
+
+ @Test
+ public void buildAppTarget_containsCorrectUser() {
+ when(mUserCache.getUserProfiles())
+ .thenReturn(Arrays.asList(MAIN_HANDLE, PRIVATE_HANDLE));
+ when(mUserCache.getUserInfo(any(UserHandle.class)))
+ .thenReturn(MAIN_ICON_INFO, PRIVATE_ICON_INFO);
+ ComponentName gmailComponentName = new ComponentName(mContext,
+ "com.android.launcher3.tests.Activity" + "Gmail");
+ AppInfo gmailAppInfo = new
+ AppInfo(gmailComponentName, "Gmail", MAIN_HANDLE, new Intent());
+ gmailAppInfo.container = CONTAINER_ALL_APPS;
+ gmailAppInfo.itemType = ITEM_TYPE_APPLICATION;
+
+ AppTarget gmailTarget = mAppEventProducer
+ .toAppTarget(buildItemInfoProtoForAppInfo(gmailAppInfo));
+
+ assert gmailTarget != null;
+ assertEquals(gmailTarget.getUser(), MAIN_HANDLE);
+
+ when(mUserCache.getUserInfo(any(UserHandle.class)))
+ .thenReturn(MAIN_ICON_INFO, PRIVATE_ICON_INFO);
+ AppInfo gmailAppInfoPrivate = new
+ AppInfo(gmailComponentName, "Gmail", PRIVATE_HANDLE, new Intent());
+ gmailAppInfoPrivate.container = CONTAINER_ALL_APPS;
+ gmailAppInfoPrivate.itemType = ITEM_TYPE_APPLICATION;
+
+ AppTarget gmailPrivateTarget = mAppEventProducer
+ .toAppTarget(buildItemInfoProtoForAppInfo(gmailAppInfoPrivate));
+
+ assert gmailPrivateTarget != null;
+ assertEquals(gmailPrivateTarget.getUser(), PRIVATE_HANDLE);
+ }
+
+ private LauncherAtom.ItemInfo buildItemInfoProtoForAppInfo(AppInfo appInfo) {
+ LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder();
+ if (appInfo.user.equals(PRIVATE_HANDLE)) {
+ itemBuilder.setUserType(SysUiStatsLog.LAUNCHER_UICHANGED__USER_TYPE__TYPE_PRIVATE);
+ } else {
+ itemBuilder.setUserType(SysUiStatsLog.LAUNCHER_UICHANGED__USER_TYPE__TYPE_MAIN);
+ }
+ itemBuilder.setApplication(LauncherAtom.Application.newBuilder()
+ .setComponentName(appInfo.componentName.flattenToShortString())
+ .setPackageName(appInfo.componentName.getPackageName()));
+ itemBuilder.setContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
+ .setAllAppsContainer(LauncherAtom.AllAppsContainer.getDefaultInstance())
+ .build());
+ return itemBuilder.build();
+ }
+}