mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-01 00:06:47 +00:00
Merge "Waiting for app install to finish before procedding with the test" into tm-qpr-dev am: 12aec8aa29
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/20378370 Change-Id: I7edf46fddca38fb0b9b0e41cfbbc7830469521d5 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package com.android.launcher3.testing;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
@@ -248,6 +249,9 @@ public class DebugTestInformationHandler extends TestInformationHandler {
|
||||
return response;
|
||||
}
|
||||
|
||||
case TestProtocol.REQUEST_MODEL_QUEUE_CLEARED:
|
||||
return getFromExecutorSync(MODEL_EXECUTOR, Bundle::new);
|
||||
|
||||
default:
|
||||
return super.call(method, arg, extras);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,9 @@ import com.android.launcher3.testing.shared.WorkspaceCellCenterRequest;
|
||||
import com.android.launcher3.util.ResourceBasedOverride;
|
||||
import com.android.launcher3.widget.picker.WidgetsFullSheet;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -214,8 +216,7 @@ public class TestInformationHandler implements ResourceBasedOverride {
|
||||
}
|
||||
|
||||
case TestProtocol.REQUEST_HAS_TIS: {
|
||||
response.putBoolean(
|
||||
TestProtocol.REQUEST_HAS_TIS, false);
|
||||
response.putBoolean(TestProtocol.REQUEST_HAS_TIS, false);
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -266,17 +267,24 @@ public class TestInformationHandler implements ResourceBasedOverride {
|
||||
*/
|
||||
private static <S, T> Bundle getUIProperty(
|
||||
BundleSetter<T> bundleSetter, Function<S, T> provider, Supplier<S> targetSupplier) {
|
||||
return getFromExecutorSync(MAIN_EXECUTOR, () -> {
|
||||
S target = targetSupplier.get();
|
||||
if (target == null) {
|
||||
return null;
|
||||
}
|
||||
T value = provider.apply(target);
|
||||
Bundle response = new Bundle();
|
||||
bundleSetter.set(response, TestProtocol.TEST_INFO_RESPONSE_FIELD, value);
|
||||
return response;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the callback on the executor and waits for the result
|
||||
*/
|
||||
protected static <T> T getFromExecutorSync(ExecutorService executor, Callable<T> callback) {
|
||||
try {
|
||||
return MAIN_EXECUTOR.submit(() -> {
|
||||
S target = targetSupplier.get();
|
||||
if (target == null) {
|
||||
return null;
|
||||
}
|
||||
T value = provider.apply(target);
|
||||
Bundle response = new Bundle();
|
||||
bundleSetter.set(response, TestProtocol.TEST_INFO_RESPONSE_FIELD, value);
|
||||
return response;
|
||||
}).get();
|
||||
return executor.submit(callback).get();
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ public final class TestProtocol {
|
||||
public static final String REQUEST_GET_OVERVIEW_PAGE_SPACING = "get-overview-page-spacing";
|
||||
public static final String REQUEST_ENABLE_ROTATION = "enable_rotation";
|
||||
public static final String REQUEST_ENABLE_SUGGESTION = "enable-suggestion";
|
||||
public static final String REQUEST_MODEL_QUEUE_CLEARED = "model-queue-cleared";
|
||||
|
||||
public static boolean sDebugTracing = false;
|
||||
public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing";
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
|
||||
<uses-permission android:name="android.permission.READ_LOGS"/>
|
||||
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
|
||||
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
|
||||
|
||||
<application android:debuggable="true" android:extractNativeLibs="true">
|
||||
<uses-library android:name="android.test.runner"/>
|
||||
|
||||
@@ -29,7 +29,6 @@ import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Point;
|
||||
import android.os.SystemClock;
|
||||
import android.platform.test.annotations.IwTest;
|
||||
|
||||
import androidx.test.filters.LargeTest;
|
||||
@@ -479,7 +478,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
|
||||
@Test
|
||||
@PortraitLandscape
|
||||
public void testUninstallFromWorkspace() throws Exception {
|
||||
TestUtil.installDummyApp();
|
||||
installDummyAppAndWaitForUIUpdate();
|
||||
try {
|
||||
verifyAppUninstalledFromAllApps(
|
||||
createShortcutInCenterIfNotExist(DUMMY_APP_NAME).uninstall(), DUMMY_APP_NAME);
|
||||
@@ -492,10 +491,8 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
|
||||
@PortraitLandscape
|
||||
@ScreenRecord // (b/256659409)
|
||||
public void testUninstallFromAllApps() throws Exception {
|
||||
TestUtil.installDummyApp();
|
||||
installDummyAppAndWaitForUIUpdate();
|
||||
try {
|
||||
// b/256659409
|
||||
SystemClock.sleep(5000);
|
||||
Workspace workspace = mLauncher.getWorkspace();
|
||||
final HomeAllApps allApps = workspace.switchToAllApps();
|
||||
allApps.freeze();
|
||||
@@ -539,7 +536,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
|
||||
Point[] gridPositions = getCornersAndCenterPositions();
|
||||
createShortcutIfNotExist(STORE_APP_NAME, gridPositions[0]);
|
||||
createShortcutIfNotExist(MAPS_APP_NAME, gridPositions[1]);
|
||||
TestUtil.installDummyApp();
|
||||
installDummyAppAndWaitForUIUpdate();
|
||||
try {
|
||||
createShortcutIfNotExist(DUMMY_APP_NAME, gridPositions[2]);
|
||||
Map<String, Point> initialPositions =
|
||||
@@ -590,6 +587,17 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
|
||||
mLauncher.getWorkspace().getHotseatAppIcon(APP_NAME));
|
||||
}
|
||||
|
||||
private void installDummyAppAndWaitForUIUpdate() throws IOException {
|
||||
TestUtil.installDummyApp();
|
||||
// Wait for model thread completion as it may be processing
|
||||
// the install event from the SystemService
|
||||
mLauncher.waitForModelQueueCleared();
|
||||
// Wait for Launcher UI thread completion, as it may be processing updating the UI in
|
||||
// response to the model update. Not that `waitForLauncherInitialized` is just a proxy
|
||||
// method, we can use any method which touches Launcher UI thread,
|
||||
mLauncher.waitForLauncherInitialized();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return List of workspace grid coordinates. Those are not pixels. See {@link
|
||||
* Workspace#getIconGridDimensions()}
|
||||
|
||||
@@ -17,8 +17,13 @@ package com.android.launcher3.util;
|
||||
|
||||
import static androidx.test.InstrumentationRegistry.getContext;
|
||||
import static androidx.test.InstrumentationRegistry.getInstrumentation;
|
||||
import static androidx.test.InstrumentationRegistry.getTargetContext;
|
||||
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
|
||||
@@ -27,6 +32,7 @@ import org.junit.Assert;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class TestUtil {
|
||||
public static final String DUMMY_PACKAGE = "com.example.android.aardwolf";
|
||||
@@ -40,24 +46,77 @@ public class TestUtil {
|
||||
final String apkFilename = getInstrumentation().getTargetContext().
|
||||
getFilesDir().getPath() + "/dummy_app.apk";
|
||||
|
||||
final FileOutputStream out = new FileOutputStream(apkFilename);
|
||||
byte[] buff = new byte[1024];
|
||||
int read;
|
||||
try (PackageInstallCheck pic = new PackageInstallCheck()) {
|
||||
final FileOutputStream out = new FileOutputStream(apkFilename);
|
||||
byte[] buff = new byte[1024];
|
||||
int read;
|
||||
|
||||
while ((read = in.read(buff)) > 0) {
|
||||
out.write(buff, 0, read);
|
||||
while ((read = in.read(buff)) > 0) {
|
||||
out.write(buff, 0, read);
|
||||
}
|
||||
in.close();
|
||||
out.close();
|
||||
|
||||
final String result = UiDevice.getInstance(getInstrumentation())
|
||||
.executeShellCommand("pm install " + apkFilename);
|
||||
Assert.assertTrue(
|
||||
"Failed to install wellbeing test apk; make sure the device is rooted",
|
||||
"Success".equals(result.replaceAll("\\s+", "")));
|
||||
pic.mAddWait.await();
|
||||
} catch (InterruptedException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
in.close();
|
||||
out.close();
|
||||
|
||||
final String result = UiDevice.getInstance(getInstrumentation())
|
||||
.executeShellCommand("pm install " + apkFilename);
|
||||
Assert.assertTrue("Failed to install wellbeing test apk; make sure the device is rooted",
|
||||
"Success".equals(result.replaceAll("\\s+", "")));
|
||||
}
|
||||
|
||||
public static void uninstallDummyApp() throws IOException {
|
||||
UiDevice.getInstance(getInstrumentation()).executeShellCommand(
|
||||
"pm uninstall " + DUMMY_PACKAGE);
|
||||
}
|
||||
|
||||
private static class PackageInstallCheck extends LauncherApps.Callback
|
||||
implements AutoCloseable {
|
||||
|
||||
final CountDownLatch mAddWait = new CountDownLatch(1);
|
||||
final LauncherApps mLauncherApps;
|
||||
|
||||
PackageInstallCheck() {
|
||||
mLauncherApps = getTargetContext().getSystemService(LauncherApps.class);
|
||||
mLauncherApps.registerCallback(this, new Handler(Looper.getMainLooper()));
|
||||
}
|
||||
|
||||
private void verifyPackage(String packageName) {
|
||||
if (DUMMY_PACKAGE.equals(packageName)) {
|
||||
mAddWait.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageAdded(String packageName, UserHandle user) {
|
||||
verifyPackage(packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageChanged(String packageName, UserHandle user) {
|
||||
verifyPackage(packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageRemoved(String packageName, UserHandle user) { }
|
||||
|
||||
@Override
|
||||
public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) {
|
||||
for (String packageName : packageNames) {
|
||||
verifyPackage(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackagesUnavailable(String[] packageNames, UserHandle user,
|
||||
boolean replacing) { }
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
mLauncherApps.unregisterCallback(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -848,6 +848,10 @@ public final class LauncherInstrumentation {
|
||||
}
|
||||
}
|
||||
|
||||
public void waitForModelQueueCleared() {
|
||||
getTestInfo(TestProtocol.REQUEST_MODEL_QUEUE_CLEARED);
|
||||
}
|
||||
|
||||
public void waitForLauncherInitialized() {
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
if (getTestInfo(
|
||||
|
||||
Reference in New Issue
Block a user