Files
Lawnchair/tests/src/com/android/launcher3/popup/SystemShortcutTest.java
T
Sunny Goyal 3b307455a0 Revert^2 "Simplifying model testing rules"
35b6d322ab

Change-Id: I3ed574a517dbe350b6dfe5b1d3ed198203d22f44
2025-03-26 23:08:55 -07:00

420 lines
17 KiB
Java

/*
* Copyright (C) 2024 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.popup;
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.launcher3.AbstractFloatingView.TYPE_SNACKBAR;
import static com.android.launcher3.Flags.FLAG_ENABLE_DISMISS_PREDICTION_UNDO;
import static com.android.launcher3.Flags.FLAG_ENABLE_PRIVATE_SPACE;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DISMISS_PREDICTION_UNDO;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_DONT_SUGGEST_APP_TAP;
import static com.android.launcher3.model.data.WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.os.Process;
import android.os.UserHandle;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.view.View;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.R;
import com.android.launcher3.allapps.PrivateProfileManager;
import com.android.launcher3.dagger.LauncherAppComponent;
import com.android.launcher3.dagger.LauncherAppSingleton;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.util.AllModulesForTest;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.LauncherMultivalentJUnit;
import com.android.launcher3.util.SandboxApplication;
import com.android.launcher3.util.TestSandboxModelContextWrapper;
import com.android.launcher3.util.TestUtil;
import com.android.launcher3.util.UserIconInfo;
import com.android.launcher3.views.Snackbar;
import com.android.launcher3.widget.picker.model.WidgetPickerDataProvider;
import com.android.launcher3.widget.picker.model.data.WidgetPickerData;
import dagger.BindsInstance;
import dagger.Component;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(LauncherMultivalentJUnit.class)
public class SystemShortcutTest {
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
@Rule public final SandboxApplication mSandboxContext = new SandboxApplication();
private static final UserHandle PRIVATE_HANDLE = new UserHandle(11);
private static final UserHandle MAIN_HANDLE = Process.myUserHandle();
private View mView;
private ItemInfo mItemInfo;
private TestSandboxModelContextWrapper mTestContext;
private PrivateProfileManager mPrivateProfileManager;
private WidgetPickerDataProvider mWidgetPickerDataProvider;
private AppInfo mAppInfo;
@Mock UserCache mUserCache;
@Mock UserIconInfo mUserIconInfo;
@Mock LauncherActivityInfo mLauncherActivityInfo;
@Mock ApplicationInfo mApplicationInfo;
@Mock Intent mIntent;
@Mock StatsLogManager mStatsLogManager;
@Mock(answer = Answers.RETURNS_SELF) StatsLogger mStatsLogger;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mSandboxContext.initDaggerComponent(
DaggerSystemShortcutTest_TestComponent.builder().bindUserCache(mUserCache)
);
mTestContext = new TestSandboxModelContextWrapper(mSandboxContext) {
@Override
public StatsLogManager getStatsLogManager() {
return mStatsLogManager;
}
};
spyOn(mSandboxContext);
doReturn(mStatsLogger).when(mStatsLogManager).logger();
mView = new View(mTestContext);
mItemInfo = new ItemInfo();
LauncherApps mLauncherApps = mSandboxContext.spyService(LauncherApps.class);
doReturn(mLauncherActivityInfo).when(mLauncherApps).resolveActivity(any(), any());
when(mLauncherActivityInfo.getApplicationInfo()).thenReturn(mApplicationInfo);
when(mUserCache.getUserInfo(any())).thenReturn(mUserIconInfo);
mPrivateProfileManager = mTestContext.getAppsView().getPrivateProfileManager();
spyOn(mPrivateProfileManager);
when(mPrivateProfileManager.getProfileUser()).thenReturn(PRIVATE_HANDLE);
mWidgetPickerDataProvider = mTestContext.getWidgetPickerDataProvider();
spyOn(mWidgetPickerDataProvider);
}
@Test
public void testWidgetsForNullComponentName() {
assertNull(mItemInfo.getTargetComponent());
SystemShortcut systemShortcut = SystemShortcut.WIDGETS
.getShortcut(mTestContext, mItemInfo, mView);
assertNull(systemShortcut);
}
@Test
public void testWidgetsForEmptyWidgetList() {
mAppInfo = new AppInfo();
mAppInfo.componentName = new ComponentName(mTestContext, getClass());
assertNotNull(mAppInfo.getTargetComponent());
doReturn(new WidgetPickerData()).when(mWidgetPickerDataProvider).get();
spyOn(mAppInfo);
SystemShortcut systemShortcut = SystemShortcut.WIDGETS
.getShortcut(mTestContext, mAppInfo, mView);
verify(mAppInfo, times(2)).getTargetComponent();
assertNull(systemShortcut);
}
@Test
public void testAppInfoShortcut() {
mAppInfo = new AppInfo();
mAppInfo.componentName = new ComponentName(mTestContext, getClass());
SystemShortcut systemShortcut = SystemShortcut.APP_INFO
.getShortcut(mTestContext, mAppInfo, mView);
assertNotNull(systemShortcut);
}
@Test
public void testDontSuggestAppForNonPredictedItem() {
assertFalse(mItemInfo.isPredictedItem());
SystemShortcut systemShortcut = SystemShortcut.DONT_SUGGEST_APP
.getShortcut(mTestContext, mItemInfo, mView);
assertNull(systemShortcut);
}
@Test
@DisableFlags(FLAG_ENABLE_DISMISS_PREDICTION_UNDO)
public void testDontSuggestAppForPredictedItem() {
mAppInfo = new AppInfo();
mAppInfo.componentName = new ComponentName(mTestContext, getClass());
mAppInfo.container = CONTAINER_HOTSEAT_PREDICTION;
assertTrue(mAppInfo.isPredictedItem());
SystemShortcut systemShortcut = SystemShortcut.DONT_SUGGEST_APP
.getShortcut(mTestContext, mAppInfo, mView);
assertNotNull(systemShortcut);
TestUtil.runOnExecutorSync(MAIN_EXECUTOR, () -> systemShortcut.onClick(mView));
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
verify(mStatsLogger).log(eq(LAUNCHER_SYSTEM_SHORTCUT_DONT_SUGGEST_APP_TAP));
assertFalse(AbstractFloatingView.hasOpenView(mTestContext, TYPE_SNACKBAR));
}
@Test
@EnableFlags(FLAG_ENABLE_DISMISS_PREDICTION_UNDO)
public void testDontSuggestAppForPredictedItemWithUndo() {
mAppInfo = new AppInfo();
mAppInfo.componentName = new ComponentName(mTestContext, getClass());
mAppInfo.container = CONTAINER_HOTSEAT_PREDICTION;
assertTrue(mAppInfo.isPredictedItem());
SystemShortcut systemShortcut = SystemShortcut.DONT_SUGGEST_APP
.getShortcut(mTestContext, mAppInfo, mView);
assertNotNull(systemShortcut);
TestUtil.runOnExecutorSync(MAIN_EXECUTOR, () -> systemShortcut.onClick(mView));
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
verify(mStatsLogger).log(eq(LAUNCHER_SYSTEM_SHORTCUT_DONT_SUGGEST_APP_TAP));
// Undo bar shown
Snackbar snackbar = AbstractFloatingView.getOpenView(mTestContext, TYPE_SNACKBAR);
assertNotNull(snackbar);
reset(mStatsLogger);
TestUtil.runOnExecutorSync(MAIN_EXECUTOR, snackbar.findViewById(
R.id.action)::performClick);
verify(mStatsLogger).log(eq(LAUNCHER_DISMISS_PREDICTION_UNDO));
}
@Test
public void testPrivateProfileInstallwithTargetComponentNull() {
assertNull(mItemInfo.getTargetComponent());
SystemShortcut systemShortcut = SystemShortcut.PRIVATE_PROFILE_INSTALL
.getShortcut(mTestContext, mItemInfo, mView);
assertNull(systemShortcut);
}
@Test
public void testPrivateProfileInstallNotAllAppsContainer() {
mAppInfo = new AppInfo();
mAppInfo.componentName = new ComponentName(mTestContext, getClass());
mAppInfo.container = CONTAINER_HOTSEAT_PREDICTION;
assertNotNull(mAppInfo.getTargetComponent());
assertFalse(mAppInfo.getContainerInfo().hasAllAppsContainer());
SystemShortcut systemShortcut = SystemShortcut.PRIVATE_PROFILE_INSTALL
.getShortcut(mTestContext, mAppInfo, mView);
assertNull(systemShortcut);
}
@Test
public void testPrivateProfileInstallNullPrivateProfileManager() {
mAppInfo = new AppInfo();
mAppInfo.componentName = new ComponentName(mTestContext, getClass());
mAppInfo.container = CONTAINER_ALL_APPS;
mPrivateProfileManager = null;
assertNotNull(mAppInfo.getTargetComponent());
assertTrue(mAppInfo.getContainerInfo().hasAllAppsContainer());
assertNull(mPrivateProfileManager);
SystemShortcut systemShortcut = SystemShortcut.PRIVATE_PROFILE_INSTALL
.getShortcut(mTestContext, mAppInfo, mView);
assertNull(systemShortcut);
}
@Test
public void testPrivateProfileInstallPrivateProfileManagerDisabled() {
mAppInfo = new AppInfo();
mAppInfo.componentName = new ComponentName(mTestContext, getClass());
mAppInfo.container = CONTAINER_ALL_APPS;
assertNotNull(mPrivateProfileManager);
assertNotNull(mAppInfo.getTargetComponent());
assertTrue(mAppInfo.getContainerInfo().hasAllAppsContainer());
when(mPrivateProfileManager.isEnabled()).thenReturn(false);
SystemShortcut systemShortcut = SystemShortcut.PRIVATE_PROFILE_INSTALL
.getShortcut(mTestContext, mAppInfo, mView);
assertNull(systemShortcut);
}
@Test
public void testPrivateProfileInstallNullPrivateProfileUser() {
mAppInfo = new AppInfo();
mAppInfo.componentName = new ComponentName(mTestContext, getClass());
mAppInfo.container = CONTAINER_ALL_APPS;
when(mPrivateProfileManager.getProfileUser()).thenReturn(null);
assertNotNull(mPrivateProfileManager);
assertNotNull(mAppInfo.getTargetComponent());
assertTrue(mAppInfo.getContainerInfo().hasAllAppsContainer());
assertNull(mPrivateProfileManager.getProfileUser());
SystemShortcut systemShortcut = SystemShortcut.PRIVATE_PROFILE_INSTALL
.getShortcut(mTestContext, mAppInfo, mView);
assertNull(systemShortcut);
}
@Test
public void testPrivateProfileInstallNonNullPrivateProfileUser() {
mAppInfo = new AppInfo();
mAppInfo.componentName = new ComponentName(mTestContext, getClass());
mAppInfo.container = CONTAINER_ALL_APPS;
when(mPrivateProfileManager.isEnabled()).thenReturn(true);
when(mPrivateProfileManager.getProfileUser()).thenReturn(PRIVATE_HANDLE);
assertNotNull(mAppInfo.getTargetComponent());
assertTrue(mAppInfo.getContainerInfo().hasAllAppsContainer());
assertNotNull(mPrivateProfileManager);
assertNotNull(mPrivateProfileManager.getProfileUser());
assertNull(mTestContext.getAppsView().getAppsStore().getApp(
new ComponentKey(mAppInfo.getTargetComponent(), PRIVATE_HANDLE)));
SystemShortcut systemShortcut = SystemShortcut.PRIVATE_PROFILE_INSTALL
.getShortcut(mTestContext, mAppInfo, mView);
verify(mPrivateProfileManager, atLeast(1)).isEnabled();
assertNotNull(systemShortcut);
}
@Test
public void testInstallGetShortcutWithNonWorkSpaceItemInfo() {
SystemShortcut systemShortcut = SystemShortcut.INSTALL.getShortcut(
mTestContext, mItemInfo, mView);
Assert.assertNull(systemShortcut);
}
@Test
@UiThreadTest
public void testInstallGetShortcutWithWorkSpaceItemInfo() {
mAppInfo = new AppInfo();
mAppInfo.componentName = new ComponentName(mTestContext, getClass());
mAppInfo.intent = mIntent;
WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(mAppInfo);
workspaceItemInfo.status = FLAG_SUPPORTS_WEB_UI;
SystemShortcut systemShortcut = SystemShortcut.INSTALL.getShortcut(
mTestContext, workspaceItemInfo, mView);
Assert.assertNotNull(systemShortcut);
}
@Test
@DisableFlags(FLAG_ENABLE_PRIVATE_SPACE)
public void testUninstallGetShortcutWithPrivateSpaceOff() {
SystemShortcut systemShortcut = SystemShortcut.UNINSTALL_APP.getShortcut(
mTestContext, null, mView);
Assert.assertNull(systemShortcut);
}
@Test
@EnableFlags(FLAG_ENABLE_PRIVATE_SPACE)
public void testUninstallGetShortcutWithNonPrivateItemInfo() {
mAppInfo = new AppInfo();
mAppInfo.user = MAIN_HANDLE;
when(mUserIconInfo.isPrivate()).thenReturn(false);
SystemShortcut systemShortcut = SystemShortcut.UNINSTALL_APP.getShortcut(
mTestContext, mAppInfo, mView);
verify(mUserIconInfo).isPrivate();
Assert.assertNull(systemShortcut);
}
@Test
@EnableFlags(FLAG_ENABLE_PRIVATE_SPACE)
public void testUninstallGetShortcutWithSystemItemInfo() {
mAppInfo = new AppInfo();
mAppInfo.user = PRIVATE_HANDLE;
mAppInfo.itemType = ITEM_TYPE_APPLICATION;
mAppInfo.intent = mIntent;
mAppInfo.componentName = new ComponentName(mTestContext, getClass());
when(mLauncherActivityInfo.getComponentName()).thenReturn(mAppInfo.componentName);
when(mUserIconInfo.isPrivate()).thenReturn(true);
// System App
mApplicationInfo.flags = 1;
SystemShortcut systemShortcut = SystemShortcut.UNINSTALL_APP.getShortcut(
mTestContext, mAppInfo, mView);
verify(mLauncherActivityInfo, times(0)).getComponentName();
Assert.assertNull(systemShortcut);
}
@Test
@EnableFlags(FLAG_ENABLE_PRIVATE_SPACE)
public void testUninstallGetShortcutWithPrivateItemInfo() {
mAppInfo = new AppInfo();
mAppInfo.user = PRIVATE_HANDLE;
mAppInfo.itemType = ITEM_TYPE_APPLICATION;
mAppInfo.intent = mIntent;
mAppInfo.componentName = new ComponentName(mTestContext, getClass());
when(mUserIconInfo.isPrivate()).thenReturn(true);
when(mLauncherActivityInfo.getComponentName()).thenReturn(mAppInfo.componentName);
// 3rd party app, not system app.
mApplicationInfo.flags = 0;
SystemShortcut systemShortcut = SystemShortcut.UNINSTALL_APP.getShortcut(
mTestContext, mAppInfo, mView);
verify(mLauncherActivityInfo).getComponentName();
Assert.assertNotNull(systemShortcut);
systemShortcut.onClick(mView);
verify(mSandboxContext).startActivity(any());
}
@LauncherAppSingleton
@Component(modules = { AllModulesForTest.class })
interface TestComponent extends LauncherAppComponent {
@Component.Builder
interface Builder extends LauncherAppComponent.Builder {
@BindsInstance
SystemShortcutTest.TestComponent.Builder bindUserCache(UserCache userCache);
@Override LauncherAppComponent build();
}
}
}