Removing methods from BaseLauncherActivityTest to make tests by composition

Bug: 324261526
Flag: EXEMPT test only
Test: All test using BaseLauncherActivityTest
Change-Id: If7cbe84b219b174cd51fac20f104080f735c03f4
This commit is contained in:
Sebastian Franco
2025-05-23 10:08:57 -07:00
parent 48e7365190
commit c5f5569f52
4 changed files with 45 additions and 42 deletions
@@ -63,7 +63,7 @@ public class LauncherIntentTest extends BaseLauncherActivityTest<Launcher> {
private void moveToSearchView() {
// All Apps view should be loaded
assertTrue("Launcher internal state is not All Apps",
isInState(() -> LauncherState.ALL_APPS));
getLauncherActivity().isInState(() -> LauncherState.ALL_APPS));
getLauncherActivity().executeOnLauncher(
launcher -> launcher.getAppsView().getSearchView().requestFocus()
);
@@ -71,20 +71,20 @@ public class LauncherIntentTest extends BaseLauncherActivityTest<Launcher> {
waitForLauncherCondition("Search view is not in focus.",
launcher -> launcher.getAppsView().getSearchView().hasFocus());
injectKeyEvent(KeyEvent.KEYCODE_C, true);
getLauncherActivity().injectKeyEvent(KeyEvent.KEYCODE_C, true);
// Upon key press, search recycler view should be loaded
waitForLauncherCondition("Search view not active.",
launcher -> launcher.getAppsView().getActiveRecyclerView()
instanceof SearchRecyclerView);
injectKeyEvent(KeyEvent.KEYCODE_C, false);
getLauncherActivity().injectKeyEvent(KeyEvent.KEYCODE_C, false);
}
// Checks if main adapter view is selected, search bar is out of focus and scroller is at start.
private void assertOnMainAdapterAToZView() {
// All Apps State should be loaded
assertTrue("Launcher internal state is not All Apps",
isInState(() -> LauncherState.ALL_APPS));
getLauncherActivity().isInState(() -> LauncherState.ALL_APPS));
// A-Z recycler view should be active.
waitForLauncherCondition("A-Z view not active.",
@@ -38,8 +38,8 @@ public class KeyboardFocusTest extends BaseLauncherActivityTest<Launcher> {
getLauncherActivity().goToState(LauncherState.ALL_APPS);
freezeAllApps();
injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, true);
injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, false);
getLauncherActivity().injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, true);
getLauncherActivity().injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, false);
waitForLauncherCondition("No focused child", launcher ->
launcher.getAppsView().getActiveRecyclerView().getApps().getFocusedChild()
!= null);
@@ -56,8 +56,8 @@ public class KeyboardFocusTest extends BaseLauncherActivityTest<Launcher> {
waitForLauncherCondition("Search view does not have focus.",
launcher -> launcher.getAppsView().getSearchView().hasFocus());
injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, true);
injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, false);
getLauncherActivity().injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, true);
getLauncherActivity().injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, false);
waitForLauncherCondition("No focused child", launcher ->
launcher.getAppsView().getActiveRecyclerView().getApps().getFocusedChild()
!= null);
@@ -74,11 +74,11 @@ public class KeyboardFocusTest extends BaseLauncherActivityTest<Launcher> {
waitForLauncherCondition("Search view does not have focus.",
launcher -> launcher.getAppsView().getSearchView().hasFocus());
injectKeyEvent(KeyEvent.KEYCODE_C, true);
getLauncherActivity().injectKeyEvent(KeyEvent.KEYCODE_C, true);
waitForLauncherCondition("Search view not active.",
launcher -> launcher.getAppsView().getActiveRecyclerView()
instanceof SearchRecyclerView);
injectKeyEvent(KeyEvent.KEYCODE_C, false);
getLauncherActivity().injectKeyEvent(KeyEvent.KEYCODE_C, false);
getLauncherActivity().executeOnLauncher(
launcher -> launcher.getAppsView().getSearchUiManager().getEditText()
@@ -86,8 +86,8 @@ public class KeyboardFocusTest extends BaseLauncherActivityTest<Launcher> {
waitForLauncherCondition("Keyboard still visible.",
ActivityContext::isSoftwareKeyboardHidden);
injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, true);
injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, false);
getLauncherActivity().injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, true);
getLauncherActivity().injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, false);
waitForLauncherCondition("No focused child", launcher ->
launcher.getAppsView().getActiveRecyclerView().getApps().getFocusedChild()
!= null);
@@ -17,6 +17,11 @@
package com.android.launcher3.integration.util
import android.content.Context
import android.os.SystemClock
import android.view.InputDevice
import android.view.KeyCharacterMap
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import androidx.core.view.children
@@ -24,6 +29,8 @@ import androidx.lifecycle.Lifecycle
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ActivityScenario.ActivityAction
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.uiautomator.UiDevice
import com.android.launcher3.Launcher
import com.android.launcher3.LauncherState
import com.android.launcher3.debug.TestEventEmitter.TestEvent
@@ -37,6 +44,7 @@ import java.util.ArrayDeque
import java.util.Queue
import java.util.concurrent.atomic.AtomicReference
import java.util.function.Function
import java.util.function.Supplier
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
@@ -48,6 +56,8 @@ open class LauncherActivityScenarioRule<LAUNCHER_TYPE : Launcher>(
private var currentScenario: ActivityScenario<LAUNCHER_TYPE>? = null
@JvmField val uiDevice = UiDevice.getInstance(getInstrumentation())
val activity: ActivityScenario<LAUNCHER_TYPE>
get() =
currentScenario
@@ -112,6 +122,29 @@ open class LauncherActivityScenarioRule<LAUNCHER_TYPE : Launcher>(
return output
}
@JvmOverloads
fun injectKeyEvent(keyCode: Int, actionDown: Boolean, metaState: Int = 0) {
uiDevice.waitForIdle()
val eventTime = SystemClock.uptimeMillis()
val event =
KeyEvent(
eventTime,
eventTime,
if (actionDown) KeyEvent.ACTION_DOWN else MotionEvent.ACTION_UP,
keyCode,
/* repeat= */ 0,
metaState,
KeyCharacterMap.VIRTUAL_KEYBOARD,
/* scancode= */ 0,
/* flags= */ 0,
InputDevice.SOURCE_KEYBOARD,
)
executeOnLauncher { it.dispatchKeyEvent(event) }
}
fun isInState(state: Supplier<LauncherState>): Boolean =
getFromLauncher { it.stateManager.state == state.get() }!!
/**
* For the given view, it iterates over all of the child views in a preorder traversal returning
* the first match to the filter
@@ -17,11 +17,6 @@ package com.android.launcher3.util
import android.content.Context
import android.content.Intent
import android.os.SystemClock
import android.view.InputDevice
import android.view.KeyCharacterMap
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import androidx.core.view.children
@@ -29,14 +24,12 @@ import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.uiautomator.UiDevice
import com.android.launcher3.Launcher
import com.android.launcher3.LauncherAppState
import com.android.launcher3.LauncherState
import com.android.launcher3.R
import com.android.launcher3.allapps.AllAppsStore.DEFER_UPDATES_TEST
import com.android.launcher3.integration.util.LauncherActivityScenarioRule
import com.android.launcher3.util.ModelTestExtensions.loadModelSync
import com.android.launcher3.util.Wait.atMost
import java.util.function.Predicate
import java.util.function.Supplier
import org.junit.Rule
/**
@@ -59,9 +52,6 @@ open class BaseLauncherActivityTest<LAUNCHER_TYPE : Launcher> {
protected fun targetContext(): Context = getInstrumentation().targetContext
protected fun isInState(state: Supplier<LauncherState>): Boolean =
launcherActivity.getFromLauncher { it.stateManager.state == state.get() }!!
protected fun waitForLauncherCondition(message: String, condition: (LAUNCHER_TYPE) -> Boolean) =
atMost(message, { launcherActivity.getFromLauncher(condition)!! })
@@ -71,26 +61,6 @@ open class BaseLauncherActivityTest<LAUNCHER_TYPE : Launcher> {
timeout: Long,
) = atMost(message, { launcherActivity.getFromLauncher(condition)!! }, null, timeout)
@JvmOverloads
protected fun injectKeyEvent(keyCode: Int, actionDown: Boolean, metaState: Int = 0) {
uiDevice.waitForIdle()
val eventTime = SystemClock.uptimeMillis()
val event =
KeyEvent(
eventTime,
eventTime,
if (actionDown) KeyEvent.ACTION_DOWN else MotionEvent.ACTION_UP,
keyCode,
/* repeat= */ 0,
metaState,
KeyCharacterMap.VIRTUAL_KEYBOARD,
/* scancode= */ 0,
/* flags= */ 0,
InputDevice.SOURCE_KEYBOARD,
)
launcherActivity.executeOnLauncher { it.dispatchKeyEvent(event) }
}
@JvmOverloads
fun startAppFast(
packageName: String,