Loading tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java→tests/src/com/android/launcher3/ui/WorkProfileTest.java +24 −45 Original line number Diff line number Diff line Loading @@ -17,9 +17,7 @@ package com.android.launcher3.ui; import static com.android.launcher3.LauncherPrefs.WORK_EDU_STEP; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.allapps.AllAppsStore.DEFER_UPDATES_TEST; import static com.android.launcher3.testing.shared.TestProtocol.NORMAL_STATE_ORDINAL; import static com.android.launcher3.util.TestUtil.installDummyAppForUser; import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL; import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT; Loading @@ -43,36 +41,39 @@ import com.android.launcher3.allapps.AllAppsPagedView; import com.android.launcher3.allapps.WorkEduCard; import com.android.launcher3.allapps.WorkPausedCard; import com.android.launcher3.allapps.WorkProfileManager; import com.android.launcher3.tapl.LauncherInstrumentation; import com.android.launcher3.util.BaseLauncherActivityTest; import com.android.launcher3.util.TestUtil; import com.android.launcher3.util.rule.ScreenRecordRule; import com.android.launcher3.util.rule.TestStabilityRule; import com.android.launcher3.util.rule.TestStabilityRule.Stability; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import java.io.IOException; import java.util.Objects; import java.util.function.Predicate; @LargeTest @RunWith(AndroidJUnit4.class) public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { public class WorkProfileTest extends BaseLauncherActivityTest<Launcher> { private static final int WORK_PAGE = ActivityAllAppsContainerView.AdapterHolder.WORK; public static final int WAIT_TIME_MS = 30000; @Rule public ScreenRecordRule mScreenRecordRule = new ScreenRecordRule(); @Rule public TestStabilityRule mTestStabilityRule = new TestStabilityRule(); private int mProfileUserId; private boolean mWorkProfileSetupSuccessful; private final String TAG = "WorkProfileTest"; private static final String TAG = "WorkProfileTest"; @Before @Override public void setUp() throws Exception { super.setUp(); String output = mDevice.executeShellCommand( "pm create-user --profileOf 0 --managed TestProfile"); String output = executeShellCommand("pm create-user --profileOf 0 --managed TestProfile"); updateWorkProfileSetupSuccessful("pm create-user", output); String[] tokens = output.split("\\s+"); Loading @@ -88,36 +89,15 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { return; // no need to setup launcher since all tests will skip. } mDevice.pressHome(); waitForLauncherCondition("Launcher didn't start", Objects::nonNull); waitForStateTransitionToEnd("Launcher internal state didn't switch to Normal", () -> NORMAL); waitForResumed("Launcher internal state is still Background"); mLauncher.getWorkspace().switchToAllApps(); waitForStateTransitionToEnd("Launcher internal state didn't switch to All Apps", () -> ALL_APPS); loadLauncherSync(); goToState(ALL_APPS); waitForState("Launcher internal state didn't switch to All Apps", () -> ALL_APPS); } @After public void removeWorkProfile() throws Exception { executeOnLauncherInTearDown(launcher -> { if (launcher.getAppsView() == null) { return; } launcher.getAppsView().getAppsStore().disableDeferUpdates(DEFER_UPDATES_TEST); }); TestUtil.uninstallDummyApp(); mLauncher.runToState( () -> { try { mDevice.executeShellCommand("pm remove-user --wait " + mProfileUserId); } catch (IOException e) { throw new RuntimeException(e); } }, NORMAL_STATE_ORDINAL, "executing pm 'remove-user' command"); executeShellCommand("pm remove-user --wait " + mProfileUserId); } private void waitForWorkTabSetup() { Loading @@ -127,7 +107,7 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { return true; } return false; }, LauncherInstrumentation.WAIT_TIME_MS); }, WAIT_TIME_MS); } @Test Loading @@ -137,10 +117,10 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { waitForWorkTabSetup(); waitForLauncherCondition("Personal tab is missing", launcher -> launcher.getAppsView().isPersonalTabVisible(), LauncherInstrumentation.WAIT_TIME_MS); WAIT_TIME_MS); waitForLauncherCondition("Work tab is missing", launcher -> launcher.getAppsView().isWorkTabVisible(), LauncherInstrumentation.WAIT_TIME_MS); WAIT_TIME_MS); } // Staging; will be promoted to presubmit if stable Loading @@ -156,12 +136,11 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { WorkProfileManager manager = getFromLauncher(l -> l.getAppsView().getWorkManager()); waitForLauncherCondition("work profile initial state check failed", launcher -> manager.getWorkUtilityView() != null && manager.getCurrentState() == WorkProfileManager.STATE_ENABLED && manager.getWorkUtilityView().isEnabled(), LauncherInstrumentation.WAIT_TIME_MS); WAIT_TIME_MS); //start work profile toggle OFF test executeOnLauncher(l -> { Loading @@ -173,7 +152,7 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { waitForLauncherCondition("Work profile toggle OFF failed", launcher -> { manager.reset(); // pulls current state from system return manager.getCurrentState() == WorkProfileManager.STATE_DISABLED; }, LauncherInstrumentation.WAIT_TIME_MS); }, WAIT_TIME_MS); waitForWorkCard("Work paused card not shown", view -> view instanceof WorkPausedCard); Loading @@ -188,7 +167,7 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { waitForLauncherCondition("Work profile toggle ON failed", launcher -> { manager.reset(); // pulls current state from system return manager.getCurrentState() == WorkProfileManager.STATE_ENABLED; }, LauncherInstrumentation.WAIT_TIME_MS); }, WAIT_TIME_MS); } Loading @@ -215,7 +194,7 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { } finally { l.getAppsView().getAppsStore().enableDeferUpdates(DEFER_UPDATES_TEST); } }, LauncherInstrumentation.WAIT_TIME_MS); }, WAIT_TIME_MS); } private void updateWorkProfileSetupSuccessful(String cli, String output) { Loading tests/src/com/android/launcher3/ui/workspace/TaplThemeIconsTest.java→tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java +203 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,10 @@ */ package com.android.launcher3.ui.workspace; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static com.android.launcher3.AbstractFloatingView.TYPE_ACTION_POPUP; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME; import static org.junit.Assert.assertEquals; Loading @@ -29,15 +33,19 @@ import android.view.View; import android.view.ViewGroup; import androidx.test.filters.LargeTest; import androidx.test.uiautomator.UiDevice; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BubbleTextView; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.allapps.AllAppsRecyclerView; import com.android.launcher3.celllayout.FavoriteItemsTransaction; import com.android.launcher3.icons.ThemedIconDrawable; import com.android.launcher3.tapl.HomeAllApps; import com.android.launcher3.tapl.HomeAppIcon; import com.android.launcher3.tapl.HomeAppIconMenuItem; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.popup.ArrowPopup; import com.android.launcher3.util.BaseLauncherActivityTest; import com.android.launcher3.util.Executors; import com.android.launcher3.util.TestUtil; import org.junit.Test; Loading @@ -50,7 +58,7 @@ import java.util.Queue; * Note running these tests will clear the workspace on the device. */ @LargeTest public class TaplThemeIconsTest extends AbstractLauncherUiTest<Launcher> { public class ThemeIconsTest extends BaseLauncherActivityTest<Launcher> { private static final String APP_NAME = "IconThemedActivity"; private static final String SHORTCUT_NAME = "Shortcut 1"; Loading @@ -58,78 +66,71 @@ public class TaplThemeIconsTest extends AbstractLauncherUiTest<Launcher> { @Test public void testIconWithoutTheme() throws Exception { setThemeEnabled(false); initialize(this); HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps(); allApps.freeze(); try { HomeAppIcon icon = allApps.getAppIcon(APP_NAME); executeOnLauncher(l -> verifyIconTheme(APP_NAME, l.getAppsView(), false)); icon.dragToWorkspace(false, false); new FavoriteItemsTransaction(targetContext()).commit(); loadLauncherSync(); goToState(LauncherState.ALL_APPS); freezeAllApps(); scrollToAppIcon(APP_NAME); BubbleTextView btv = getFromLauncher( l -> verifyIconTheme(APP_NAME, l.getAppsView(), false)); addToWorkspace(btv); executeOnLauncher(l -> verifyIconTheme(APP_NAME, l.getWorkspace(), false)); } finally { allApps.unfreeze(); } } @Test public void testShortcutIconWithoutTheme() throws Exception { setThemeEnabled(false); initialize(this); HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps(); allApps.freeze(); try { HomeAppIcon icon = allApps.getAppIcon(TEST_APP_NAME); HomeAppIconMenuItem shortcutItem = (HomeAppIconMenuItem) icon.openDeepShortcutMenu().getMenuItem(SHORTCUT_NAME); shortcutItem.dragToWorkspace(false, false); new FavoriteItemsTransaction(targetContext()).commit(); loadLauncherSync(); goToState(LauncherState.ALL_APPS); freezeAllApps(); scrollToAppIcon(TEST_APP_NAME); BubbleTextView btv = getFromLauncher(l -> findBtv(TEST_APP_NAME, l.getAppsView())); TestUtil.runOnExecutorSync(MAIN_EXECUTOR, btv::performLongClick); BubbleTextView menuItem = getOnceNotNull("Popup menu not open", l -> (AbstractFloatingView.getOpenView(l, TYPE_ACTION_POPUP) instanceof ArrowPopup ap) ? findBtv(SHORTCUT_NAME, ap) : null); addToWorkspace(menuItem); executeOnLauncher(l -> verifyIconTheme(SHORTCUT_NAME, l.getWorkspace(), false)); } finally { allApps.unfreeze(); } } @Test public void testIconWithTheme() throws Exception { setThemeEnabled(true); initialize(this); HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps(); allApps.freeze(); try { HomeAppIcon icon = allApps.getAppIcon(APP_NAME); executeOnLauncher(l -> verifyIconTheme(APP_NAME, l.getAppsView(), false)); icon.dragToWorkspace(false, false); new FavoriteItemsTransaction(targetContext()).commit(); loadLauncherSync(); goToState(LauncherState.ALL_APPS); freezeAllApps(); scrollToAppIcon(APP_NAME); BubbleTextView btv = getFromLauncher(l -> verifyIconTheme(APP_NAME, l.getAppsView(), false)); addToWorkspace(btv); executeOnLauncher(l -> verifyIconTheme(APP_NAME, l.getWorkspace(), true)); } finally { allApps.unfreeze(); } } @Test public void testShortcutIconWithTheme() throws Exception { setThemeEnabled(true); initialize(this); HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps(); allApps.freeze(); try { HomeAppIcon icon = allApps.getAppIcon(TEST_APP_NAME); HomeAppIconMenuItem shortcutItem = (HomeAppIconMenuItem) icon.openDeepShortcutMenu().getMenuItem(SHORTCUT_NAME); shortcutItem.dragToWorkspace(false, false); loadLauncherSync(); goToState(LauncherState.ALL_APPS); freezeAllApps(); scrollToAppIcon(TEST_APP_NAME); BubbleTextView btv = getFromLauncher(l -> findBtv(TEST_APP_NAME, l.getAppsView())); TestUtil.runOnExecutorSync(MAIN_EXECUTOR, btv::performLongClick); BubbleTextView menuItem = getOnceNotNull("Popup menu not open", l -> (AbstractFloatingView.getOpenView(l, TYPE_ACTION_POPUP) instanceof ArrowPopup ap) ? findBtv(SHORTCUT_NAME, ap) : null); addToWorkspace(menuItem); executeOnLauncher(l -> verifyIconTheme(SHORTCUT_NAME, l.getWorkspace(), true)); } finally { allApps.unfreeze(); } } private void verifyIconTheme(String title, ViewGroup parent, boolean isThemed) { private BubbleTextView findBtv(String title, ViewGroup parent) { // Wait for Launcher model to be completed try { Executors.MODEL_EXECUTOR.submit(() -> { }).get(); Loading @@ -149,29 +150,54 @@ public class TaplThemeIconsTest extends AbstractLauncherUiTest<Launcher> { viewQueue.add(parent.getChildAt(i)); } } else if (view instanceof BubbleTextView btv) { if (title.equals(btv.getContentDescription().toString())) { if (btv.getContentDescription() != null && title.equals(btv.getContentDescription().toString())) { icon = btv; break; } } } return icon; } private BubbleTextView verifyIconTheme(String title, ViewGroup parent, boolean isThemed) { BubbleTextView icon = findBtv(title, parent); assertNotNull(icon.getIcon()); assertEquals(isThemed, icon.getIcon() instanceof ThemedIconDrawable); return icon; } private void setThemeEnabled(boolean isEnabled) throws Exception { Uri uri = new Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority(mTargetPackage + ".grid_control") .authority(targetContext().getPackageName() + ".grid_control") .appendPath("set_icon_themed") .build(); ContentValues values = new ContentValues(); values.put("boolean_value", isEnabled); try (ContentProviderClient client = mTargetContext.getContentResolver() try (ContentProviderClient client = targetContext().getContentResolver() .acquireContentProviderClient(uri)) { int result = client.update(uri, values, null); assertTrue(result > 0); } } private void scrollToAppIcon(String appName) { executeOnLauncher(l -> { l.hideKeyboard(); AllAppsRecyclerView rv = l.getAppsView().getActiveRecyclerView(); int pos = rv.getApps().getAdapterItems().indexOf(rv.getApps().getAdapterItems().stream() .filter(i -> i.itemInfo != null && appName.equals(i.itemInfo.title.toString())) .findFirst() .get()); rv.getLayoutManager().scrollToPosition(pos); }); } private void addToWorkspace(View btv) { TestUtil.runOnExecutorSync(MAIN_EXECUTOR, () -> btv.getAccessibilityDelegate().performAccessibilityAction( btv, com.android.launcher3.R.id.action_add_to_workspace, null)); UiDevice.getInstance(getInstrumentation()).waitForIdle(); } } tests/src/com/android/launcher3/util/BaseLauncherActivityTest.kt +9 −2 Original line number Diff line number Diff line Loading @@ -69,8 +69,9 @@ open class BaseLauncherActivityTest<LAUNCHER_TYPE : Launcher> { protected fun targetContext(): Context = getInstrumentation().targetContext protected fun goToState(state: LauncherState) = executeOnLauncher { it.stateManager.goToState(state, 0) protected fun goToState(state: LauncherState) { executeOnLauncher { it.stateManager.goToState(state, 0) } UiDevice.getInstance(getInstrumentation()).waitForIdle() } protected fun executeOnLauncher(f: ActivityAction<LAUNCHER_TYPE>) = scenario.onActivity(f) Loading @@ -92,6 +93,12 @@ open class BaseLauncherActivityTest<LAUNCHER_TYPE : Launcher> { condition: Function<LAUNCHER_TYPE, Boolean>, ) = atMost(message, { getFromLauncher(condition)!! }) protected fun waitForLauncherCondition( message: String, condition: Function<LAUNCHER_TYPE, Boolean>, timeout: Long, ) = atMost(message, { getFromLauncher(condition)!! }, null, timeout) protected fun <T> getOnceNotNull(message: String, f: Function<LAUNCHER_TYPE, T?>): T? { var output: T? = null atMost( Loading Loading
tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java→tests/src/com/android/launcher3/ui/WorkProfileTest.java +24 −45 Original line number Diff line number Diff line Loading @@ -17,9 +17,7 @@ package com.android.launcher3.ui; import static com.android.launcher3.LauncherPrefs.WORK_EDU_STEP; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.allapps.AllAppsStore.DEFER_UPDATES_TEST; import static com.android.launcher3.testing.shared.TestProtocol.NORMAL_STATE_ORDINAL; import static com.android.launcher3.util.TestUtil.installDummyAppForUser; import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL; import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT; Loading @@ -43,36 +41,39 @@ import com.android.launcher3.allapps.AllAppsPagedView; import com.android.launcher3.allapps.WorkEduCard; import com.android.launcher3.allapps.WorkPausedCard; import com.android.launcher3.allapps.WorkProfileManager; import com.android.launcher3.tapl.LauncherInstrumentation; import com.android.launcher3.util.BaseLauncherActivityTest; import com.android.launcher3.util.TestUtil; import com.android.launcher3.util.rule.ScreenRecordRule; import com.android.launcher3.util.rule.TestStabilityRule; import com.android.launcher3.util.rule.TestStabilityRule.Stability; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import java.io.IOException; import java.util.Objects; import java.util.function.Predicate; @LargeTest @RunWith(AndroidJUnit4.class) public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { public class WorkProfileTest extends BaseLauncherActivityTest<Launcher> { private static final int WORK_PAGE = ActivityAllAppsContainerView.AdapterHolder.WORK; public static final int WAIT_TIME_MS = 30000; @Rule public ScreenRecordRule mScreenRecordRule = new ScreenRecordRule(); @Rule public TestStabilityRule mTestStabilityRule = new TestStabilityRule(); private int mProfileUserId; private boolean mWorkProfileSetupSuccessful; private final String TAG = "WorkProfileTest"; private static final String TAG = "WorkProfileTest"; @Before @Override public void setUp() throws Exception { super.setUp(); String output = mDevice.executeShellCommand( "pm create-user --profileOf 0 --managed TestProfile"); String output = executeShellCommand("pm create-user --profileOf 0 --managed TestProfile"); updateWorkProfileSetupSuccessful("pm create-user", output); String[] tokens = output.split("\\s+"); Loading @@ -88,36 +89,15 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { return; // no need to setup launcher since all tests will skip. } mDevice.pressHome(); waitForLauncherCondition("Launcher didn't start", Objects::nonNull); waitForStateTransitionToEnd("Launcher internal state didn't switch to Normal", () -> NORMAL); waitForResumed("Launcher internal state is still Background"); mLauncher.getWorkspace().switchToAllApps(); waitForStateTransitionToEnd("Launcher internal state didn't switch to All Apps", () -> ALL_APPS); loadLauncherSync(); goToState(ALL_APPS); waitForState("Launcher internal state didn't switch to All Apps", () -> ALL_APPS); } @After public void removeWorkProfile() throws Exception { executeOnLauncherInTearDown(launcher -> { if (launcher.getAppsView() == null) { return; } launcher.getAppsView().getAppsStore().disableDeferUpdates(DEFER_UPDATES_TEST); }); TestUtil.uninstallDummyApp(); mLauncher.runToState( () -> { try { mDevice.executeShellCommand("pm remove-user --wait " + mProfileUserId); } catch (IOException e) { throw new RuntimeException(e); } }, NORMAL_STATE_ORDINAL, "executing pm 'remove-user' command"); executeShellCommand("pm remove-user --wait " + mProfileUserId); } private void waitForWorkTabSetup() { Loading @@ -127,7 +107,7 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { return true; } return false; }, LauncherInstrumentation.WAIT_TIME_MS); }, WAIT_TIME_MS); } @Test Loading @@ -137,10 +117,10 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { waitForWorkTabSetup(); waitForLauncherCondition("Personal tab is missing", launcher -> launcher.getAppsView().isPersonalTabVisible(), LauncherInstrumentation.WAIT_TIME_MS); WAIT_TIME_MS); waitForLauncherCondition("Work tab is missing", launcher -> launcher.getAppsView().isWorkTabVisible(), LauncherInstrumentation.WAIT_TIME_MS); WAIT_TIME_MS); } // Staging; will be promoted to presubmit if stable Loading @@ -156,12 +136,11 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { WorkProfileManager manager = getFromLauncher(l -> l.getAppsView().getWorkManager()); waitForLauncherCondition("work profile initial state check failed", launcher -> manager.getWorkUtilityView() != null && manager.getCurrentState() == WorkProfileManager.STATE_ENABLED && manager.getWorkUtilityView().isEnabled(), LauncherInstrumentation.WAIT_TIME_MS); WAIT_TIME_MS); //start work profile toggle OFF test executeOnLauncher(l -> { Loading @@ -173,7 +152,7 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { waitForLauncherCondition("Work profile toggle OFF failed", launcher -> { manager.reset(); // pulls current state from system return manager.getCurrentState() == WorkProfileManager.STATE_DISABLED; }, LauncherInstrumentation.WAIT_TIME_MS); }, WAIT_TIME_MS); waitForWorkCard("Work paused card not shown", view -> view instanceof WorkPausedCard); Loading @@ -188,7 +167,7 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { waitForLauncherCondition("Work profile toggle ON failed", launcher -> { manager.reset(); // pulls current state from system return manager.getCurrentState() == WorkProfileManager.STATE_ENABLED; }, LauncherInstrumentation.WAIT_TIME_MS); }, WAIT_TIME_MS); } Loading @@ -215,7 +194,7 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> { } finally { l.getAppsView().getAppsStore().enableDeferUpdates(DEFER_UPDATES_TEST); } }, LauncherInstrumentation.WAIT_TIME_MS); }, WAIT_TIME_MS); } private void updateWorkProfileSetupSuccessful(String cli, String output) { Loading
tests/src/com/android/launcher3/ui/workspace/TaplThemeIconsTest.java→tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java +203 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,10 @@ */ package com.android.launcher3.ui.workspace; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static com.android.launcher3.AbstractFloatingView.TYPE_ACTION_POPUP; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME; import static org.junit.Assert.assertEquals; Loading @@ -29,15 +33,19 @@ import android.view.View; import android.view.ViewGroup; import androidx.test.filters.LargeTest; import androidx.test.uiautomator.UiDevice; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BubbleTextView; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.allapps.AllAppsRecyclerView; import com.android.launcher3.celllayout.FavoriteItemsTransaction; import com.android.launcher3.icons.ThemedIconDrawable; import com.android.launcher3.tapl.HomeAllApps; import com.android.launcher3.tapl.HomeAppIcon; import com.android.launcher3.tapl.HomeAppIconMenuItem; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.popup.ArrowPopup; import com.android.launcher3.util.BaseLauncherActivityTest; import com.android.launcher3.util.Executors; import com.android.launcher3.util.TestUtil; import org.junit.Test; Loading @@ -50,7 +58,7 @@ import java.util.Queue; * Note running these tests will clear the workspace on the device. */ @LargeTest public class TaplThemeIconsTest extends AbstractLauncherUiTest<Launcher> { public class ThemeIconsTest extends BaseLauncherActivityTest<Launcher> { private static final String APP_NAME = "IconThemedActivity"; private static final String SHORTCUT_NAME = "Shortcut 1"; Loading @@ -58,78 +66,71 @@ public class TaplThemeIconsTest extends AbstractLauncherUiTest<Launcher> { @Test public void testIconWithoutTheme() throws Exception { setThemeEnabled(false); initialize(this); HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps(); allApps.freeze(); try { HomeAppIcon icon = allApps.getAppIcon(APP_NAME); executeOnLauncher(l -> verifyIconTheme(APP_NAME, l.getAppsView(), false)); icon.dragToWorkspace(false, false); new FavoriteItemsTransaction(targetContext()).commit(); loadLauncherSync(); goToState(LauncherState.ALL_APPS); freezeAllApps(); scrollToAppIcon(APP_NAME); BubbleTextView btv = getFromLauncher( l -> verifyIconTheme(APP_NAME, l.getAppsView(), false)); addToWorkspace(btv); executeOnLauncher(l -> verifyIconTheme(APP_NAME, l.getWorkspace(), false)); } finally { allApps.unfreeze(); } } @Test public void testShortcutIconWithoutTheme() throws Exception { setThemeEnabled(false); initialize(this); HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps(); allApps.freeze(); try { HomeAppIcon icon = allApps.getAppIcon(TEST_APP_NAME); HomeAppIconMenuItem shortcutItem = (HomeAppIconMenuItem) icon.openDeepShortcutMenu().getMenuItem(SHORTCUT_NAME); shortcutItem.dragToWorkspace(false, false); new FavoriteItemsTransaction(targetContext()).commit(); loadLauncherSync(); goToState(LauncherState.ALL_APPS); freezeAllApps(); scrollToAppIcon(TEST_APP_NAME); BubbleTextView btv = getFromLauncher(l -> findBtv(TEST_APP_NAME, l.getAppsView())); TestUtil.runOnExecutorSync(MAIN_EXECUTOR, btv::performLongClick); BubbleTextView menuItem = getOnceNotNull("Popup menu not open", l -> (AbstractFloatingView.getOpenView(l, TYPE_ACTION_POPUP) instanceof ArrowPopup ap) ? findBtv(SHORTCUT_NAME, ap) : null); addToWorkspace(menuItem); executeOnLauncher(l -> verifyIconTheme(SHORTCUT_NAME, l.getWorkspace(), false)); } finally { allApps.unfreeze(); } } @Test public void testIconWithTheme() throws Exception { setThemeEnabled(true); initialize(this); HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps(); allApps.freeze(); try { HomeAppIcon icon = allApps.getAppIcon(APP_NAME); executeOnLauncher(l -> verifyIconTheme(APP_NAME, l.getAppsView(), false)); icon.dragToWorkspace(false, false); new FavoriteItemsTransaction(targetContext()).commit(); loadLauncherSync(); goToState(LauncherState.ALL_APPS); freezeAllApps(); scrollToAppIcon(APP_NAME); BubbleTextView btv = getFromLauncher(l -> verifyIconTheme(APP_NAME, l.getAppsView(), false)); addToWorkspace(btv); executeOnLauncher(l -> verifyIconTheme(APP_NAME, l.getWorkspace(), true)); } finally { allApps.unfreeze(); } } @Test public void testShortcutIconWithTheme() throws Exception { setThemeEnabled(true); initialize(this); HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps(); allApps.freeze(); try { HomeAppIcon icon = allApps.getAppIcon(TEST_APP_NAME); HomeAppIconMenuItem shortcutItem = (HomeAppIconMenuItem) icon.openDeepShortcutMenu().getMenuItem(SHORTCUT_NAME); shortcutItem.dragToWorkspace(false, false); loadLauncherSync(); goToState(LauncherState.ALL_APPS); freezeAllApps(); scrollToAppIcon(TEST_APP_NAME); BubbleTextView btv = getFromLauncher(l -> findBtv(TEST_APP_NAME, l.getAppsView())); TestUtil.runOnExecutorSync(MAIN_EXECUTOR, btv::performLongClick); BubbleTextView menuItem = getOnceNotNull("Popup menu not open", l -> (AbstractFloatingView.getOpenView(l, TYPE_ACTION_POPUP) instanceof ArrowPopup ap) ? findBtv(SHORTCUT_NAME, ap) : null); addToWorkspace(menuItem); executeOnLauncher(l -> verifyIconTheme(SHORTCUT_NAME, l.getWorkspace(), true)); } finally { allApps.unfreeze(); } } private void verifyIconTheme(String title, ViewGroup parent, boolean isThemed) { private BubbleTextView findBtv(String title, ViewGroup parent) { // Wait for Launcher model to be completed try { Executors.MODEL_EXECUTOR.submit(() -> { }).get(); Loading @@ -149,29 +150,54 @@ public class TaplThemeIconsTest extends AbstractLauncherUiTest<Launcher> { viewQueue.add(parent.getChildAt(i)); } } else if (view instanceof BubbleTextView btv) { if (title.equals(btv.getContentDescription().toString())) { if (btv.getContentDescription() != null && title.equals(btv.getContentDescription().toString())) { icon = btv; break; } } } return icon; } private BubbleTextView verifyIconTheme(String title, ViewGroup parent, boolean isThemed) { BubbleTextView icon = findBtv(title, parent); assertNotNull(icon.getIcon()); assertEquals(isThemed, icon.getIcon() instanceof ThemedIconDrawable); return icon; } private void setThemeEnabled(boolean isEnabled) throws Exception { Uri uri = new Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority(mTargetPackage + ".grid_control") .authority(targetContext().getPackageName() + ".grid_control") .appendPath("set_icon_themed") .build(); ContentValues values = new ContentValues(); values.put("boolean_value", isEnabled); try (ContentProviderClient client = mTargetContext.getContentResolver() try (ContentProviderClient client = targetContext().getContentResolver() .acquireContentProviderClient(uri)) { int result = client.update(uri, values, null); assertTrue(result > 0); } } private void scrollToAppIcon(String appName) { executeOnLauncher(l -> { l.hideKeyboard(); AllAppsRecyclerView rv = l.getAppsView().getActiveRecyclerView(); int pos = rv.getApps().getAdapterItems().indexOf(rv.getApps().getAdapterItems().stream() .filter(i -> i.itemInfo != null && appName.equals(i.itemInfo.title.toString())) .findFirst() .get()); rv.getLayoutManager().scrollToPosition(pos); }); } private void addToWorkspace(View btv) { TestUtil.runOnExecutorSync(MAIN_EXECUTOR, () -> btv.getAccessibilityDelegate().performAccessibilityAction( btv, com.android.launcher3.R.id.action_add_to_workspace, null)); UiDevice.getInstance(getInstrumentation()).waitForIdle(); } }
tests/src/com/android/launcher3/util/BaseLauncherActivityTest.kt +9 −2 Original line number Diff line number Diff line Loading @@ -69,8 +69,9 @@ open class BaseLauncherActivityTest<LAUNCHER_TYPE : Launcher> { protected fun targetContext(): Context = getInstrumentation().targetContext protected fun goToState(state: LauncherState) = executeOnLauncher { it.stateManager.goToState(state, 0) protected fun goToState(state: LauncherState) { executeOnLauncher { it.stateManager.goToState(state, 0) } UiDevice.getInstance(getInstrumentation()).waitForIdle() } protected fun executeOnLauncher(f: ActivityAction<LAUNCHER_TYPE>) = scenario.onActivity(f) Loading @@ -92,6 +93,12 @@ open class BaseLauncherActivityTest<LAUNCHER_TYPE : Launcher> { condition: Function<LAUNCHER_TYPE, Boolean>, ) = atMost(message, { getFromLauncher(condition)!! }) protected fun waitForLauncherCondition( message: String, condition: Function<LAUNCHER_TYPE, Boolean>, timeout: Long, ) = atMost(message, { getFromLauncher(condition)!! }, null, timeout) protected fun <T> getOnceNotNull(message: String, f: Function<LAUNCHER_TYPE, T?>): T? { var output: T? = null atMost( Loading