Merge changes If9b31b3b,Iea400614,I9567aaf5,I6696029f,I3d4f434e, ...
* changes:
Don't show new groups until their children inflate
Cleanup PreparationCoordinator a bit
Add onCleanup() method to Pluggables
Introduce GroupEntryBuilder
NotificationEntryBuilder can modify existing entries
Move creationTime into ListEntry (from NotifEntry)
diff --git a/apct-tests/perftests/autofill/src/android/view/autofill/AbstractAutofillPerfTestCase.java b/apct-tests/perftests/autofill/src/android/view/autofill/AbstractAutofillPerfTestCase.java
index 48ce8ab..8f8fc29e 100644
--- a/apct-tests/perftests/autofill/src/android/view/autofill/AbstractAutofillPerfTestCase.java
+++ b/apct-tests/perftests/autofill/src/android/view/autofill/AbstractAutofillPerfTestCase.java
@@ -26,7 +26,6 @@
import android.provider.Settings;
import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
import org.junit.After;
@@ -37,7 +36,6 @@
/**
* Base class for all autofill tests.
*/
-@LargeTest
public abstract class AbstractAutofillPerfTestCase {
@ClassRule
diff --git a/apct-tests/perftests/autofill/src/android/view/autofill/LoginTest.java b/apct-tests/perftests/autofill/src/android/view/autofill/LoginTest.java
index fb5ea80..5f52dc7 100644
--- a/apct-tests/perftests/autofill/src/android/view/autofill/LoginTest.java
+++ b/apct-tests/perftests/autofill/src/android/view/autofill/LoginTest.java
@@ -24,10 +24,14 @@
import android.view.View;
import android.widget.EditText;
+import androidx.test.filters.LargeTest;
+
import com.android.perftests.autofill.R;
+import org.junit.Ignore;
import org.junit.Test;
+@LargeTest
public class LoginTest extends AbstractAutofillPerfTestCase {
private EditText mUsername;
@@ -90,6 +94,8 @@
/**
* Now the service returns autofill data, for both username and password.
*/
+ // TODO(b/162216576): fix fail test and re-enable it
+ @Ignore
@Test
public void testFocus_autofillBothFields() throws Throwable {
MyAutofillService.newCannedResponse()
@@ -142,6 +148,8 @@
/**
* Now the service returns autofill data, but just for username.
*/
+ // TODO(b/162216576): fix fail test and re-enable it
+ @Ignore
@Test
public void testFocus_autofillUsernameOnly() throws Throwable {
// Must set ignored ids so focus on password does not trigger new requests
@@ -258,6 +266,8 @@
});
}
+ // TODO(b/162216576): fix fail test and re-enable it
+ @Ignore
@Test
public void testCallbacks() throws Throwable {
MyAutofillService.newCannedResponse()
diff --git a/apct-tests/perftests/contentcapture/src/android/view/contentcapture/AbstractContentCapturePerfTestCase.java b/apct-tests/perftests/contentcapture/src/android/view/contentcapture/AbstractContentCapturePerfTestCase.java
index f02c96d..9b853fe 100644
--- a/apct-tests/perftests/contentcapture/src/android/view/contentcapture/AbstractContentCapturePerfTestCase.java
+++ b/apct-tests/perftests/contentcapture/src/android/view/contentcapture/AbstractContentCapturePerfTestCase.java
@@ -33,7 +33,6 @@
import android.util.Log;
import androidx.annotation.NonNull;
-import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
import com.android.compatibility.common.util.ActivitiesWatcher;
@@ -51,7 +50,6 @@
/**
* Base class for all content capture tests.
*/
-@LargeTest
public abstract class AbstractContentCapturePerfTestCase {
private static final String TAG = AbstractContentCapturePerfTestCase.class.getSimpleName();
diff --git a/apct-tests/perftests/contentcapture/src/android/view/contentcapture/LoginTest.java b/apct-tests/perftests/contentcapture/src/android/view/contentcapture/LoginTest.java
index 750d3b4..7257509 100644
--- a/apct-tests/perftests/contentcapture/src/android/view/contentcapture/LoginTest.java
+++ b/apct-tests/perftests/contentcapture/src/android/view/contentcapture/LoginTest.java
@@ -21,11 +21,14 @@
import android.perftests.utils.BenchmarkState;
import android.view.View;
+import androidx.test.filters.LargeTest;
+
import com.android.compatibility.common.util.ActivitiesWatcher.ActivityWatcher;
import com.android.perftests.contentcapture.R;
import org.junit.Test;
+@LargeTest
public class LoginTest extends AbstractContentCapturePerfTestCase {
@Test
diff --git a/api/test-current.txt b/api/test-current.txt
index 866b9383..963ef7c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -553,11 +553,13 @@
method public int getActivityType();
method public android.graphics.Rect getAppBounds();
method public android.graphics.Rect getBounds();
+ method @NonNull public android.graphics.Rect getMaxBounds();
method public int getRotation();
method public int getWindowingMode();
method public void setActivityType(int);
method public void setAppBounds(android.graphics.Rect);
method public void setBounds(android.graphics.Rect);
+ method public void setMaxBounds(@Nullable android.graphics.Rect);
method public void setRotation(int);
method public void setTo(android.app.WindowConfiguration);
method public void setWindowingMode(int);
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index ec81ae3..79f05a3 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -310,7 +310,6 @@
* Sets the maximum bounds to the provided {@link Rect}.
* @param rect the new bounds value.
* @see #getMaxBounds()
- * @hide
*/
public void setMaxBounds(@Nullable Rect rect) {
if (rect == null) {
@@ -364,10 +363,8 @@
return mBounds;
}
- /**
- * @see #setMaxBounds(Rect)
- * @hide
- */
+ /** @see #setMaxBounds(Rect) */
+ @NonNull
public Rect getMaxBounds() {
return mMaxBounds;
}
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 15625cd..decf053 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -683,6 +683,8 @@
*<p>BACKWARD_COMPATIBLE devices capable of streaming concurrently with other devices as described by
* {@link android.hardware.camera2.CameraManager#getConcurrentCameraIds} have the
* following guaranteed streams (when streaming concurrently with other devices)</p>
+ * <p> Note: The sizes mentioned for these concurrent streams are the maximum sizes guaranteed
+ * to be supported. Sizes smaller than these, obtained by {@link StreamConfigurationMap#getOutputSizes} for a particular format, are supported as well. </p>
*
* <table>
* <tr><th colspan="5">Concurrent stream guaranteed configurations</th></tr>
@@ -696,7 +698,7 @@
* </table><br>
* </p>
*
- * <p> Devices which are not backwards-compatible, support a mandatory single stream of size sVGA with image format {@code DEPTH16} during concurrent operation.
+ * <p> Devices which are not backwards-compatible, support a mandatory single stream of size sVGA with image format {@code DEPTH16} during concurrent operation. </p>
*
* <p> For guaranteed concurrent stream configurations:</p>
* <p> sVGA refers to the camera device's maximum resolution for that format from {@link StreamConfigurationMap#getOutputSizes} or
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index ffb087f..5d4003a 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -608,7 +608,7 @@
public static final int TYPE_BLUETOOTH = 7;
/**
- * Dummy data connection. This should not be used on shipping devices.
+ * Fake data connection. This should not be used on shipping devices.
* @deprecated This is not used any more.
*/
@Deprecated
@@ -1084,9 +1084,9 @@
* to remove an existing always-on VPN configuration.
* @param lockdownEnabled {@code true} to disallow networking when the VPN is not connected or
* {@code false} otherwise.
- * @param lockdownWhitelist The list of packages that are allowed to access network directly
+ * @param lockdownAllowlist The list of packages that are allowed to access network directly
* when VPN is in lockdown mode but is not running. Non-existent packages are ignored so
- * this method must be called when a package that should be whitelisted is installed or
+ * this method must be called when a package that should be allowed is installed or
* uninstalled.
* @return {@code true} if the package is set as always-on VPN controller;
* {@code false} otherwise.
@@ -1094,10 +1094,10 @@
*/
@RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage,
- boolean lockdownEnabled, @Nullable List<String> lockdownWhitelist) {
+ boolean lockdownEnabled, @Nullable List<String> lockdownAllowlist) {
try {
return mService.setAlwaysOnVpnPackage(
- userId, vpnPackage, lockdownEnabled, lockdownWhitelist);
+ userId, vpnPackage, lockdownEnabled, lockdownAllowlist);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java
index e449615..713b688 100644
--- a/core/java/android/net/NetworkState.java
+++ b/core/java/android/net/NetworkState.java
@@ -28,7 +28,7 @@
* @hide
*/
public class NetworkState implements Parcelable {
- private static final boolean SANITY_CHECK_ROAMING = false;
+ private static final boolean VALIDATE_ROAMING_STATE = false;
public static final NetworkState EMPTY = new NetworkState(null, null, null, null, null, null);
@@ -52,7 +52,7 @@
// This object is an atomic view of a network, so the various components
// should always agree on roaming state.
- if (SANITY_CHECK_ROAMING && networkInfo != null && networkCapabilities != null) {
+ if (VALIDATE_ROAMING_STATE && networkInfo != null && networkCapabilities != null) {
if (networkInfo.isRoaming() == networkCapabilities
.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)) {
Slog.wtf("NetworkState", "Roaming state disagreement between " + networkInfo
diff --git a/core/java/android/net/SntpClient.java b/core/java/android/net/SntpClient.java
index 8c6faf6..6c94b7a 100644
--- a/core/java/android/net/SntpClient.java
+++ b/core/java/android/net/SntpClient.java
@@ -140,7 +140,7 @@
final long receiveTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);
final long transmitTime = readTimeStamp(buffer, TRANSMIT_TIME_OFFSET);
- /* do sanity check according to RFC */
+ /* Do validation according to RFC */
// TODO: validate originateTime == requestTime.
checkValidServerReply(leap, mode, stratum, transmitTime);
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index 9c2c5b8..8e90a119 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -119,7 +119,7 @@
* <p> The Android system starts a VPN in the background by calling
* {@link android.content.Context#startService startService()}. In Android 8.0
* (API level 26) and higher, the system places VPN apps on the temporary
- * whitelist for a short period so the app can start in the background. The VPN
+ * allowlist for a short period so the app can start in the background. The VPN
* app must promote itself to the foreground after it's launched or the system
* will shut down the app.
*
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 0cc469a..c4048e5 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -26,6 +26,7 @@
import android.annotation.TestApi;
import android.app.KeyguardManager;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -1157,9 +1158,19 @@
* </p><p>
* The real size may be smaller than the physical size of the screen when the
* window manager is emulating a smaller display (using adb shell wm size).
- * </p>
+ * </p><p>
+ * In general, {@link #getRealSize(Point)} and {@link WindowManager#getMaximumWindowMetrics()}
+ * report the same bounds except that certain areas of the display may not be available to
+ * windows created in the {@link WindowManager}'s {@link Context}.
+ *
+ * For example, imagine a device which has a multi-task mode that limits windows to half of the
+ * screen. In this case, {@link WindowManager#getMaximumWindowMetrics()} reports the
+ * bounds of the screen half where the window is located, while {@link #getRealSize(Point)}
+ * still reports the bounds of the whole display.
*
* @param outSize Set to the real size of the display.
+ *
+ * @see WindowManager#getMaximumWindowMetrics()
*/
public void getRealSize(Point outSize) {
synchronized (this) {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 1d54d92..cf4315f 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -72,6 +72,7 @@
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.PixelFormat;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.IBinder;
@@ -473,9 +474,18 @@
*
* Note that this might still be smaller than the size of the physical display if certain areas
* of the display are not available to windows created in this {@link Context}.
+ * <p>
+ * For example, given that there's a device which have a multi-task mode to limit activities
+ * to a half screen. In this case, {@link #getMaximumWindowMetrics()} reports the bounds of
+ * the half screen which the activity is located, while {@link Display#getRealSize(Point)} still
+ * reports the bounds of the whole physical display.
*
- * @see #getMaximumWindowMetrics()
+ * Despite this, {@link #getMaximumWindowMetrics()} and {@link Display#getRealSize(Point)}
+ * reports the same bounds in general.
+ *
+ * @see #getCurrentWindowMetrics()
* @see WindowMetrics
+ * @see Display#getRealSize(Point)
*/
default @NonNull WindowMetrics getMaximumWindowMetrics() {
throw new UnsupportedOperationException();
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 2fe7c02..b4561c5 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -29,7 +29,6 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.graphics.Insets;
-import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Bundle;
@@ -233,17 +232,16 @@
@Override
public WindowMetrics getMaximumWindowMetrics() {
- final Rect maxBounds = getMaximumBounds();
+ final Context context = mParentWindow != null ? mParentWindow.getContext() : mContext;
+ final Rect maxBounds = getMaximumBounds(context);
+
return new WindowMetrics(maxBounds, computeWindowInsets(maxBounds));
}
- private Rect getMaximumBounds() {
- // TODO(b/128338354): Current maximum bound is display size, but it should be displayArea
- // bound after displayArea feature is finished.
- final Display display = mContext.getDisplayNoVerify();
- final Point displaySize = new Point();
- display.getRealSize(displaySize);
- return new Rect(0, 0, displaySize.x, displaySize.y);
+ private static Rect getMaximumBounds(Context context) {
+ synchronized (ResourcesManager.getInstance()) {
+ return context.getResources().getConfiguration().windowConfiguration.getMaxBounds();
+ }
}
// TODO(b/150095967): Set window type to LayoutParams
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index c216638..b85cbef 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -204,6 +204,7 @@
optional WindowContainerProto window_container = 1;
optional string name = 2 [ (.android.privacy).dest = DEST_EXPLICIT ];
repeated DisplayAreaChildProto children = 3 [deprecated=true];
+ optional bool is_task_display_area = 4;
}
/* represents a generic child of a DisplayArea */
diff --git a/libs/hwui/AutoBackendTextureRelease.cpp b/libs/hwui/AutoBackendTextureRelease.cpp
index 72747e8..33264d5 100644
--- a/libs/hwui/AutoBackendTextureRelease.cpp
+++ b/libs/hwui/AutoBackendTextureRelease.cpp
@@ -25,7 +25,8 @@
namespace android {
namespace uirenderer {
-AutoBackendTextureRelease::AutoBackendTextureRelease(GrContext* context, AHardwareBuffer* buffer) {
+AutoBackendTextureRelease::AutoBackendTextureRelease(GrDirectContext* context,
+ AHardwareBuffer* buffer) {
AHardwareBuffer_Desc desc;
AHardwareBuffer_describe(buffer, &desc);
bool createProtectedImage = 0 != (desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT);
@@ -67,8 +68,9 @@
textureRelease->unref(false);
}
-void AutoBackendTextureRelease::makeImage(AHardwareBuffer* buffer, android_dataspace dataspace,
- GrContext* context) {
+void AutoBackendTextureRelease::makeImage(AHardwareBuffer* buffer,
+ android_dataspace dataspace,
+ GrDirectContext* context) {
AHardwareBuffer_Desc desc;
AHardwareBuffer_describe(buffer, &desc);
SkColorType colorType = GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(desc.format);
@@ -81,7 +83,7 @@
}
}
-void AutoBackendTextureRelease::newBufferContent(GrContext* context) {
+void AutoBackendTextureRelease::newBufferContent(GrDirectContext* context) {
if (mBackendTexture.isValid()) {
mUpdateProc(mImageCtx, context);
}
diff --git a/libs/hwui/AutoBackendTextureRelease.h b/libs/hwui/AutoBackendTextureRelease.h
index acdd63c..06f51fc 100644
--- a/libs/hwui/AutoBackendTextureRelease.h
+++ b/libs/hwui/AutoBackendTextureRelease.h
@@ -31,7 +31,8 @@
*/
class AutoBackendTextureRelease final {
public:
- AutoBackendTextureRelease(GrContext* context, AHardwareBuffer* buffer);
+ AutoBackendTextureRelease(GrDirectContext* context,
+ AHardwareBuffer* buffer);
const GrBackendTexture& getTexture() const { return mBackendTexture; }
@@ -42,9 +43,11 @@
inline sk_sp<SkImage> getImage() const { return mImage; }
- void makeImage(AHardwareBuffer* buffer, android_dataspace dataspace, GrContext* context);
+ void makeImage(AHardwareBuffer* buffer,
+ android_dataspace dataspace,
+ GrDirectContext* context);
- void newBufferContent(GrContext* context);
+ void newBufferContent(GrDirectContext* context);
private:
// The only way to invoke dtor is with unref, when mUsageCount is 0.
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 67d8c07..6589dbd 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -189,7 +189,7 @@
sk_sp<SkImage> DeferredLayerUpdater::ImageSlot::createIfNeeded(AHardwareBuffer* buffer,
android_dataspace dataspace,
bool forceCreate,
- GrContext* context) {
+ GrDirectContext* context) {
if (!mTextureRelease || !mTextureRelease->getImage().get() || dataspace != mDataspace ||
forceCreate || mBuffer != buffer) {
if (buffer != mBuffer) {
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 05f3774..6731e9c 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -106,7 +106,7 @@
~ImageSlot() { clear(); }
sk_sp<SkImage> createIfNeeded(AHardwareBuffer* buffer, android_dataspace dataspace,
- bool forceCreate, GrContext* context);
+ bool forceCreate, GrDirectContext* context);
private:
void clear();
diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp
index c2d2ff8..8724442 100644
--- a/libs/hwui/HardwareBitmapUploader.cpp
+++ b/libs/hwui/HardwareBitmapUploader.cpp
@@ -21,7 +21,7 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES3/gl3.h>
-#include <GrContext.h>
+#include <GrDirectContext.h>
#include <SkCanvas.h>
#include <SkImage.h>
#include <utils/GLUtils.h>
@@ -285,7 +285,7 @@
return (image.get() != nullptr);
}
- sk_sp<GrContext> mGrContext;
+ sk_sp<GrDirectContext> mGrContext;
renderthread::VulkanManager mVulkanManager;
std::mutex mVkLock;
};
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index 0dea354..b71bb07 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -118,7 +118,7 @@
}
int imgWidth = image->width();
int imgHeight = image->height();
- sk_sp<GrContext> grContext = sk_ref_sp(mRenderThread.getGrContext());
+ sk_sp<GrDirectContext> grContext = sk_ref_sp(mRenderThread.getGrContext());
if (bitmap->colorType() == kRGBA_F16_SkColorType &&
!grContext->colorTypeSupportedAsSurface(bitmap->colorType())) {
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
index 14a297f..dd0fc69 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
@@ -15,7 +15,7 @@
*/
#include "GLFunctorDrawable.h"
-#include <GrContext.h>
+#include <GrDirectContext.h>
#include <private/hwui/DrawGlInfo.h>
#include "FunctorDrawable.h"
#include "GrBackendSurface.h"
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index f839213e..f95f347 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -29,7 +29,7 @@
void LayerDrawable::onDraw(SkCanvas* canvas) {
Layer* layer = mLayerUpdater->backingLayer();
if (layer) {
- DrawLayer(canvas->getGrContext(), canvas, layer, nullptr, nullptr, true);
+ DrawLayer(canvas->recordingContext(), canvas, layer, nullptr, nullptr, true);
}
}
@@ -67,8 +67,12 @@
isIntegerAligned(dstDevRect.y()));
}
-bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer,
- const SkRect* srcRect, const SkRect* dstRect,
+// TODO: Context arg probably doesn't belong here – do debug check at callsite instead.
+bool LayerDrawable::DrawLayer(GrRecordingContext* context,
+ SkCanvas* canvas,
+ Layer* layer,
+ const SkRect* srcRect,
+ const SkRect* dstRect,
bool useLayerTransform) {
if (context == nullptr) {
SkDEBUGF(("Attempting to draw LayerDrawable into an unsupported surface"));
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.h b/libs/hwui/pipeline/skia/LayerDrawable.h
index 7cd515a..ffbb480 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.h
+++ b/libs/hwui/pipeline/skia/LayerDrawable.h
@@ -32,8 +32,12 @@
public:
explicit LayerDrawable(DeferredLayerUpdater* layerUpdater) : mLayerUpdater(layerUpdater) {}
- static bool DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer, const SkRect* srcRect,
- const SkRect* dstRect, bool useLayerTransform);
+ static bool DrawLayer(GrRecordingContext* context,
+ SkCanvas* canvas,
+ Layer* layer,
+ const SkRect* srcRect,
+ const SkRect* dstRect,
+ bool useLayerTransform);
protected:
virtual SkRect onGetBounds() override {
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 206b58f..565fb61 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -190,7 +190,7 @@
auto glesVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
auto size = glesVersion ? strlen(glesVersion) : -1;
cacheManager().configureContext(&options, glesVersion, size);
- sk_sp<GrContext> grContext(GrContext::MakeGL(std::move(glInterface), options));
+ sk_sp<GrDirectContext> grContext(GrDirectContext::MakeGL(std::move(glInterface), options));
LOG_ALWAYS_FATAL_IF(!grContext.get());
setGrContext(grContext);
}
@@ -204,7 +204,7 @@
initGrContextOptions(options);
auto vkDriverVersion = mVkManager->getDriverVersion();
cacheManager().configureContext(&options, &vkDriverVersion, sizeof(vkDriverVersion));
- sk_sp<GrContext> grContext = mVkManager->createContext(options);
+ sk_sp<GrDirectContext> grContext = mVkManager->createContext(options);
LOG_ALWAYS_FATAL_IF(!grContext.get());
setGrContext(grContext);
}
@@ -263,7 +263,7 @@
return *mReadback;
}
-void RenderThread::setGrContext(sk_sp<GrContext> context) {
+void RenderThread::setGrContext(sk_sp<GrDirectContext> context) {
mCacheManager->reset(context);
if (mGrContext) {
mRenderState->onContextDestroyed();
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 2c295bc..b8ce556 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -17,7 +17,7 @@
#ifndef RENDERTHREAD_H_
#define RENDERTHREAD_H_
-#include <GrContext.h>
+#include <GrDirectContext.h>
#include <SkBitmap.h>
#include <apex/choreographer.h>
#include <cutils/compiler.h>
@@ -106,8 +106,8 @@
ProfileDataContainer& globalProfileData() { return mGlobalProfileData; }
Readback& readback();
- GrContext* getGrContext() const { return mGrContext.get(); }
- void setGrContext(sk_sp<GrContext> cxt);
+ GrDirectContext* getGrContext() const { return mGrContext.get(); }
+ void setGrContext(sk_sp<GrDirectContext> cxt);
CacheManager& cacheManager() { return *mCacheManager; }
VulkanManager& vulkanManager() { return *mVkManager; }
@@ -186,7 +186,7 @@
ProfileDataContainer mGlobalProfileData;
Readback* mReadback = nullptr;
- sk_sp<GrContext> mGrContext;
+ sk_sp<GrDirectContext> mGrContext;
CacheManager* mCacheManager;
VulkanManager* mVkManager;
};
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 3cb1607..249936e 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -20,7 +20,7 @@
#include <EGL/eglext.h>
#include <GrBackendSemaphore.h>
#include <GrBackendSurface.h>
-#include <GrContext.h>
+#include <GrDirectContext.h>
#include <GrTypes.h>
#include <android/sync.h>
#include <ui/FatVector.h>
@@ -369,7 +369,7 @@
}
}
-sk_sp<GrContext> VulkanManager::createContext(const GrContextOptions& options) {
+sk_sp<GrDirectContext> VulkanManager::createContext(const GrContextOptions& options) {
auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) {
if (device != VK_NULL_HANDLE) {
return vkGetDeviceProcAddr(device, proc_name);
@@ -388,7 +388,7 @@
backendContext.fDeviceFeatures2 = &mPhysicalDeviceFeatures2;
backendContext.fGetProc = std::move(getProc);
- return GrContext::MakeVulkan(backendContext, options);
+ return GrDirectContext::MakeVulkan(backendContext, options);
}
VkFunctorInitParams VulkanManager::getVkFunctorInitParams() const {
@@ -562,9 +562,11 @@
delete surface;
}
-VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode colorMode,
+VulkanSurface* VulkanManager::createSurface(ANativeWindow* window,
+ ColorMode colorMode,
sk_sp<SkColorSpace> surfaceColorSpace,
- SkColorType surfaceColorType, GrContext* grContext,
+ SkColorType surfaceColorType,
+ GrDirectContext* grContext,
uint32_t extraBuffers) {
LOG_ALWAYS_FATAL_IF(!hasVkContext(), "Not initialized");
if (!window) {
@@ -575,7 +577,7 @@
*this, extraBuffers);
}
-status_t VulkanManager::fenceWait(int fence, GrContext* grContext) {
+status_t VulkanManager::fenceWait(int fence, GrDirectContext* grContext) {
if (!hasVkContext()) {
ALOGE("VulkanManager::fenceWait: VkDevice not initialized");
return INVALID_OPERATION;
@@ -623,7 +625,7 @@
return OK;
}
-status_t VulkanManager::createReleaseFence(int* nativeFence, GrContext* grContext) {
+status_t VulkanManager::createReleaseFence(int* nativeFence, GrDirectContext* grContext) {
*nativeFence = -1;
if (!hasVkContext()) {
ALOGE("VulkanManager::createReleaseFence: VkDevice not initialized");
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index 8b19f13..3f2df8d 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -57,9 +57,11 @@
bool hasVkContext() { return mDevice != VK_NULL_HANDLE; }
// Create and destroy functions for wrapping an ANativeWindow in a VulkanSurface
- VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode,
+ VulkanSurface* createSurface(ANativeWindow* window,
+ ColorMode colorMode,
sk_sp<SkColorSpace> surfaceColorSpace,
- SkColorType surfaceColorType, GrContext* grContext,
+ SkColorType surfaceColorType,
+ GrDirectContext* grContext,
uint32_t extraBuffers);
void destroySurface(VulkanSurface* surface);
@@ -70,18 +72,18 @@
void destroy();
// Inserts a wait on fence command into the Vulkan command buffer.
- status_t fenceWait(int fence, GrContext* grContext);
+ status_t fenceWait(int fence, GrDirectContext* grContext);
// Creates a fence that is signaled when all the pending Vulkan commands are finished on the
// GPU.
- status_t createReleaseFence(int* nativeFence, GrContext* grContext);
+ status_t createReleaseFence(int* nativeFence, GrDirectContext* grContext);
// Returned pointers are owned by VulkanManager.
// An instance of VkFunctorInitParams returned from getVkFunctorInitParams refers to
// the internal state of VulkanManager: VulkanManager must be alive to use the returned value.
VkFunctorInitParams getVkFunctorInitParams() const;
- sk_sp<GrContext> createContext(const GrContextOptions& options);
+ sk_sp<GrDirectContext> createContext(const GrContextOptions& options);
uint32_t getDriverVersion() const { return mDriverVersion; }
diff --git a/libs/hwui/tests/unit/CacheManagerTests.cpp b/libs/hwui/tests/unit/CacheManagerTests.cpp
index a4d7b82..edd3e4e 100644
--- a/libs/hwui/tests/unit/CacheManagerTests.cpp
+++ b/libs/hwui/tests/unit/CacheManagerTests.cpp
@@ -26,7 +26,7 @@
using namespace android::uirenderer;
using namespace android::uirenderer::renderthread;
-static size_t getCacheUsage(GrContext* grContext) {
+static size_t getCacheUsage(GrDirectContext* grContext) {
size_t cacheUsage;
grContext->getResourceCacheUsage(nullptr, &cacheUsage);
return cacheUsage;
@@ -35,7 +35,7 @@
RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, trimMemory) {
int32_t width = DeviceInfo::get()->getWidth();
int32_t height = DeviceInfo::get()->getHeight();
- GrContext* grContext = renderThread.getGrContext();
+ GrDirectContext* grContext = renderThread.getGrContext();
ASSERT_TRUE(grContext != nullptr);
// create pairs of offscreen render targets and images until we exceed the
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 1038069..5721fb7 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2951,25 +2951,26 @@
if ((expecting == null) || (old == expecting)) {
mProcessNames.remove(name, uid);
}
- if (old != null && old.uidRecord != null) {
- old.uidRecord.numProcs--;
- old.uidRecord.procRecords.remove(old);
- if (old.uidRecord.numProcs == 0) {
+ final ProcessRecord record = expecting != null ? expecting : old;
+ if (record != null && record.uidRecord != null) {
+ final UidRecord uidRecord = record.uidRecord;
+ uidRecord.numProcs--;
+ uidRecord.procRecords.remove(record);
+ if (uidRecord.numProcs == 0) {
// No more processes using this uid, tell clients it is gone.
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
- "No more processes in " + old.uidRecord);
- mService.enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
+ "No more processes in " + uidRecord);
+ mService.enqueueUidChangeLocked(uidRecord, -1, UidRecord.CHANGE_GONE);
EventLogTags.writeAmUidStopped(uid);
mActiveUids.remove(uid);
mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT,
ActivityManager.PROCESS_CAPABILITY_NONE);
}
- old.uidRecord = null;
+ record.uidRecord = null;
}
mIsolatedProcesses.remove(uid);
mGlobalIsolatedUids.freeIsolatedUidLocked(uid);
// Remove the (expected) ProcessRecord from the app zygote
- final ProcessRecord record = expecting != null ? expecting : old;
if (record != null && record.appZygote) {
removeProcessFromAppZygoteLocked(record);
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java
index 86ad0b3..e9868fd 100644
--- a/services/core/java/com/android/server/net/NetworkStatsFactory.java
+++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java
@@ -59,7 +59,7 @@
private static final String TAG = "NetworkStatsFactory";
private static final boolean USE_NATIVE_PARSING = true;
- private static final boolean SANITY_CHECK_NATIVE = false;
+ private static final boolean VALIDATE_NATIVE_STATS = false;
/** Path to {@code /proc/net/xt_qtaguid/iface_stat_all}. */
private final File mStatsXtIfaceAll;
@@ -347,7 +347,7 @@
INTERFACES_ALL, TAG_ALL, mUseBpfStats) != 0) {
throw new IOException("Failed to parse network stats");
}
- if (SANITY_CHECK_NATIVE) {
+ if (VALIDATE_NATIVE_STATS) {
final NetworkStats javaStats = javaReadNetworkStatsDetail(mStatsXtUid,
UID_ALL, INTERFACES_ALL, TAG_ALL);
assertEquals(javaStats, stats);
diff --git a/services/core/java/com/android/server/net/NetworkStatsRecorder.java b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
index 9eff5d1..ce74169 100644
--- a/services/core/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
@@ -227,7 +227,7 @@
for (int i = 0; i < delta.size(); i++) {
entry = delta.getValues(i, entry);
- // As a last-ditch sanity check, report any negative values and
+ // As a last-ditch check, report any negative values and
// clamp them so recording below doesn't croak.
if (entry.isNegative()) {
if (mObserver != null) {
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 4c4680b..a2b46a0 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -3208,6 +3208,7 @@
// If we're stuck in a really low-level reboot loop, and a
// rescue party is trying to prompt the user for a factory data
// reset, we must GET TO DA CHOPPA!
+ // No check point from ShutdownCheckPoints will be dumped at this state.
PowerManagerService.lowLevelReboot(reason);
} else {
throw new IllegalStateException("Too early to call shutdown() or reboot()");
@@ -5114,6 +5115,7 @@
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
}
+ ShutdownCheckPoints.recordCheckPoint(Binder.getCallingPid(), reason);
final long ident = Binder.clearCallingIdentity();
try {
shutdownOrRebootInternal(HALT_MODE_REBOOT, confirm, reason, wait);
@@ -5132,10 +5134,11 @@
public void rebootSafeMode(boolean confirm, boolean wait) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
+ String reason = PowerManager.REBOOT_SAFE_MODE;
+ ShutdownCheckPoints.recordCheckPoint(Binder.getCallingPid(), reason);
final long ident = Binder.clearCallingIdentity();
try {
- shutdownOrRebootInternal(HALT_MODE_REBOOT_SAFE_MODE, confirm,
- PowerManager.REBOOT_SAFE_MODE, wait);
+ shutdownOrRebootInternal(HALT_MODE_REBOOT_SAFE_MODE, confirm, reason, wait);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -5151,6 +5154,7 @@
public void shutdown(boolean confirm, String reason, boolean wait) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
+ ShutdownCheckPoints.recordCheckPoint(Binder.getCallingPid(), reason);
final long ident = Binder.clearCallingIdentity();
try {
shutdownOrRebootInternal(HALT_MODE_SHUTDOWN, confirm, reason, wait);
diff --git a/services/core/java/com/android/server/power/ShutdownCheckPoints.java b/services/core/java/com/android/server/power/ShutdownCheckPoints.java
index e6d0ddd..05ee7df 100644
--- a/services/core/java/com/android/server/power/ShutdownCheckPoints.java
+++ b/services/core/java/com/android/server/power/ShutdownCheckPoints.java
@@ -90,18 +90,19 @@
}
/** Records the stack trace of this {@link Thread} as a shutdown check point. */
- public static void recordCheckPoint() {
- INSTANCE.recordCheckPointInternal();
+ public static void recordCheckPoint(@Nullable String reason) {
+ INSTANCE.recordCheckPointInternal(reason);
}
/** Records the pid of the caller process as a shutdown check point. */
- public static void recordCheckPoint(int callerProcessId) {
- INSTANCE.recordCheckPointInternal(callerProcessId);
+ public static void recordCheckPoint(int callerProcessId, @Nullable String reason) {
+ INSTANCE.recordCheckPointInternal(callerProcessId, reason);
}
/** Records the {@link android.content.Intent} name and package as a shutdown check point. */
- public static void recordCheckPoint(String intentName, String packageName) {
- INSTANCE.recordCheckPointInternal(intentName, packageName);
+ public static void recordCheckPoint(
+ String intentName, String packageName, @Nullable String reason) {
+ INSTANCE.recordCheckPointInternal(intentName, packageName, reason);
}
/** Serializes the recorded check points and writes them to given {@code printWriter}. */
@@ -119,24 +120,24 @@
}
@VisibleForTesting
- void recordCheckPointInternal() {
- recordCheckPointInternal(new SystemServerCheckPoint(mInjector));
+ void recordCheckPointInternal(@Nullable String reason) {
+ recordCheckPointInternal(new SystemServerCheckPoint(mInjector, reason));
Slog.v(TAG, "System server shutdown checkpoint recorded");
}
@VisibleForTesting
- void recordCheckPointInternal(int callerProcessId) {
+ void recordCheckPointInternal(int callerProcessId, @Nullable String reason) {
recordCheckPointInternal(callerProcessId == Process.myPid()
- ? new SystemServerCheckPoint(mInjector)
- : new BinderCheckPoint(mInjector, callerProcessId));
+ ? new SystemServerCheckPoint(mInjector, reason)
+ : new BinderCheckPoint(mInjector, callerProcessId, reason));
Slog.v(TAG, "Binder shutdown checkpoint recorded with pid=" + callerProcessId);
}
@VisibleForTesting
- void recordCheckPointInternal(String intentName, String packageName) {
+ void recordCheckPointInternal(String intentName, String packageName, @Nullable String reason) {
recordCheckPointInternal("android".equals(packageName)
- ? new SystemServerCheckPoint(mInjector)
- : new IntentCheckPoint(mInjector, intentName, packageName));
+ ? new SystemServerCheckPoint(mInjector, reason)
+ : new IntentCheckPoint(mInjector, intentName, packageName, reason));
Slog.v(TAG, String.format("Shutdown intent checkpoint recorded intent=%s from package=%s",
intentName, packageName));
}
@@ -182,14 +183,20 @@
private abstract static class CheckPoint {
private final long mTimestamp;
+ @Nullable private final String mReason;
- CheckPoint(Injector injector) {
+ CheckPoint(Injector injector, @Nullable String reason) {
mTimestamp = injector.currentTimeMillis();
+ mReason = reason;
}
final void dump(PrintWriter printWriter) {
printWriter.print("Shutdown request from ");
printWriter.print(getOrigin());
+ if (mReason != null) {
+ printWriter.print(" for reason ");
+ printWriter.print(mReason);
+ }
printWriter.print(" at ");
printWriter.print(DATE_FORMAT.format(new Date(mTimestamp)));
printWriter.println(" (epoch=" + mTimestamp + ")");
@@ -206,8 +213,8 @@
private final StackTraceElement[] mStackTraceElements;
- SystemServerCheckPoint(Injector injector) {
- super(injector);
+ SystemServerCheckPoint(Injector injector, @Nullable String reason) {
+ super(injector, reason);
mStackTraceElements = Thread.currentThread().getStackTrace();
}
@@ -263,8 +270,8 @@
private final int mCallerProcessId;
private final IActivityManager mActivityManager;
- BinderCheckPoint(Injector injector, int callerProcessId) {
- super(injector);
+ BinderCheckPoint(Injector injector, int callerProcessId, @Nullable String reason) {
+ super(injector, reason);
mCallerProcessId = callerProcessId;
mActivityManager = injector.activityManager();
}
@@ -307,8 +314,9 @@
private final String mIntentName;
private final String mPackageName;
- IntentCheckPoint(Injector injector, String intentName, String packageName) {
- super(injector);
+ IntentCheckPoint(
+ Injector injector, String intentName, String packageName, @Nullable String reason) {
+ super(injector, reason);
mIntentName = intentName;
mPackageName = packageName;
}
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 2621d8b..e94575c 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -65,7 +65,7 @@
private static final int RADIOS_STATE_POLL_SLEEP_MS = 100;
// maximum time we wait for the shutdown broadcast before going on.
private static final int MAX_BROADCAST_TIME = 10 * 1000;
- private static final int MAX_CHECK_POINTS_DUMP_WAIT_TIME = 20 * 1000;
+ private static final int MAX_CHECK_POINTS_DUMP_WAIT_TIME = 10 * 1000;
private static final int MAX_RADIO_WAIT_TIME = 12 * 1000;
private static final int MAX_UNCRYPT_WAIT_TIME = 15 * 60 * 1000;
// constants for progress bar. the values are roughly estimated based on timeout.
@@ -165,6 +165,10 @@
}
}
+ // Add checkpoint for this shutdown attempt. The user might still cancel the dialog, but
+ // this point preserves the system trace of the trigger point of the ShutdownThread.
+ ShutdownCheckPoints.recordCheckPoint(/* reason= */ null);
+
final int longPressBehavior = context.getResources().getInteger(
com.android.internal.R.integer.config_longPressOnPowerBehavior);
final int resourceId = mRebootSafeMode
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 93ea5e3..9bc8afa 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -67,6 +67,7 @@
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.notification.NotificationDelegate;
import com.android.server.policy.GlobalActionsProvider;
+import com.android.server.power.ShutdownCheckPoints;
import com.android.server.power.ShutdownThread;
import java.io.FileDescriptor;
@@ -1182,13 +1183,14 @@
@Override
public void shutdown() {
enforceStatusBarService();
+ String reason = PowerManager.SHUTDOWN_USER_REQUESTED;
+ ShutdownCheckPoints.recordCheckPoint(Binder.getCallingPid(), reason);
long identity = Binder.clearCallingIdentity();
try {
mNotificationDelegate.prepareForPossibleShutdown();
// ShutdownThread displays UI, so give it a UI context.
mHandler.post(() ->
- ShutdownThread.shutdown(getUiContext(),
- PowerManager.SHUTDOWN_USER_REQUESTED, false));
+ ShutdownThread.shutdown(getUiContext(), reason, false));
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -1200,6 +1202,10 @@
@Override
public void reboot(boolean safeMode) {
enforceStatusBarService();
+ String reason = safeMode
+ ? PowerManager.REBOOT_SAFE_MODE
+ : PowerManager.SHUTDOWN_USER_REQUESTED;
+ ShutdownCheckPoints.recordCheckPoint(Binder.getCallingPid(), reason);
long identity = Binder.clearCallingIdentity();
try {
mNotificationDelegate.prepareForPossibleShutdown();
@@ -1208,8 +1214,7 @@
if (safeMode) {
ShutdownThread.rebootSafeMode(getUiContext(), true);
} else {
- ShutdownThread.reboot(getUiContext(),
- PowerManager.SHUTDOWN_USER_REQUESTED, false);
+ ShutdownThread.reboot(getUiContext(), reason, false);
}
});
} finally {
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index e84f040..f7cb014 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -118,6 +118,7 @@
import com.android.internal.app.IVoiceInteractor;
import com.android.server.am.PendingIntentRecord;
import com.android.server.pm.InstantAppResolver;
+import com.android.server.power.ShutdownCheckPoints;
import com.android.server.uri.NeededUriGrants;
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
import com.android.server.wm.ActivityStackSupervisor.PendingActivityLaunch;
@@ -647,6 +648,19 @@
mRequest.resolveActivity(mSupervisor);
}
+ // Add checkpoint for this shutdown or reboot attempt, so we can record the original
+ // intent action and package name.
+ if (mRequest.intent != null) {
+ String intentAction = mRequest.intent.getAction();
+ String callingPackage = mRequest.callingPackage;
+ if (intentAction != null && callingPackage != null
+ && (Intent.ACTION_REQUEST_SHUTDOWN.equals(intentAction)
+ || Intent.ACTION_SHUTDOWN.equals(intentAction)
+ || Intent.ACTION_REBOOT.equals(intentAction))) {
+ ShutdownCheckPoints.recordCheckPoint(intentAction, callingPackage, null);
+ }
+ }
+
int res;
synchronized (mService.mGlobalLock) {
final boolean globalConfigWillChange = mRequest.globalConfig != null
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index 0d8e882..13033a6 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -93,9 +93,17 @@
private final Rect mTmpRect = new Rect();
static final int BOUNDS_CHANGE_NONE = 0;
- // Return value from {@link setBounds} indicating the position of the override bounds changed.
+
+ /**
+ * Return value from {@link #setBounds(Rect)} indicating the position of the override bounds
+ * changed.
+ */
static final int BOUNDS_CHANGE_POSITION = 1;
- // Return value from {@link setBounds} indicating the size of the override bounds changed.
+
+ /**
+ * Return value from {@link #setBounds(Rect)} indicating the size of the override bounds
+ * changed.
+ */
static final int BOUNDS_CHANGE_SIZE = 1 << 1;
/**
@@ -226,6 +234,11 @@
return equivalentBounds(getRequestedOverrideBounds(), bounds);
}
+ /** Similar to {@link #equivalentRequestedOverrideBounds(Rect)}, but compares max bounds. */
+ public boolean equivalentRequestedOverrideMaxBounds(Rect bounds) {
+ return equivalentBounds(getRequestedOverrideMaxBounds(), bounds);
+ }
+
/**
* Returns whether the two bounds are equal to each other or are a combination of null or empty.
*/
@@ -238,7 +251,6 @@
/**
* Returns the effective bounds of this container, inheriting the first non-empty bounds set in
* its ancestral hierarchy, including itself.
- * @return
*/
public Rect getBounds() {
mReturnBounds.set(getConfiguration().windowConfiguration.getBounds());
@@ -249,6 +261,12 @@
outBounds.set(getBounds());
}
+ /** Similar to {@link #getBounds()}, but reports the max bounds. */
+ public Rect getMaxBounds() {
+ mReturnBounds.set(getConfiguration().windowConfiguration.getMaxBounds());
+ return mReturnBounds;
+ }
+
/**
* Sets {@code out} to the top-left corner of the bounds as returned by {@link #getBounds()}.
*/
@@ -273,6 +291,13 @@
return mReturnBounds;
}
+ /** Similar to {@link #getRequestedOverrideBounds()}, but returns the max bounds. */
+ public Rect getRequestedOverrideMaxBounds() {
+ mReturnBounds.set(getRequestedOverrideConfiguration().windowConfiguration.getMaxBounds());
+
+ return mReturnBounds;
+ }
+
/**
* Returns {@code true} if the {@link WindowConfiguration} in the requested override
* {@link Configuration} specifies bounds.
@@ -283,7 +308,7 @@
/**
* Sets the passed in {@link Rect} to the current bounds.
- * @see {@link #getRequestedOverrideBounds()}.
+ * @see #getRequestedOverrideBounds()
*/
public void getRequestedOverrideBounds(Rect outBounds) {
outBounds.set(getRequestedOverrideBounds());
@@ -295,19 +320,25 @@
* {@link #getRequestedOverrideBounds()}. If
* an empty {@link Rect} or null is specified, this container will be considered to match its
* parent bounds {@see #matchParentBounds} and will inherit bounds from its parent.
+ *
* @param bounds The bounds defining the container size.
+ *
* @return a bitmask representing the types of changes made to the bounds.
*/
public int setBounds(Rect bounds) {
int boundsChange = diffRequestedOverrideBounds(bounds);
+ final boolean overrideMaxBounds = providesMaxBounds()
+ && diffRequestedOverrideMaxBounds(bounds) != BOUNDS_CHANGE_NONE;
- if (boundsChange == BOUNDS_CHANGE_NONE) {
+ if (boundsChange == BOUNDS_CHANGE_NONE && !overrideMaxBounds) {
return boundsChange;
}
-
mRequestsTmpConfig.setTo(getRequestedOverrideConfiguration());
mRequestsTmpConfig.windowConfiguration.setBounds(bounds);
+ if (overrideMaxBounds) {
+ mRequestsTmpConfig.windowConfiguration.setMaxBounds(bounds);
+ }
onRequestedOverrideConfigurationChanged(mRequestsTmpConfig);
return boundsChange;
@@ -318,6 +349,40 @@
return setBounds(mTmpRect);
}
+ /**
+ * Returns {@code true} if this {@link ConfigurationContainer} provides the maximum bounds to
+ * its child {@link ConfigurationContainer}s. Returns {@code false}, otherwise.
+ * <p>
+ * The maximum bounds is how large a window can be expanded. Currently only
+ * {@link DisplayContent} and {@link DisplayArea} effect this property.
+ * </p>
+ */
+ protected boolean providesMaxBounds() {
+ return false;
+ }
+
+ int diffRequestedOverrideMaxBounds(Rect bounds) {
+ if (equivalentRequestedOverrideMaxBounds(bounds)) {
+ return BOUNDS_CHANGE_NONE;
+ }
+
+ int boundsChange = BOUNDS_CHANGE_NONE;
+
+ final Rect existingBounds = getRequestedOverrideMaxBounds();
+
+ if (bounds == null || existingBounds.left != bounds.left
+ || existingBounds.top != bounds.top) {
+ boundsChange |= BOUNDS_CHANGE_POSITION;
+ }
+
+ if (bounds == null || existingBounds.width() != bounds.width()
+ || existingBounds.height() != bounds.height()) {
+ boundsChange |= BOUNDS_CHANGE_SIZE;
+ }
+
+ return boundsChange;
+ }
+
int diffRequestedOverrideBounds(Rect bounds) {
if (equivalentRequestedOverrideBounds(bounds)) {
return BOUNDS_CHANGE_NONE;
@@ -340,10 +405,6 @@
return boundsChange;
}
- boolean hasOverrideConfiguration() {
- return mHasOverrideConfiguration;
- }
-
public WindowConfiguration getWindowConfiguration() {
return mFullConfiguration.windowConfiguration;
}
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index 546c5d4..6ffb482 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -25,6 +25,7 @@
import static android.window.DisplayAreaOrganizer.FEATURE_WINDOW_TOKENS;
import static com.android.internal.util.Preconditions.checkState;
+import static com.android.server.wm.DisplayAreaProto.IS_TASK_DISPLAY_AREA;
import static com.android.server.wm.DisplayAreaProto.NAME;
import static com.android.server.wm.DisplayAreaProto.WINDOW_CONTAINER;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
@@ -194,6 +195,7 @@
final long token = proto.start(fieldId);
super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
proto.write(NAME, mName);
+ proto.write(IS_TASK_DISPLAY_AREA, isTaskDisplayArea());
proto.end(token);
}
@@ -349,6 +351,15 @@
return info;
}
+ @Override
+ public boolean providesMaxBounds() {
+ return true;
+ }
+
+ protected boolean isTaskDisplayArea() {
+ return false;
+ }
+
/**
* DisplayArea that contains WindowTokens, and orders them according to their type.
*/
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0b1f4d9e..77fc2283 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1930,6 +1930,7 @@
final DisplayInfo displayInfo = updateDisplayAndOrientation(config.uiMode, config);
calculateBounds(displayInfo, mTmpBounds);
config.windowConfiguration.setBounds(mTmpBounds);
+ config.windowConfiguration.setMaxBounds(mTmpBounds);
config.windowConfiguration.setWindowingMode(getWindowingMode());
config.windowConfiguration.setDisplayWindowingMode(getWindowingMode());
@@ -2544,10 +2545,6 @@
return mDisplayAreaPolicy.getDefaultTaskDisplayArea();
}
- void positionDisplayAt(int position, boolean includingParents) {
- getParent().positionChildAt(position, this, includingParents);
- }
-
/**
* Returns true if the input point is within an app window.
*/
@@ -5393,6 +5390,11 @@
});
}
+ @Override
+ public boolean providesMaxBounds() {
+ return true;
+ }
+
/** The entry for proceeding to handle {@link #mFixedRotationLaunchingApp}. */
class FixedRotationTransitionListener extends WindowManagerInternal.AppTransitionListener {
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 0e24fc8..4f6f75d 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -356,6 +356,8 @@
private WindowState mFocusedWindow;
private WindowState mLastFocusedWindow;
+ private WindowState mSystemUiControllingWindow;
+
// The states of decor windows from the last layout. These are used to generate another display
// layout in different bounds but with the same states.
private boolean mLastNavVisible;
@@ -3436,6 +3438,7 @@
}
}
final WindowState win = winCandidate;
+ mSystemUiControllingWindow = win;
mDisplayContent.getInsetsPolicy().updateBarControlTarget(win);
@@ -3740,8 +3743,12 @@
& WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
final boolean hideStatusBarSysui =
(vis & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
- final boolean hideNavBarSysui =
- (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
+ final boolean hideNavBarSysui = (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0
+ // We shouldn't rely on the system UI visibilities anymore because the window can
+ // use the new API (e.g., WindowInsetsController.hide) to hide navigation bar.
+ // TODO(b/149813814): clean up the system UI flag usages in this function.
+ || !win.getRequestedInsetsState().getSourceOrDefaultVisibility(
+ ITYPE_NAVIGATION_BAR);
final boolean transientStatusBarAllowed = getStatusBar() != null
&& (notificationShadeHasFocus || (!mForceShowSystemBars
@@ -3755,15 +3762,16 @@
&& now - mPendingPanicGestureUptime <= PANIC_GESTURE_EXPIRATION;
final DisplayPolicy defaultDisplayPolicy =
mService.getDefaultDisplayContentLocked().getDisplayPolicy();
- if (pendingPanic && hideNavBarSysui && !isKeyguardShowing()
+ if (pendingPanic && hideNavBarSysui && win != mNotificationShade
+ && getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)
// TODO (b/111955725): Show keyguard presentation on all external displays
&& defaultDisplayPolicy.isKeyguardDrawComplete()) {
// The user performed the panic gesture recently, we're about to hide the bars,
// we're no longer on the Keyguard and the screen is ready. We can now request the bars.
mPendingPanicGestureUptime = 0;
- mStatusBarController.showTransient();
if (!isNavBarEmpty(vis)) {
- mNavigationBarController.showTransient();
+ mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap(
+ new int[] {ITYPE_NAVIGATION_BAR}));
}
}
@@ -3908,6 +3916,9 @@
}
private boolean isImmersiveMode(WindowState win) {
+ if (win == null) {
+ return false;
+ }
final int behavior = win.mAttrs.insetsFlags.behavior;
return getNavigationBar() != null
&& canHideNavigationBar()
@@ -3942,11 +3953,7 @@
return;
}
mPendingPanicGestureUptime = SystemClock.uptimeMillis();
- if (!isNavBarEmpty(mLastSystemUiFlags)) {
- mNavigationBarController.showTransient();
- mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap(
- new int[] {ITYPE_NAVIGATION_BAR}));
- }
+ updateSystemUiVisibilityLw();
}
}
};
@@ -3955,7 +3962,7 @@
// Detect user pressing the power button in panic when an application has
// taken over the whole screen.
boolean panic = mImmersiveModeConfirmation.onPowerKeyDown(isScreenOn,
- SystemClock.elapsedRealtime(), isImmersiveMode(mLastSystemUiFlags),
+ SystemClock.elapsedRealtime(), isImmersiveMode(mSystemUiControllingWindow),
isNavBarEmpty(mLastSystemUiFlags));
if (panic) {
mHandler.post(mHiddenNavPanic);
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 246753a..a847744 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -1294,7 +1294,13 @@
}
void onSplitScreenModeDismissed() {
- onSplitScreenModeDismissed(null /* toTop */);
+ // The focused task could be a non-resizeable fullscreen root task that is on top of the
+ // other split-screen tasks, therefore had to dismiss split-screen, make sure the current
+ // focused root task can still be on top after dismissal
+ final Task rootTask = getFocusedStack();
+ final Task toTop =
+ rootTask != null && !rootTask.inSplitScreenWindowingMode() ? rootTask : null;
+ onSplitScreenModeDismissed(toTop);
}
void onSplitScreenModeDismissed(Task toTop) {
@@ -1838,6 +1844,10 @@
return lastReparentedStack;
}
+ @Override
+ protected boolean isTaskDisplayArea() {
+ return true;
+ }
@Override
void dump(PrintWriter pw, String prefix, boolean dumpAll) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2dd25c9..0b942ba 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2931,8 +2931,8 @@
synchronized (mGlobalLock) {
final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null && mRoot.getTopChild() != displayContent) {
- displayContent.positionDisplayAt(WindowContainer.POSITION_TOP,
- true /* includingParents */);
+ displayContent.getParent().positionChildAt(WindowContainer.POSITION_TOP,
+ displayContent, true /* includingParents */);
}
}
syncInputTransactions();
@@ -8017,7 +8017,7 @@
final DisplayContent displayContent = touchedWindow.getDisplayContent();
if (!displayContent.isOnTop()) {
- displayContent.positionDisplayAt(WindowContainer.POSITION_TOP,
+ displayContent.getParent().positionChildAt(WindowContainer.POSITION_TOP, displayContent,
true /* includingParents */);
}
handleTaskFocusChange(touchedWindow.getTask());
diff --git a/services/tests/servicestests/src/com/android/server/power/ShutdownCheckPointsTest.java b/services/tests/servicestests/src/com/android/server/power/ShutdownCheckPointsTest.java
index a1f1056..2230ddd 100644
--- a/services/tests/servicestests/src/com/android/server/power/ShutdownCheckPointsTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/ShutdownCheckPointsTest.java
@@ -72,21 +72,32 @@
@Test
public void testSystemServerEntry() {
mTestInjector.setCurrentTime(1000);
- mInstance.recordCheckPointInternal();
+ mInstance.recordCheckPointInternal("reason1");
assertTrue(dumpToString().startsWith(
- "Shutdown request from SYSTEM at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Shutdown request from SYSTEM for reason reason1 "
+ + "at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "com.android.server.power.ShutdownCheckPointsTest"
+ ".testSystemServerEntry\n at "));
}
@Test
- public void testSystemServiceBinderEntry() {
+ public void testSystemServerEntryWithoutReason() {
mTestInjector.setCurrentTime(1000);
- mInstance.recordCheckPointInternal(Process.myPid());
+ mInstance.recordCheckPointInternal(null);
assertTrue(dumpToString().startsWith(
- "Shutdown request from SYSTEM at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Shutdown request from SYSTEM at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"));
+ }
+
+ @Test
+ public void testSystemServiceBinderEntry() {
+ mTestInjector.setCurrentTime(1000);
+ mInstance.recordCheckPointInternal(Process.myPid(), "reason1");
+
+ assertTrue(dumpToString().startsWith(
+ "Shutdown request from SYSTEM for reason reason1 "
+ + "at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "com.android.server.power.ShutdownCheckPointsTest"
+ ".testSystemServiceBinderEntry\n at "));
}
@@ -99,10 +110,11 @@
when(mActivityManager.getRunningAppProcesses()).thenReturn(runningAppProcessInfos);
mTestInjector.setCurrentTime(1000);
- mInstance.recordCheckPointInternal(1);
+ mInstance.recordCheckPointInternal(1, "reason1");
assertEquals(
- "Shutdown request from BINDER at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Shutdown request from BINDER for reason reason1 "
+ + "at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "com.android.server.power.ShutdownCheckPointsTest"
+ ".testCallerProcessBinderEntry\n"
+ "From process process_name (pid=1)\n\n",
@@ -114,10 +126,11 @@
when(mActivityManager.getRunningAppProcesses()).thenThrow(new RemoteException("Error"));
mTestInjector.setCurrentTime(1000);
- mInstance.recordCheckPointInternal(1);
+ mInstance.recordCheckPointInternal(1, "reason1");
assertEquals(
- "Shutdown request from BINDER at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Shutdown request from BINDER for reason reason1 "
+ + "at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "com.android.server.power.ShutdownCheckPointsTest"
+ ".testRemoteExceptionOnBinderEntry\n"
+ "From process ? (pid=1)\n\n",
@@ -127,10 +140,11 @@
@Test
public void testUnknownProcessBinderEntry() {
mTestInjector.setCurrentTime(1000);
- mInstance.recordCheckPointInternal(1);
+ mInstance.recordCheckPointInternal(1, "reason1");
assertEquals(
- "Shutdown request from BINDER at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Shutdown request from BINDER for reason reason1 "
+ + "at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "com.android.server.power.ShutdownCheckPointsTest"
+ ".testUnknownProcessBinderEntry\n"
+ "From process ? (pid=1)\n\n",
@@ -138,12 +152,22 @@
}
@Test
- public void testSystemServiceIntentEntry() {
+ public void testBinderEntryWithoutReason() throws RemoteException {
mTestInjector.setCurrentTime(1000);
- mInstance.recordCheckPointInternal("some.intent", "android");
+ mInstance.recordCheckPointInternal(1, null);
assertTrue(dumpToString().startsWith(
- "Shutdown request from SYSTEM at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Shutdown request from BINDER at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"));
+ }
+
+ @Test
+ public void testSystemServiceIntentEntry() {
+ mTestInjector.setCurrentTime(1000);
+ mInstance.recordCheckPointInternal("some.intent", "android", "reason1");
+
+ assertTrue(dumpToString().startsWith(
+ "Shutdown request from SYSTEM for reason reason1 "
+ + "at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "com.android.server.power.ShutdownCheckPointsTest"
+ ".testSystemServiceIntentEntry\n at "));
}
@@ -151,39 +175,47 @@
@Test
public void testIntentEntry() {
mTestInjector.setCurrentTime(1000);
- mInstance.recordCheckPointInternal("some.intent", "some.app");
+ mInstance.recordCheckPointInternal("some.intent", "some.app", "reason1");
assertEquals(
- "Shutdown request from INTENT at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Shutdown request from INTENT for reason reason1 "
+ + "at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Intent: some.intent\n"
+ "Package: some.app\n\n",
dumpToString());
}
@Test
+ public void testIntentEntryWithoutReason() {
+ mTestInjector.setCurrentTime(1000);
+ mInstance.recordCheckPointInternal("some.intent", "some.app", null);
+
+ assertTrue(dumpToString().startsWith(
+ "Shutdown request from INTENT at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"));
+ }
+
+ @Test
public void testMultipleEntries() {
mTestInjector.setCurrentTime(1000);
- mInstance.recordCheckPointInternal(1);
+ mInstance.recordCheckPointInternal(1, "reason1");
mTestInjector.setCurrentTime(2000);
- mInstance.recordCheckPointInternal(2);
+ mInstance.recordCheckPointInternal(2, "reason2");
mTestInjector.setCurrentTime(3000);
- mInstance.recordCheckPointInternal("intent", "app");
+ mInstance.recordCheckPointInternal("intent", "app", "reason3");
assertEquals(
- "Shutdown request from BINDER at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Shutdown request from BINDER for reason reason1 "
+ + "at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "com.android.server.power.ShutdownCheckPointsTest.testMultipleEntries\n"
- + "From process ? (pid=1)\n"
- + "\n"
- + "Shutdown request from BINDER at 1970-01-01 00:00:02.000 UTC (epoch=2000)"
- + "\n"
+ + "From process ? (pid=1)\n\n"
+ + "Shutdown request from BINDER for reason reason2 "
+ + "at 1970-01-01 00:00:02.000 UTC (epoch=2000)\n"
+ "com.android.server.power.ShutdownCheckPointsTest.testMultipleEntries\n"
- + "From process ? (pid=2)\n"
- + "\n"
- + "Shutdown request from INTENT at 1970-01-01 00:00:03.000 UTC (epoch=3000)"
- + "\n"
+ + "From process ? (pid=2)\n\n"
+ + "Shutdown request from INTENT for reason reason3 "
+ + "at 1970-01-01 00:00:03.000 UTC (epoch=3000)\n"
+ "Intent: intent\n"
- + "Package: app\n"
- + "\n",
+ + "Package: app\n\n",
dumpToString());
}
@@ -193,23 +225,22 @@
ShutdownCheckPoints limitedInstance = new ShutdownCheckPoints(mTestInjector);
mTestInjector.setCurrentTime(1000);
- limitedInstance.recordCheckPointInternal("intent.1", "app.1");
+ limitedInstance.recordCheckPointInternal("intent.1", "app.1", "reason1");
mTestInjector.setCurrentTime(2000);
- limitedInstance.recordCheckPointInternal("intent.2", "app.2");
+ limitedInstance.recordCheckPointInternal("intent.2", "app.2", "reason2");
mTestInjector.setCurrentTime(3000);
- limitedInstance.recordCheckPointInternal("intent.3", "app.3");
+ limitedInstance.recordCheckPointInternal("intent.3", "app.3", "reason3");
// Drops first intent.
assertEquals(
- "Shutdown request from INTENT at 1970-01-01 00:00:02.000 UTC (epoch=2000)\n"
+ "Shutdown request from INTENT for reason reason2 "
+ + "at 1970-01-01 00:00:02.000 UTC (epoch=2000)\n"
+ "Intent: intent.2\n"
- + "Package: app.2\n"
- + "\n"
- + "Shutdown request from INTENT at 1970-01-01 00:00:03.000 UTC (epoch=3000)"
- + "\n"
+ + "Package: app.2\n\n"
+ + "Shutdown request from INTENT for reason reason3 "
+ + "at 1970-01-01 00:00:03.000 UTC (epoch=3000)\n"
+ "Intent: intent.3\n"
- + "Package: app.3\n"
- + "\n",
+ + "Package: app.3\n\n",
dumpToString(limitedInstance));
}
@@ -219,11 +250,11 @@
File baseFile = new File(tempDir, "checkpoints");
mTestInjector.setCurrentTime(1000);
- mInstance.recordCheckPointInternal("first.intent", "first.app");
+ mInstance.recordCheckPointInternal("first.intent", "first.app", "reason1");
dumpToFile(baseFile);
mTestInjector.setCurrentTime(2000);
- mInstance.recordCheckPointInternal("second.intent", "second.app");
+ mInstance.recordCheckPointInternal("second.intent", "second.app", "reason2");
dumpToFile(baseFile);
File[] dumpFiles = tempDir.listFiles();
@@ -231,16 +262,18 @@
assertEquals(2, dumpFiles.length);
assertEquals(
- "Shutdown request from INTENT at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Shutdown request from INTENT for reason reason1 "
+ + "at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Intent: first.intent\n"
+ "Package: first.app\n\n",
readFileAsString(dumpFiles[0].getAbsolutePath()));
assertEquals(
- "Shutdown request from INTENT at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Shutdown request from INTENT for reason reason1 "
+ + "at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Intent: first.intent\n"
+ "Package: first.app\n\n"
- + "Shutdown request from INTENT at 1970-01-01 00:00:02.000 UTC (epoch=2000)"
- + "\n"
+ + "Shutdown request from INTENT for reason reason2 "
+ + "at 1970-01-01 00:00:02.000 UTC (epoch=2000)\n"
+ "Intent: second.intent\n"
+ "Package: second.app\n\n",
readFileAsString(dumpFiles[1].getAbsolutePath()));
@@ -254,21 +287,22 @@
File baseFile = new File(tempDir, "checkpoints");
mTestInjector.setCurrentTime(1000);
- instance.recordCheckPointInternal("first.intent", "first.app");
+ instance.recordCheckPointInternal("first.intent", "first.app", "reason1");
dumpToFile(instance, baseFile);
mTestInjector.setCurrentTime(2000);
- instance.recordCheckPointInternal("second.intent", "second.app");
+ instance.recordCheckPointInternal("second.intent", "second.app", "reason2");
dumpToFile(instance, baseFile);
File[] dumpFiles = tempDir.listFiles();
assertEquals(1, dumpFiles.length);
assertEquals(
- "Shutdown request from INTENT at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Shutdown request from INTENT for reason reason1 "
+ + "at 1970-01-01 00:00:01.000 UTC (epoch=1000)\n"
+ "Intent: first.intent\n"
+ "Package: first.app\n\n"
- + "Shutdown request from INTENT at 1970-01-01 00:00:02.000 UTC (epoch=2000)"
- + "\n"
+ + "Shutdown request from INTENT for reason reason2 "
+ + "at 1970-01-01 00:00:02.000 UTC (epoch=2000)\n"
+ "Intent: second.intent\n"
+ "Package: second.app\n\n",
readFileAsString(dumpFiles[0].getAbsolutePath()));
diff --git a/services/tests/wmtests/src/com/android/server/wm/ConfigurationContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/ConfigurationContainerTests.java
index bcd93715..5828d02 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ConfigurationContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ConfigurationContainerTests.java
@@ -33,6 +33,7 @@
import static org.junit.Assert.assertTrue;
import android.content.res.Configuration;
+import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
@@ -324,6 +325,47 @@
assertEquals(100, listener.mOverrideConfiguration.smallestScreenWidthDp);
}
+ @Test
+ public void testSetMaxBoundsByHierarchy() {
+ final TestConfigurationContainer root =
+ new TestConfigurationContainer(true /* providesMaxBounds */);
+ final Rect bounds = new Rect(0, 0, 10, 10);
+ final TestConfigurationContainer child = new TestConfigurationContainer();
+ root.addChild(child);
+
+ root.setBounds(bounds);
+
+ assertEquals(bounds, root.getBounds());
+ assertEquals(bounds, root.getConfiguration().windowConfiguration.getBounds());
+ assertEquals(bounds, child.getBounds());
+ assertEquals(bounds, child.getConfiguration().windowConfiguration.getBounds());
+
+ assertEquals(bounds, root.getMaxBounds());
+ assertEquals(bounds, root.getConfiguration().windowConfiguration.getMaxBounds());
+ assertEquals(bounds, child.getMaxBounds());
+ assertEquals(bounds, child.getConfiguration().windowConfiguration.getMaxBounds());
+ }
+
+ @Test
+ public void testSetBoundsNotOverrideMaxBounds() {
+ final TestConfigurationContainer root = new TestConfigurationContainer();
+ final Rect bounds = new Rect(0, 0, 10, 10);
+ final TestConfigurationContainer child = new TestConfigurationContainer();
+ root.addChild(child);
+
+ root.setBounds(bounds);
+
+ assertEquals(bounds, root.getBounds());
+ assertEquals(bounds, root.getConfiguration().windowConfiguration.getBounds());
+ assertEquals(bounds, child.getBounds());
+ assertEquals(bounds, child.getConfiguration().windowConfiguration.getBounds());
+
+ assertTrue(root.getMaxBounds().isEmpty());
+ assertTrue(root.getConfiguration().windowConfiguration.getMaxBounds().isEmpty());
+ assertTrue(child.getMaxBounds().isEmpty());
+ assertTrue(child.getConfiguration().windowConfiguration.getMaxBounds().isEmpty());
+ }
+
/**
* Contains minimal implementation of {@link ConfigurationContainer}'s abstract behavior needed
* for testing.
@@ -333,6 +375,14 @@
private List<TestConfigurationContainer> mChildren = new ArrayList<>();
private TestConfigurationContainer mParent;
+ private boolean mProvidesMaxBounds = false;
+
+ TestConfigurationContainer() {}
+
+ TestConfigurationContainer(boolean providesMaxBounds) {
+ mProvidesMaxBounds = providesMaxBounds;
+ }
+
TestConfigurationContainer addChild(TestConfigurationContainer childContainer) {
final ConfigurationContainer oldParent = childContainer.getParent();
childContainer.mParent = this;
@@ -369,6 +419,11 @@
protected ConfigurationContainer getParent() {
return mParent;
}
+
+ @Override
+ public boolean providesMaxBounds() {
+ return mProvidesMaxBounds;
+ }
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
index c8ed87d..e17601e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
@@ -40,8 +41,10 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
+import android.graphics.Rect;
import android.os.Binder;
import android.platform.test.annotations.Presubmit;
+import android.view.SurfaceControl;
import com.google.android.collect.Lists;
@@ -63,7 +66,6 @@
*/
@Presubmit
public class DisplayAreaTest {
-
@Rule
public SystemServicesTestRule mWmsRule = new SystemServicesTestRule();
@@ -379,6 +381,42 @@
assertThat(result).isEqualTo(tda1);
}
+ @Test
+ public void testSetMaxBounds() {
+ final Rect parentBounds = new Rect(0, 0, 100, 100);
+ final Rect childBounds1 = new Rect(parentBounds.left, parentBounds.top,
+ parentBounds.right / 2, parentBounds.bottom);
+ final Rect childBounds2 = new Rect(parentBounds.right / 2, parentBounds.top,
+ parentBounds.right, parentBounds.bottom);
+ TestDisplayArea parentDa = new TestDisplayArea(mWms, parentBounds);
+ TestDisplayArea childDa1 = new TestDisplayArea(mWms, childBounds1);
+ TestDisplayArea childDa2 = new TestDisplayArea(mWms, childBounds2);
+ parentDa.addChild(childDa1, 0);
+ parentDa.addChild(childDa2, 1);
+
+ assertEquals(parentBounds, parentDa.getMaxBounds());
+ assertEquals(childBounds1, childDa1.getMaxBounds());
+ assertEquals(childBounds2, childDa2.getMaxBounds());
+
+ final WindowToken windowToken = createWindowToken(TYPE_APPLICATION);
+ childDa1.addChild(windowToken, 0);
+
+ assertEquals("DisplayArea's children must have the same max bounds as itself",
+ childBounds1, windowToken.getMaxBounds());
+ }
+
+ private static class TestDisplayArea<T extends WindowContainer> extends DisplayArea<T> {
+ private TestDisplayArea(WindowManagerService wms, Rect bounds) {
+ super(wms, ANY, "half display area");
+ setBounds(bounds);
+ }
+
+ @Override
+ SurfaceControl.Builder makeChildSurface(WindowContainer child) {
+ return new MockSurfaceControlBuilder();
+ }
+ }
+
private WindowToken createWindowToken(int type) {
return new WindowToken(mWmsRule.getWindowManagerService(), new Binder(),
type, false /* persist */, null /* displayContent */,
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index 5161fba..952997e 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -24,6 +24,7 @@
test_suites: ["device-tests"],
libs: ["android.test.runner"],
static_libs: [
+ "androidx.test.ext.junit",
"flickertestapplib",
"flickerlib",
"truth-prebuilt",
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
new file mode 100644
index 0000000..dcabce8
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2020 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.server.wm.flicker
+
+import com.android.server.wm.flicker.dsl.LayersAssertion
+import com.android.server.wm.flicker.dsl.WmAssertion
+import com.android.server.wm.flicker.helpers.WindowUtils
+
+@JvmOverloads
+fun WmAssertion.statusBarWindowIsAlwaysVisible(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("statusBarWindowIsAlwaysVisible", enabled, bugId) {
+ this.showsAboveAppWindow(FlickerTestBase.STATUS_BAR_WINDOW_TITLE)
+ }
+}
+
+@JvmOverloads
+fun WmAssertion.navBarWindowIsAlwaysVisible(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("navBarWindowIsAlwaysVisible", enabled, bugId) {
+ this.showsAboveAppWindow(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE)
+ }
+}
+
+@JvmOverloads
+fun LayersAssertion.noUncoveredRegions(
+ beginRotation: Int,
+ endRotation: Int = beginRotation,
+ allStates: Boolean = true,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ val startingBounds = WindowUtils.getDisplayBounds(beginRotation)
+ val endingBounds = WindowUtils.getDisplayBounds(endRotation)
+ if (allStates) {
+ all("noUncoveredRegions", enabled, bugId) {
+ if (startingBounds == endingBounds) {
+ this.coversRegion(startingBounds)
+ } else {
+ this.coversRegion(startingBounds)
+ .then()
+ .coversRegion(endingBounds)
+ }
+ }
+ } else {
+ start("noUncoveredRegions_StartingPos") {
+ this.coversRegion(startingBounds)
+ }
+ end("noUncoveredRegions_EndingPos") {
+ this.coversRegion(endingBounds)
+ }
+ }
+}
+
+@JvmOverloads
+fun LayersAssertion.navBarLayerIsAlwaysVisible(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("navBarLayerIsAlwaysVisible", enabled, bugId) {
+ this.showsLayer(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE)
+ }
+}
+
+@JvmOverloads
+fun LayersAssertion.statusBarLayerIsAlwaysVisible(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("statusBarLayerIsAlwaysVisible", enabled, bugId) {
+ this.showsLayer(FlickerTestBase.STATUS_BAR_WINDOW_TITLE)
+ }
+}
+
+@JvmOverloads
+fun LayersAssertion.navBarLayerRotatesAndScales(
+ beginRotation: Int,
+ endRotation: Int = beginRotation,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ val startingPos = WindowUtils.getNavigationBarPosition(beginRotation)
+ val endingPos = WindowUtils.getNavigationBarPosition(endRotation)
+
+ start("navBarLayerRotatesAndScales_StartingPos", enabled, bugId) {
+ this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, startingPos)
+ }
+ end("navBarLayerRotatesAndScales_EndingPost", enabled, bugId) {
+ this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, endingPos)
+ }
+
+ if (startingPos == endingPos) {
+ all("navBarLayerRotatesAndScales", enabled, bugId) {
+ this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, startingPos)
+ }
+ }
+}
+
+@JvmOverloads
+fun LayersAssertion.statusBarLayerRotatesScales(
+ beginRotation: Int,
+ endRotation: Int = beginRotation,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ val startingPos = WindowUtils.getStatusBarPosition(beginRotation)
+ val endingPos = WindowUtils.getStatusBarPosition(endRotation)
+
+ start("statusBarLayerRotatesScales_StartingPos", enabled, bugId) {
+ this.hasVisibleRegion(FlickerTestBase.STATUS_BAR_WINDOW_TITLE, startingPos)
+ }
+ end("statusBarLayerRotatesScales_EndingPos", enabled, bugId) {
+ this.hasVisibleRegion(FlickerTestBase.STATUS_BAR_WINDOW_TITLE, endingPos)
+ }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt
deleted file mode 100644
index b69e6a9..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright (C) 2020 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.server.wm.flicker
-
-import android.app.Instrumentation
-import android.content.Context
-import android.content.Intent
-import android.os.RemoteException
-import android.os.SystemClock
-import android.platform.helpers.IAppHelper
-import android.util.Rational
-import android.view.Surface
-import androidx.test.uiautomator.By
-import androidx.test.uiautomator.UiDevice
-import androidx.test.uiautomator.Until
-import com.android.server.wm.flicker.helpers.AutomationUtils
-import com.android.server.wm.flicker.helpers.ImeAppHelper
-import com.android.server.wm.flicker.helpers.PipAppHelper
-
-/**
- * Collection of common transitions which can be used to test different apps or scenarios.
- */
-internal object CommonTransitions {
- private const val ITERATIONS = 1
- private const val APP_LAUNCH_TIMEOUT: Long = 10000
- private fun setRotation(device: UiDevice, rotation: Int) {
- try {
- when (rotation) {
- Surface.ROTATION_270 -> device.setOrientationLeft()
- Surface.ROTATION_90 -> device.setOrientationRight()
- Surface.ROTATION_0 -> device.setOrientationNatural()
- else -> device.setOrientationNatural()
- }
- // Wait for animation to complete
- SystemClock.sleep(1000)
- } catch (e: RemoteException) {
- throw RuntimeException(e)
- }
- }
-
- /**
- * Build a test tag for the test
- * @param testName Name of the transition(s) being tested
- * @param app App being launcher
- * @param rotation Initial screen rotation
- *
- * @return test tag with pattern <NAME>__<APP>__<ROTATION>
- </ROTATION></APP></NAME> */
- private fun buildTestTag(testName: String, app: IAppHelper, rotation: Int): String {
- return buildTestTag(
- testName, app, rotation, rotation, app2 = null, extraInfo = "")
- }
-
- /**
- * Build a test tag for the test
- * @param testName Name of the transition(s) being tested
- * @param app App being launcher
- * @param beginRotation Initial screen rotation
- * @param endRotation End screen rotation (if any, otherwise use same as initial)
- *
- * @return test tag with pattern <NAME>__<APP>__<BEGIN_ROTATION>-<END_ROTATION>
- </END_ROTATION></BEGIN_ROTATION></APP></NAME> */
- private fun buildTestTag(
- testName: String,
- app: IAppHelper,
- beginRotation: Int,
- endRotation: Int
- ): String {
- return buildTestTag(
- testName, app, beginRotation, endRotation, app2 = null, extraInfo = "")
- }
-
- /**
- * Build a test tag for the test
- * @param testName Name of the transition(s) being tested
- * @param app App being launcher
- * @param app2 Second app being launched (if any)
- * @param beginRotation Initial screen rotation
- * @param endRotation End screen rotation (if any, otherwise use same as initial)
- * @param extraInfo Additional information to append to the tag
- *
- * @return test tag with pattern <NAME>__<APP></APP>(S)>__<ROTATION></ROTATION>(S)>[__<EXTRA>]
- </EXTRA></NAME> */
- private fun buildTestTag(
- testName: String,
- app: IAppHelper,
- beginRotation: Int,
- endRotation: Int,
- app2: IAppHelper?,
- extraInfo: String
- ): String {
- val testTag = StringBuilder()
- testTag.append(testName)
- .append("__")
- .append(app.launcherName)
- if (app2 != null) {
- testTag.append("-")
- .append(app2.launcherName)
- }
- testTag.append("__")
- .append(Surface.rotationToString(beginRotation))
- if (endRotation != beginRotation) {
- testTag.append("-")
- .append(Surface.rotationToString(endRotation))
- }
- if (extraInfo.isNotEmpty()) {
- testTag.append("__")
- .append(extraInfo)
- }
- return testTag.toString()
- }
-
- fun openAppWarm(
- testApp: IAppHelper,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int
- ): TransitionRunner.TransitionBuilder {
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(buildTestTag("openAppWarm", testApp, beginRotation))
- .recordAllRuns()
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .runBeforeAll { setRotation(device, beginRotation) }
- .runBeforeAll { testApp.open() }
- .runBefore { device.pressHome() }
- .runBefore { device.waitForIdle() }
- .runBefore { setRotation(device, beginRotation) }
- .run { testApp.open() }
- .runAfterAll { testApp.exit() }
- .runAfterAll { AutomationUtils.setDefaultWait() }
- .repeat(ITERATIONS)
- }
-
- fun closeAppWithBackKey(
- testApp: IAppHelper,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int
- ): TransitionRunner.TransitionBuilder {
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(buildTestTag("closeAppWithBackKey", testApp, beginRotation))
- .recordAllRuns()
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .runBefore { testApp.open() }
- .runBefore { device.waitForIdle() }
- .run { device.pressBack() }
- .run { device.waitForIdle() }
- .runAfterAll { testApp.exit() }
- .runAfterAll { AutomationUtils.setDefaultWait() }
- .repeat(ITERATIONS)
- }
-
- fun closeAppWithHomeKey(
- testApp: IAppHelper,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int
- ): TransitionRunner.TransitionBuilder {
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(buildTestTag("closeAppWithHomeKey", testApp, beginRotation))
- .recordAllRuns()
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .runBefore { testApp.open() }
- .runBefore { device.waitForIdle() }
- .run { device.pressHome() }
- .run { device.waitForIdle() }
- .runAfterAll { testApp.exit() }
- .runAfterAll { AutomationUtils.setDefaultWait() }
- .repeat(ITERATIONS)
- }
-
- fun openAppCold(
- testApp: IAppHelper,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int
- ): TransitionRunner.TransitionBuilder {
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(buildTestTag("openAppCold", testApp, beginRotation))
- .recordAllRuns()
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .runBefore { device.pressHome() }
- .runBeforeAll { setRotation(device, beginRotation) }
- .runBefore { testApp.exit() }
- .runBefore { device.waitForIdle() }
- .run { testApp.open() }
- .runAfterAll { testApp.exit() }
- .runAfterAll { setRotation(device, Surface.ROTATION_0) }
- .repeat(ITERATIONS)
- }
-
- fun changeAppRotation(
- testApp: IAppHelper,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int,
- endRotation: Int
- ): TransitionRunner.TransitionBuilder {
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(buildTestTag("changeAppRotation", testApp, beginRotation, endRotation))
- .recordAllRuns()
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .runBeforeAll { testApp.open() }
- .runBefore { setRotation(device, beginRotation) }
- .run { setRotation(device, endRotation) }
- .runAfterAll { testApp.exit() }
- .runAfterAll { setRotation(device, Surface.ROTATION_0) }
- .repeat(ITERATIONS)
- }
-
- fun changeAppRotation(
- intent: Intent,
- intentId: String,
- context: Context,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int,
- endRotation: Int
- ): TransitionRunner.TransitionBuilder {
- val testTag = "changeAppRotation_" + intentId + "_" +
- Surface.rotationToString(beginRotation) + "_" +
- Surface.rotationToString(endRotation)
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(testTag)
- .recordAllRuns()
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .runBeforeAll {
- context.startActivity(intent)
- device.wait(Until.hasObject(By.pkg(intent.component?.packageName)
- .depth(0)), APP_LAUNCH_TIMEOUT)
- }
- .runBefore { setRotation(device, beginRotation) }
- .run { setRotation(device, endRotation) }
- .runAfterAll { AutomationUtils.stopPackage(context, intent.component?.packageName) }
- .runAfterAll { setRotation(device, Surface.ROTATION_0) }
- .repeat(ITERATIONS)
- }
-
- fun appToSplitScreen(
- testApp: IAppHelper,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int
- ): TransitionRunner.TransitionBuilder {
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(buildTestTag("appToSplitScreen", testApp, beginRotation))
- .recordAllRuns()
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .runBeforeAll { setRotation(device, beginRotation) }
- .runBefore { testApp.open() }
- .runBefore { device.waitForIdle() }
- .runBefore { SystemClock.sleep(500) }
- .run { AutomationUtils.launchSplitScreen(device) }
- .runAfter { AutomationUtils.exitSplitScreen(device) }
- .runAfterAll { testApp.exit() }
- .repeat(ITERATIONS)
- }
-
- fun splitScreenToLauncher(
- testApp: IAppHelper,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int
- ): TransitionRunner.TransitionBuilder {
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(buildTestTag("splitScreenToLauncher", testApp, beginRotation))
- .recordAllRuns()
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .runBefore { testApp.open() }
- .runBefore { device.waitForIdle() }
- .runBefore { AutomationUtils.launchSplitScreen(device) }
- .run { AutomationUtils.exitSplitScreen(device) }
- .runAfterAll { testApp.exit() }
- .repeat(ITERATIONS)
- }
-
- fun editTextSetFocus(
- testApp: ImeAppHelper,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int
- ): TransitionRunner.TransitionBuilder {
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(buildTestTag("editTextSetFocus", testApp, beginRotation))
- .recordAllRuns()
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .runBefore { device.pressHome() }
- .runBefore { setRotation(device, beginRotation) }
- .runBefore { testApp.open() }
- .run { testApp.openIME(device) }
- .runAfterAll { testApp.exit() }
- .repeat(ITERATIONS)
- }
-
- fun resizeSplitScreen(
- testAppTop: IAppHelper,
- testAppBottom: ImeAppHelper,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int,
- startRatio: Rational,
- stopRatio: Rational
- ): TransitionRunner.TransitionBuilder {
- val description = (startRatio.toString().replace("/", "-") + "_to_" +
- stopRatio.toString().replace("/", "-"))
- val testTag = buildTestTag("resizeSplitScreen", testAppTop, beginRotation,
- beginRotation, testAppBottom, description)
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(testTag)
- .recordAllRuns()
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .runBeforeAll { setRotation(device, beginRotation) }
- .runBeforeAll { AutomationUtils.clearRecents(instrumentation) }
- .runBefore { testAppBottom.open() }
- .runBefore { device.pressHome() }
- .runBefore { testAppTop.open() }
- .runBefore { device.waitForIdle() }
- .runBefore { AutomationUtils.launchSplitScreen(device) }
- .runBefore {
- val snapshot = device.findObject(
- By.res(device.launcherPackageName, "snapshot"))
- snapshot.click()
- }
- .runBefore { testAppBottom.openIME(device) }
- .runBefore { device.pressBack() }
- .runBefore { AutomationUtils.resizeSplitScreen(device, startRatio) }
- .run { AutomationUtils.resizeSplitScreen(device, stopRatio) }
- .runAfter { AutomationUtils.exitSplitScreen(device) }
- .runAfter { device.pressHome() }
- .runAfterAll { testAppTop.exit() }
- .runAfterAll { testAppBottom.exit() }
- .repeat(ITERATIONS)
- }
-
- fun editTextLoseFocusToHome(
- testApp: ImeAppHelper,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int
- ): TransitionRunner.TransitionBuilder {
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(buildTestTag("editTextLoseFocusToHome", testApp, beginRotation))
- .recordAllRuns()
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .runBefore { device.pressHome() }
- .runBefore { setRotation(device, beginRotation) }
- .runBefore { testApp.open() }
- .runBefore { testApp.openIME(device) }
- .run { device.pressHome() }
- .run { device.waitForIdle() }
- .runAfterAll { testApp.exit() }
- .repeat(ITERATIONS)
- }
-
- fun editTextLoseFocusToApp(
- testApp: ImeAppHelper,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int
- ): TransitionRunner.TransitionBuilder {
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(buildTestTag("editTextLoseFocusToApp", testApp, beginRotation))
- .recordAllRuns()
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .runBefore { device.pressHome() }
- .runBefore { setRotation(device, beginRotation) }
- .runBefore { testApp.open() }
- .runBefore { testApp.openIME(device) }
- .run { device.pressBack() }
- .run { device.waitForIdle() }
- .runAfterAll { testApp.exit() }
- .repeat(ITERATIONS)
- }
-
- fun enterPipMode(
- testApp: PipAppHelper,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int
- ): TransitionRunner.TransitionBuilder {
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(buildTestTag("enterPipMode", testApp, beginRotation))
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .runBefore { device.pressHome() }
- .runBefore { setRotation(device, beginRotation) }
- .runBefore { testApp.open() }
- .run { testApp.clickEnterPipButton(device) }
- .runAfter { testApp.closePipWindow(device) }
- .runAfterAll { testApp.exit() }
- .repeat(ITERATIONS)
- }
-
- fun exitPipModeToHome(
- testApp: PipAppHelper,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int
- ): TransitionRunner.TransitionBuilder {
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(buildTestTag("exitPipModeToHome", testApp, beginRotation))
- .recordAllRuns()
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .runBefore { device.pressHome() }
- .runBefore { setRotation(device, beginRotation) }
- .runBefore { testApp.open() }
- .run { testApp.clickEnterPipButton(device) }
- .run { testApp.closePipWindow(device) }
- .run { device.waitForIdle() }
- .run { testApp.exit() }
- .repeat(ITERATIONS)
- }
-
- fun exitPipModeToApp(
- testApp: PipAppHelper,
- instrumentation: Instrumentation,
- device: UiDevice,
- beginRotation: Int
- ): TransitionRunner.TransitionBuilder {
- return TransitionRunner.TransitionBuilder(instrumentation)
- .withTag(buildTestTag("exitPipModeToApp", testApp, beginRotation))
- .recordAllRuns()
- .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
- .run { device.pressHome() }
- .run { setRotation(device, beginRotation) }
- .run { testApp.open() }
- .run { testApp.clickEnterPipButton(device) }
- .run { AutomationUtils.expandPipWindow(device) }
- .run { device.waitForIdle() }
- .run { testApp.exit() }
- .repeat(ITERATIONS)
- }
-}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt
deleted file mode 100644
index 43cfdff..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2020 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.server.wm.flicker
-
-import android.platform.helpers.IAppHelper
-import android.util.Rational
-import android.view.Surface
-import androidx.test.InstrumentationRegistry
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.LargeTest
-import androidx.test.runner.AndroidJUnit4
-import androidx.test.uiautomator.UiDevice
-import com.android.server.wm.flicker.helpers.ImeAppHelper
-import com.android.server.wm.flicker.helpers.PipAppHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-
-/**
- * Tests to help debug individual transitions, capture video recordings and create test cases.
- *
- * Not actual tests
- */
-@LargeTest
-@FlakyTest
-@RunWith(AndroidJUnit4::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class DebugTest {
- private val instrumentation = InstrumentationRegistry.getInstrumentation()
- private val testApp: IAppHelper = StandardAppHelper(instrumentation,
- "com.android.server.wm.flicker.testapp", "SimpleApp")
- private val uiDevice = UiDevice.getInstance(instrumentation)
-
- /**
- * atest FlickerTests:DebugTest#openAppCold
- */
- @Test
- fun openAppCold() {
- CommonTransitions.openAppCold(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
- .recordAllRuns().build().run()
- }
-
- /**
- * atest FlickerTests:DebugTest#openAppWarm
- */
- @Test
- fun openAppWarm() {
- CommonTransitions.openAppWarm(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
- .recordAllRuns().build().run()
- }
-
- /**
- * atest FlickerTests:DebugTest#changeOrientationFromNaturalToLeft
- */
- @Test
- fun changeOrientationFromNaturalToLeft() {
- CommonTransitions.changeAppRotation(testApp, instrumentation, uiDevice, Surface.ROTATION_0,
- Surface.ROTATION_270).recordAllRuns().build().run()
- }
-
- /**
- * atest FlickerTests:DebugTest#closeAppWithBackKey
- */
- @Test
- fun closeAppWithBackKey() {
- CommonTransitions.closeAppWithBackKey(testApp, instrumentation, uiDevice,
- Surface.ROTATION_0).recordAllRuns().build().run()
- }
-
- /**
- * atest FlickerTests:DebugTest#closeAppWithHomeKey
- */
- @Test
- fun closeAppWithHomeKey() {
- CommonTransitions.closeAppWithHomeKey(testApp, instrumentation, uiDevice,
- Surface.ROTATION_0).recordAllRuns().build().run()
- }
-
- /**
- * atest FlickerTests:DebugTest#openAppToSplitScreen
- */
- @Test
- fun openAppToSplitScreen() {
- CommonTransitions.appToSplitScreen(testApp, instrumentation, uiDevice,
- Surface.ROTATION_0).includeJankyRuns().recordAllRuns()
- .build().run()
- }
-
- /**
- * atest FlickerTests:DebugTest#splitScreenToLauncher
- */
- @Test
- fun splitScreenToLauncher() {
- CommonTransitions.splitScreenToLauncher(testApp, instrumentation, uiDevice,
- Surface.ROTATION_0).includeJankyRuns().recordAllRuns().build().run()
- }
-
- /**
- * atest FlickerTests:DebugTest#resizeSplitScreen
- */
- @Test
- fun resizeSplitScreen() {
- val bottomApp = ImeAppHelper(instrumentation)
- CommonTransitions.resizeSplitScreen(
- testApp,
- bottomApp,
- instrumentation,
- uiDevice,
- Surface.ROTATION_0,
- Rational(1, 3), Rational(2, 3)
- ).includeJankyRuns().build().run()
- }
- // IME tests
- /**
- * atest FlickerTests:DebugTest#editTextSetFocus
- */
- @Test
- fun editTextSetFocus() {
- val testApp = ImeAppHelper(instrumentation)
- CommonTransitions.editTextSetFocus(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
- .includeJankyRuns()
- .build().run()
- }
-
- /**
- * atest FlickerTests:DebugTest#editTextLoseFocusToHome
- */
- @Test
- fun editTextLoseFocusToHome() {
- val testApp = ImeAppHelper(instrumentation)
- CommonTransitions.editTextLoseFocusToHome(testApp, instrumentation, uiDevice,
- Surface.ROTATION_0).includeJankyRuns().build().run()
- }
-
- /**
- * atest FlickerTests:DebugTest#editTextLoseFocusToApp
- */
- @Test
- fun editTextLoseFocusToApp() {
- val testApp = ImeAppHelper(instrumentation)
- CommonTransitions.editTextLoseFocusToHome(testApp, instrumentation, uiDevice,
- Surface.ROTATION_0).includeJankyRuns().build().run()
- }
- // PIP tests
- /**
- * atest FlickerTests:DebugTest#enterPipMode
- */
- @Test
- fun enterPipMode() {
- val testApp = PipAppHelper(instrumentation)
- CommonTransitions.enterPipMode(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
- .includeJankyRuns().build().run()
- }
-
- /**
- * atest FlickerTests:DebugTest#exitPipModeToHome
- */
- @Test
- fun exitPipModeToHome() {
- val testApp = PipAppHelper(instrumentation)
- CommonTransitions.exitPipModeToHome(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
- .includeJankyRuns()
- .build().run()
- }
-
- /**
- * atest FlickerTests:DebugTest#exitPipModeToApp
- */
- @Test
- fun exitPipModeToApp() {
- val testApp = PipAppHelper(instrumentation)
- CommonTransitions.exitPipModeToApp(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
- .includeJankyRuns().build().run()
- }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
index d7586d0..eaf4d87 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
@@ -16,15 +16,12 @@
package com.android.server.wm.flicker
+import android.os.RemoteException
+import android.os.SystemClock
import android.platform.helpers.IAppHelper
-import android.util.Log
-import androidx.test.InstrumentationRegistry
+import android.view.Surface
+import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
-import com.android.server.wm.flicker.helpers.AutomationUtils
-import com.google.common.truth.Truth
-import org.junit.After
-import org.junit.AfterClass
-import org.junit.Before
/**
* Base class of all Flicker test that performs common functions for all flicker tests:
@@ -37,101 +34,96 @@
* - Fails tests if results are not available for any test due to jank.
*/
abstract class FlickerTestBase {
- lateinit var testApp: IAppHelper
- open val instrumentation by lazy {
+ val instrumentation by lazy {
InstrumentationRegistry.getInstrumentation()
}
val uiDevice by lazy {
UiDevice.getInstance(instrumentation)
}
- lateinit var tesults: List<TransitionResult>
- private var lastResult: TransitionResult? = null
/**
- * Runs a transition, returns a cached result if the transition has run before.
- */
- fun run(transition: TransitionRunner) {
- if (transitionResults.containsKey(transition.testTag)) {
- tesults = transitionResults[transition.testTag]
- ?: throw IllegalStateException("Results do not contain test tag " +
- transition.testTag)
- return
+ * Build a test tag for the test
+ * @param testName Name of the transition(s) being tested
+ * @param app App being launcher
+ * @param rotation Initial screen rotation
+ *
+ * @return test tag with pattern <NAME>__<APP>__<ROTATION>
+ </ROTATION></APP></NAME> */
+ protected fun buildTestTag(testName: String, app: IAppHelper, rotation: Int): String {
+ return buildTestTag(
+ testName, app, rotation, rotation, app2 = null, extraInfo = "")
+ }
+
+ /**
+ * Build a test tag for the test
+ * @param testName Name of the transition(s) being tested
+ * @param app App being launcher
+ * @param beginRotation Initial screen rotation
+ * @param endRotation End screen rotation (if any, otherwise use same as initial)
+ *
+ * @return test tag with pattern <NAME>__<APP>__<BEGIN_ROTATION>-<END_ROTATION>
+ </END_ROTATION></BEGIN_ROTATION></APP></NAME> */
+ protected fun buildTestTag(
+ testName: String,
+ app: IAppHelper,
+ beginRotation: Int,
+ endRotation: Int
+ ): String {
+ return buildTestTag(
+ testName, app, beginRotation, endRotation, app2 = null, extraInfo = "")
+ }
+
+ /**
+ * Build a test tag for the test
+ * @param testName Name of the transition(s) being tested
+ * @param app App being launcher
+ * @param app2 Second app being launched (if any)
+ * @param beginRotation Initial screen rotation
+ * @param endRotation End screen rotation (if any, otherwise use same as initial)
+ * @param extraInfo Additional information to append to the tag
+ *
+ * @return test tag with pattern <NAME>__<APP></APP>(S)>__<ROTATION></ROTATION>(S)>[__<EXTRA>]
+ </EXTRA></NAME> */
+ protected fun buildTestTag(
+ testName: String,
+ app: IAppHelper,
+ beginRotation: Int,
+ endRotation: Int,
+ app2: IAppHelper?,
+ extraInfo: String
+ ): String {
+ var testTag = "${testName}__$${app.launcherName}"
+ if (app2 != null) {
+ testTag += "-${app2.launcherName}"
}
- tesults = transition.run().results
- /* Fail if we don't have any results due to jank */
- Truth.assertWithMessage("No results to test because all transition runs were invalid " +
- "because of Jank").that(tesults).isNotEmpty()
- transitionResults[transition.testTag] = tesults
- }
-
- /**
- * Runs a transition, returns a cached result if the transition has run before.
- */
- @Before
- fun runTransition() {
- run(transitionToRun)
- }
-
- /**
- * Gets the transition that will be executed
- */
- abstract val transitionToRun: TransitionRunner
-
- /**
- * Goes through a list of transition results and checks assertions on each result.
- */
- fun checkResults(assertion: (TransitionResult) -> Unit) {
- for (result in tesults) {
- lastResult = result
- assertion(result)
+ testTag += "__${Surface.rotationToString(beginRotation)}"
+ if (endRotation != beginRotation) {
+ testTag += "-${Surface.rotationToString(endRotation)}"
}
- lastResult = null
+ if (extraInfo.isNotEmpty()) {
+ testTag += "__$extraInfo"
+ }
+ return testTag
}
- /**
- * Kludge to mark a file for saving. If `checkResults` fails, the last result is not
- * cleared. This indicates the assertion failed for the result, so mark it for saving.
- */
- @After
- fun markArtifactsForSaving() {
- lastResult?.flagForSaving()
+ protected fun Flicker.setRotation(rotation: Int) {
+ try {
+ when (rotation) {
+ Surface.ROTATION_270 -> device.setOrientationLeft()
+ Surface.ROTATION_90 -> device.setOrientationRight()
+ Surface.ROTATION_0 -> device.setOrientationNatural()
+ else -> device.setOrientationNatural()
+ }
+ // Wait for animation to complete
+ SystemClock.sleep(1000)
+ } catch (e: RemoteException) {
+ throw RuntimeException(e)
+ }
}
companion object {
- const val TAG = "FLICKER"
const val NAVIGATION_BAR_WINDOW_TITLE = "NavigationBar"
const val STATUS_BAR_WINDOW_TITLE = "StatusBar"
const val DOCKED_STACK_DIVIDER = "DockedStackDivider"
- private val transitionResults = mutableMapOf<String, List<TransitionResult>>()
-
- /**
- * Teardown any system settings and clean up test artifacts from the file system.
- *
- * Note: test artifacts for failed tests will remain on the device.
- */
- @AfterClass
- @JvmStatic
- fun teardown() {
- AutomationUtils.setDefaultWait()
- transitionResults.values
- .flatten()
- .forEach {
- if (it.canDelete()) {
- it.delete()
- } else {
- if (it.layersTraceExists()) {
- Log.e(TAG, "Layers trace saved to ${it.layersTracePath}")
- }
- if (it.windowManagerTraceExists()) {
- Log.e(TAG,
- "WindowManager trace saved to ${it.windowManagerTracePath}")
- }
- if (it.screenCaptureVideoExists()) {
- Log.e(TAG,
- "Screen capture video saved to ${it.screenCaptureVideoPath()}")
- }
- }
- }
- }
}
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt
index 1f8150c..e7d1f8e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt
@@ -17,52 +17,20 @@
package com.android.server.wm.flicker
import android.view.Surface
-import androidx.test.filters.FlakyTest
-import org.junit.Test
import org.junit.runners.Parameterized
abstract class NonRotationTestBase(
- beginRotationName: String,
- protected val beginRotation: Int
+ protected val rotationName: String,
+ protected val rotation: Int
) : FlickerTestBase() {
- @FlakyTest(bugId = 141361128)
- @Test
- fun checkCoveredRegion_noUncoveredRegions() {
- val displayBounds = WindowUtils.getDisplayBounds(beginRotation)
- checkResults {
- LayersTraceSubject.assertThat(it).coversRegion(
- displayBounds).forAllEntries()
- }
- }
-
- @FlakyTest(bugId = 141361128)
- @Test
- fun checkVisibility_navBarLayerIsAlwaysVisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
- }
- }
-
- @FlakyTest(bugId = 141361128)
- @Test
- fun checkVisibility_statusBarLayerIsAlwaysVisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries()
- }
- }
-
companion object {
+ const val SCREENSHOT_LAYER = "RotationLayer"
+
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<Array<Any>> {
val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90)
- val params: MutableCollection<Array<Any>> = ArrayList()
- for (begin in supportedRotations) {
- params.add(arrayOf(Surface.rotationToString(begin), begin))
- }
- return params
+ return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
}
}
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt
index dfc3c07..3b67727 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt
@@ -17,8 +17,6 @@
package com.android.server.wm.flicker
import android.view.Surface
-import androidx.test.filters.FlakyTest
-import org.junit.Test
import org.junit.runners.Parameterized
abstract class RotationTestBase(
@@ -27,82 +25,7 @@
protected val beginRotation: Int,
protected val endRotation: Int
) : FlickerTestBase() {
- @FlakyTest(bugId = 140855415)
- @Test
- fun checkVisibility_navBarWindowIsAlwaysVisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
- }
- }
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun checkVisibility_statusBarWindowIsAlwaysVisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries()
- }
- }
-
- @Test
- fun checkPosition_navBarLayerRotatesAndScales() {
- val startingPos = WindowUtils.getNavigationBarPosition(beginRotation)
- val endingPos = WindowUtils.getNavigationBarPosition(endRotation)
- if (startingPos == endingPos) {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
- .forAllEntries()
- }
- } else {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
- .inTheBeginning()
- }
- checkResults {
- LayersTraceSubject.assertThat(it)
- .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, endingPos)
- .atTheEnd()
- }
- }
- }
-
- @Test
- fun checkPosition_statusBarLayerRotatesScales() {
- val startingPos = WindowUtils.getStatusBarPosition(beginRotation)
- val endingPos = WindowUtils.getStatusBarPosition(endRotation)
- checkResults {
- LayersTraceSubject.assertThat(it)
- .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, startingPos)
- .inTheBeginning()
- LayersTraceSubject.assertThat(it)
- .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, endingPos).atTheEnd()
- }
- }
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun checkVisibility_navBarLayerIsAlwaysVisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
- }
- }
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun checkVisibility_statusBarLayerIsAlwaysVisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries()
- }
- }
-
companion object {
- const val SCREENSHOT_LAYER = "RotationLayer"
-
@Parameterized.Parameters(name = "{0}-{1}")
@JvmStatic
fun getParams(): Collection<Array<Any>> {
@@ -123,4 +46,4 @@
return params
}
}
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt
index e579533..7147577 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt
@@ -17,14 +17,15 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
+import android.support.test.launcherhelper.ILauncherStrategy
import com.android.server.wm.flicker.StandardAppHelper
abstract class FlickerAppHelper(
instr: Instrumentation,
- launcherName: String
-) : StandardAppHelper(instr, sFlickerPackage, launcherName) {
+ launcherName: String,
+ launcherStrategy: ILauncherStrategy
+) : StandardAppHelper(instr, sFlickerPackage, launcherName, launcherStrategy) {
companion object {
- var sFindTimeout = 10000
var sFlickerPackage = "com.android.server.wm.flicker.testapp"
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
index 979cbea..c1b7657 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
@@ -17,6 +17,8 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
+import android.support.test.launcherhelper.ILauncherStrategy
+import android.support.test.launcherhelper.LauncherStrategyFactory
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.Until
@@ -24,17 +26,26 @@
open class ImeAppHelper(
instr: Instrumentation,
- launcherName: String = "ImeApp"
-) : FlickerAppHelper(instr, launcherName) {
+ launcherName: String = "ImeApp",
+ launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
+ .getInstance(instr)
+ .launcherStrategy
+) : FlickerAppHelper(instr, launcherName, launcherStrategy) {
open fun openIME(device: UiDevice) {
val editText = device.wait(
Until.findObject(By.res(getPackage(), "plain_text_input")),
- AutomationUtils.FIND_TIMEOUT)
+ FIND_TIMEOUT)
Assert.assertNotNull("Text field not found, this usually happens when the device " +
"was left in an unknown state (e.g. in split screen)", editText)
editText.click()
- if (!AutomationUtils.waitForIME(device)) {
+ if (!device.waitForIME()) {
Assert.fail("IME did not appear")
}
}
+
+ open fun closeIME(device: UiDevice) {
+ device.pressBack()
+ // Using only the AccessibilityInfo it is not possible to identify if the IME is active
+ device.waitForIdle(1000)
+ }
}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
index daee810..d10bb1e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
@@ -17,20 +17,27 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
+import android.support.test.launcherhelper.ILauncherStrategy
+import android.support.test.launcherhelper.LauncherStrategyFactory
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import org.junit.Assert
-class PipAppHelper(instr: Instrumentation) : FlickerAppHelper(instr, "PipApp") {
+class PipAppHelper(
+ instr: Instrumentation,
+ launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
+ .getInstance(instr)
+ .launcherStrategy
+) : FlickerAppHelper(instr, "PipApp", launcherStrategy) {
fun clickEnterPipButton(device: UiDevice) {
val enterPipButton = device.findObject(By.res(getPackage(), "enter_pip"))
Assert.assertNotNull("Pip button not found, this usually happens when the device " +
"was left in an unknown state (e.g. in split screen)", enterPipButton)
enterPipButton.click()
- AutomationUtils.hasPipWindow(device)
+ device.hasPipWindow()
}
fun closePipWindow(device: UiDevice) {
- AutomationUtils.closePipWindow(device)
+ device.closePipWindow()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
index 814cdcf..80d0394 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
@@ -16,11 +16,19 @@
package com.android.server.wm.flicker.ime
-import androidx.test.filters.FlakyTest
+import android.view.Surface
import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.dsl.flicker
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -35,33 +43,52 @@
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class CloseImeAutoOpenWindowToAppTest(
- beginRotationName: String,
- beginRotation: Int
-) : CloseImeWindowToAppTest(beginRotationName, beginRotation) {
- init {
- testApp = ImeAppAutoFocusHelper(instrumentation)
- }
+ rotationName: String,
+ rotation: Int
+) : CloseImeWindowToAppTest(rotationName, rotation) {
+ override val testApp: ImeAppHelper
+ get() = ImeAppAutoFocusHelper(instrumentation)
- override val transitionToRun: TransitionRunner
- get() = CommonTransitions.editTextLoseFocusToApp(testApp as ImeAppAutoFocusHelper,
- instrumentation, uiDevice, beginRotation)
- .includeJankyRuns().build()
-
- @FlakyTest(bugId = 141458352)
@Test
- override fun checkVisibility_imeLayerBecomesInvisible() {
- super.checkVisibility_imeLayerBecomesInvisible()
- }
+ override fun test() {
+ flicker(instrumentation) {
+ withTag { buildTestTag("imeToAppAutoOpen", testApp, rotation) }
+ repeat { 1 }
+ setup {
+ eachRun {
+ device.wakeUpAndGoToHomeScreen()
+ this.setRotation(rotation)
+ testApp.open()
+ testApp.openIME(device)
+ }
+ }
+ teardown {
+ eachRun {
+ testApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ }
+ transitions {
+ device.pressBack()
+ device.waitForIdle()
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ imeAppWindowIsAlwaysVisible(testApp, bugId = 141458352)
+ }
- @FlakyTest(bugId = 141458352)
- @Test
- override fun checkVisibility_imeAppLayerIsAlwaysVisible() {
- super.checkVisibility_imeAppLayerIsAlwaysVisible()
- }
-
- @FlakyTest(bugId = 141458352)
- @Test
- override fun checkVisibility_imeAppWindowIsAlwaysVisible() {
- super.checkVisibility_imeAppWindowIsAlwaysVisible()
+ layersTrace {
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ noUncoveredRegions(rotation)
+ navBarLayerRotatesAndScales(rotation)
+ statusBarLayerRotatesScales(rotation)
+ imeLayerBecomesInvisible(bugId = 141458352)
+ imeAppLayerIsAlwaysVisible(testApp, bugId = 141458352)
+ }
+ }
+ }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
index c2025b6..31d1fd3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
@@ -16,11 +16,19 @@
package com.android.server.wm.flicker.ime
-import androidx.test.filters.FlakyTest
+import android.view.Surface
import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.dsl.flicker
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -35,33 +43,53 @@
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class CloseImeAutoOpenWindowToHomeTest(
- beginRotationName: String,
- beginRotation: Int
-) : CloseImeWindowToHomeTest(beginRotationName, beginRotation) {
- init {
- testApp = ImeAppAutoFocusHelper(instrumentation)
- }
+ rotationName: String,
+ rotation: Int
+) : CloseImeWindowToHomeTest(rotationName, rotation) {
+ override val testApp: ImeAppHelper
+ get() = ImeAppAutoFocusHelper(instrumentation)
- override val transitionToRun: TransitionRunner
- get() = CommonTransitions.editTextLoseFocusToHome(testApp as ImeAppAutoFocusHelper,
- instrumentation, uiDevice, beginRotation)
- .includeJankyRuns().build()
-
- @FlakyTest(bugId = 141458352)
@Test
- override fun checkVisibility_imeWindowBecomesInvisible() {
- super.checkVisibility_imeWindowBecomesInvisible()
- }
+ override fun test() {
+ flicker(instrumentation) {
+ withTag { buildTestTag("imeToHomeAutoOpen", testApp, rotation) }
+ repeat { 1 }
+ setup {
+ eachRun {
+ device.wakeUpAndGoToHomeScreen()
+ this.setRotation(rotation)
+ testApp.open()
+ testApp.openIME(device)
+ }
+ }
+ teardown {
+ eachRun {
+ testApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ }
+ transitions {
+ device.pressHome()
+ device.waitForIdle()
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ imeWindowBecomesInvisible(bugId = 141458352)
+ imeAppWindowBecomesInvisible(testApp, bugId = 157449248)
+ }
- @FlakyTest(bugId = 141458352)
- @Test
- override fun checkVisibility_imeLayerBecomesInvisible() {
- super.checkVisibility_imeLayerBecomesInvisible()
- }
-
- @FlakyTest(bugId = 157449248)
- @Test
- override fun checkVisibility_imeAppWindowBecomesInvisible() {
- super.checkVisibility_imeAppWindowBecomesInvisible()
+ layersTrace {
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ noUncoveredRegions(rotation)
+ navBarLayerRotatesAndScales(rotation)
+ statusBarLayerRotatesScales(rotation)
+ imeLayerBecomesInvisible(bugId = 141458352)
+ imeAppLayerBecomesInvisible(testApp, bugId = 153739621)
+ }
+ }
+ }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
index b38262e..67c46d3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
@@ -16,14 +16,19 @@
package com.android.server.wm.flicker.ime
-import androidx.test.filters.FlakyTest
+import android.view.Surface
import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.dsl.flicker
import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -38,49 +43,51 @@
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
open class CloseImeWindowToAppTest(
- beginRotationName: String,
- beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
- init {
- testApp = ImeAppHelper(instrumentation)
- }
-
- override val transitionToRun: TransitionRunner
- get() = CommonTransitions.editTextLoseFocusToApp(testApp as ImeAppHelper,
- instrumentation, uiDevice, beginRotation)
- .includeJankyRuns().build()
-
- @FlakyTest
- @Test
- open fun checkVisibility_imeLayerBecomesInvisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer(IME_WINDOW_TITLE)
- .then()
- .hidesLayer(IME_WINDOW_TITLE)
- .forAllEntries()
- }
- }
+ rotationName: String,
+ rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
+ open val testApp = ImeAppHelper(instrumentation)
@Test
- open fun checkVisibility_imeAppLayerIsAlwaysVisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer(testApp.getPackage())
- .forAllEntries()
+ open fun test() {
+ flicker(instrumentation) {
+ withTag { buildTestTag("imeToApp", testApp, rotation) }
+ repeat { 1 }
+ setup {
+ eachRun {
+ device.wakeUpAndGoToHomeScreen()
+ this.setRotation(rotation)
+ testApp.open()
+ testApp.openIME(device)
+ }
+ }
+ teardown {
+ eachRun {
+ testApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ }
+ transitions {
+ device.pressBack()
+ device.waitForIdle()
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ imeAppWindowIsAlwaysVisible(testApp)
+ }
+
+ layersTrace {
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ noUncoveredRegions(rotation)
+ navBarLayerRotatesAndScales(rotation)
+ statusBarLayerRotatesScales(rotation)
+ imeLayerBecomesInvisible(enabled = false)
+ imeAppLayerIsAlwaysVisible(testApp)
+ }
+ }
}
}
-
- @Test
- open fun checkVisibility_imeAppWindowIsAlwaysVisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAppWindowOnTop(testApp.getPackage())
- .forAllEntries()
- }
- }
-
- companion object {
- const val IME_WINDOW_TITLE = "InputMethod"
- }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
index ca04bab..b643ec2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
@@ -16,20 +16,26 @@
package com.android.server.wm.flicker.ime
-import androidx.test.filters.FlakyTest
+import android.view.Surface
import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.dsl.flicker
import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.android.server.wm.flicker.helpers.openQuickstep
+import com.android.server.wm.flicker.helpers.reopenAppFromOverview
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
-
/**
* Test IME window closing to home transitions.
* To run this test: `atest FlickerTests:CloseImeWindowToHomeTest`
@@ -38,67 +44,60 @@
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
open class CloseImeWindowToHomeTest(
- beginRotationName: String,
- beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
- init {
- testApp = ImeAppHelper(instrumentation)
- }
-
- override val transitionToRun: TransitionRunner
- get() = CommonTransitions.editTextLoseFocusToHome(testApp as ImeAppHelper,
- instrumentation, uiDevice, beginRotation)
- .includeJankyRuns().build()
+ rotationName: String,
+ rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
+ open val testApp = ImeAppHelper(instrumentation)
@Test
- open fun checkVisibility_imeWindowBecomesInvisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsNonAppWindow(IME_WINDOW_TITLE)
- .then()
- .hidesNonAppWindow(IME_WINDOW_TITLE)
- .forAllEntries()
+ open fun test() {
+ flicker(instrumentation) {
+ withTag { buildTestTag("imeToHome", testApp, rotation) }
+ repeat { 1 }
+ setup {
+ test {
+ device.wakeUpAndGoToHomeScreen()
+ this.setRotation(rotation)
+ testApp.open()
+ }
+ eachRun {
+ device.openQuickstep()
+ device.reopenAppFromOverview()
+ this.setRotation(rotation)
+ testApp.openIME(device)
+ }
+ }
+ transitions {
+ device.pressHome()
+ device.waitForIdle()
+ }
+ teardown {
+ eachRun {
+ device.pressHome()
+ }
+ test {
+ testApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ imeWindowBecomesInvisible()
+ imeAppWindowBecomesInvisible(testApp)
+ }
+
+ layersTrace {
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ noUncoveredRegions(rotation)
+ navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0)
+ statusBarLayerRotatesScales(rotation, Surface.ROTATION_0)
+ imeLayerBecomesInvisible(bugId = 153739621)
+ imeAppLayerBecomesInvisible(testApp, bugId = 153739621)
+ }
+ }
}
}
-
- @FlakyTest(bugId = 153739621)
- @Test
- open fun checkVisibility_imeLayerBecomesInvisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .skipUntilFirstAssertion()
- .showsLayer(IME_WINDOW_TITLE)
- .then()
- .hidesLayer(IME_WINDOW_TITLE)
- .forAllEntries()
- }
- }
-
- @FlakyTest(bugId = 153739621)
- @Test
- fun checkVisibility_imeAppLayerBecomesInvisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .skipUntilFirstAssertion()
- .showsLayer(testApp.getPackage())
- .then()
- .hidesLayer(testApp.getPackage())
- .forAllEntries()
- }
- }
-
- @Test
- open fun checkVisibility_imeAppWindowBecomesInvisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAppWindowOnTop(testApp.getPackage())
- .then()
- .appWindowNotOnTop(testApp.getPackage())
- .forAllEntries()
- }
- }
-
- companion object {
- const val IME_WINDOW_TITLE: String = "InputMethod"
- }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ImeAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ImeAssertions.kt
new file mode 100644
index 0000000..b2be54f
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ImeAssertions.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2020 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.server.wm.flicker.ime
+
+import android.platform.helpers.IAppHelper
+import com.android.server.wm.flicker.dsl.LayersAssertion
+import com.android.server.wm.flicker.dsl.WmAssertion
+
+const val IME_WINDOW_TITLE = "InputMethod"
+
+@JvmOverloads
+fun LayersAssertion.imeLayerBecomesVisible(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("imeLayerBecomesVisible", enabled, bugId) {
+ this.hidesLayer(IME_WINDOW_TITLE)
+ .then()
+ .showsLayer(IME_WINDOW_TITLE)
+ }
+}
+
+fun LayersAssertion.imeLayerBecomesInvisible(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("imeLayerBecomesInvisible", enabled, bugId) {
+ this.showsLayer(IME_WINDOW_TITLE)
+ .then()
+ .hidesLayer(IME_WINDOW_TITLE)
+ }
+}
+
+fun LayersAssertion.imeAppLayerIsAlwaysVisible(
+ testApp: IAppHelper,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("imeAppLayerIsAlwaysVisible", enabled, bugId) {
+ this.showsLayer(testApp.getPackage())
+ }
+}
+
+fun WmAssertion.imeAppWindowIsAlwaysVisible(
+ testApp: IAppHelper,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("imeAppWindowIsAlwaysVisible", enabled, bugId) {
+ this.showsAppWindowOnTop(testApp.getPackage())
+ }
+}
+
+fun WmAssertion.imeWindowBecomesInvisible(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("imeWindowBecomesInvisible", enabled, bugId) {
+ this.showsNonAppWindow(IME_WINDOW_TITLE)
+ .then()
+ .hidesNonAppWindow(IME_WINDOW_TITLE)
+ }
+}
+
+fun WmAssertion.imeAppWindowBecomesInvisible(
+ testApp: IAppHelper,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("imeAppWindowBecomesInvisible", enabled, bugId) {
+ this.showsAppWindowOnTop(testApp.getPackage())
+ .then()
+ .appWindowNotOnTop(testApp.getPackage())
+ }
+}
+
+fun LayersAssertion.imeAppLayerBecomesInvisible(
+ testApp: IAppHelper,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("imeAppLayerBecomesInvisible", enabled, bugId) {
+ this.skipUntilFirstAssertion()
+ .showsLayer(testApp.getPackage())
+ .then()
+ .hidesLayer(testApp.getPackage())
+ }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
index c7731f3..5874a07 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
@@ -16,13 +16,19 @@
package com.android.server.wm.flicker.ime
+import android.view.Surface
import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.dsl.flicker
import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -37,38 +43,58 @@
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class OpenImeWindowTest(
- beginRotationName: String,
- beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
- init {
- testApp = ImeAppHelper(instrumentation)
- }
-
- override val transitionToRun: TransitionRunner
- get() = CommonTransitions.editTextSetFocus(testApp as ImeAppHelper,
- instrumentation, uiDevice, beginRotation)
- .includeJankyRuns().build()
-
+ rotationName: String,
+ rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
@Test
- fun checkVisibility_imeWindowBecomesVisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .skipUntilFirstAssertion()
- .hidesNonAppWindow(IME_WINDOW_TITLE)
- .then()
- .showsNonAppWindow(IME_WINDOW_TITLE)
- .forAllEntries()
- }
- }
+ fun test() {
+ val testApp = ImeAppHelper(instrumentation)
- @Test
- fun checkVisibility_imeLayerBecomesVisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .hidesLayer(IME_WINDOW_TITLE)
- .then()
- .showsLayer(IME_WINDOW_TITLE)
- .forAllEntries()
+ flicker(instrumentation) {
+ withTag { buildTestTag("openIme", testApp, rotation) }
+ repeat { 1 }
+ setup {
+ test {
+ device.wakeUpAndGoToHomeScreen()
+ this.setRotation(rotation)
+ testApp.open()
+ }
+ }
+ transitions {
+ testApp.openIME(device)
+ }
+ teardown {
+ eachRun {
+ testApp.closeIME(device)
+ }
+ test {
+ testApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+
+ all("imeWindowBecomesVisible") {
+ this.skipUntilFirstAssertion()
+ .hidesNonAppWindow(IME_WINDOW_TITLE)
+ .then()
+ .showsNonAppWindow(IME_WINDOW_TITLE)
+ }
+ }
+
+ layersTrace {
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ noUncoveredRegions(rotation)
+ navBarLayerRotatesAndScales(rotation)
+ statusBarLayerRotatesScales(rotation)
+
+ imeLayerBecomesVisible()
+ }
+ }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index 88b8854..1240e0d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -16,14 +16,17 @@
package com.android.server.wm.flicker.launch
-import androidx.test.filters.FlakyTest
+import android.view.Surface
import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
-import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.StandardAppHelper
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -38,50 +41,49 @@
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class OpenAppColdTest(
- beginRotationName: String,
- beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
- init {
- testApp = StandardAppHelper(instrumentation,
- "com.android.server.wm.flicker.testapp", "SimpleApp")
- }
-
- override val transitionToRun: TransitionRunner
- get() = CommonTransitions.openAppCold(testApp, instrumentation, uiDevice, beginRotation)
- .includeJankyRuns().build()
-
+ rotationName: String,
+ rotation: Int
+) : OpenAppTestBase(rotationName, rotation) {
@Test
- fun checkVisibility_wallpaperWindowBecomesInvisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsBelowAppWindow("Wallpaper")
- .then()
- .hidesBelowAppWindow("Wallpaper")
- .forAllEntries()
- }
- }
+ fun test() {
+ flicker(instrumentation) {
+ withTag { buildTestTag("openAppCold", testApp, rotation) }
+ repeat { 1 }
+ setup {
+ test {
+ device.wakeUpAndGoToHomeScreen()
+ }
+ eachRun {
+ this.setRotation(rotation)
+ }
+ }
+ transitions {
+ testApp.open()
+ }
+ teardown {
+ eachRun {
+ testApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ appWindowReplacesLauncherAsTopWindow(bugId = 141361128)
+ wallpaperWindowBecomesInvisible()
+ }
- @FlakyTest(bugId = 140855415)
- @Test
- fun checkZOrder_appWindowReplacesLauncherAsTopWindow() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAppWindowOnTop(
- "com.android.launcher3/.Launcher")
- .then()
- .showsAppWindowOnTop(testApp.getPackage())
- .forAllEntries()
- }
- }
-
- @Test
- fun checkVisibility_wallpaperLayerBecomesInvisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer("Wallpaper")
- .then()
- .replaceVisibleLayer("Wallpaper", testApp.getPackage())
- .forAllEntries()
+ layersTrace {
+ noUncoveredRegions(rotation, bugId = 141361128)
+ // During testing the launcher is always in portrait mode
+ navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation)
+ statusBarLayerRotatesScales(Surface.ROTATION_0, rotation)
+ navBarLayerIsAlwaysVisible(bugId = 141361128)
+ statusBarLayerIsAlwaysVisible(bugId = 141361128)
+ wallpaperLayerBecomesInvisible(bugId = 141361128)
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt
new file mode 100644
index 0000000..3cec077
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2020 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.server.wm.flicker.launch
+
+import com.android.server.wm.flicker.NonRotationTestBase
+import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.dsl.LayersAssertion
+import com.android.server.wm.flicker.dsl.WmAssertion
+
+abstract class OpenAppTestBase(
+ rotationName: String,
+ rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
+ protected val testApp = StandardAppHelper(instrumentation,
+ "com.android.server.wm.flicker.testapp", "SimpleApp")
+
+ protected fun WmAssertion.wallpaperWindowBecomesInvisible(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+ ) {
+ all("wallpaperWindowBecomesInvisible", enabled, bugId) {
+ this.showsBelowAppWindow("Wallpaper")
+ .then()
+ .hidesBelowAppWindow("Wallpaper")
+ }
+ }
+
+ protected fun WmAssertion.appWindowReplacesLauncherAsTopWindow(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+ ) {
+ all("appWindowReplacesLauncherAsTopWindow", enabled, bugId) {
+ this.showsAppWindowOnTop(
+ "Launcher")
+ .then()
+ .showsAppWindowOnTop(testApp.getPackage())
+ }
+ }
+
+ protected fun LayersAssertion.wallpaperLayerBecomesInvisible(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+ ) {
+ all("appWindowReplacesLauncherAsTopWindow", enabled, bugId) {
+ this.showsLayer("Wallpaper")
+ .then()
+ .replaceVisibleLayer("Wallpaper", testApp.getPackage())
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index f0bc3f0..98413a1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -16,14 +16,18 @@
package com.android.server.wm.flicker.launch
-import androidx.test.filters.FlakyTest
+import android.view.Surface
import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
-import com.android.server.wm.flicker.NonRotationTestBase
import com.android.server.wm.flicker.StandardAppHelper
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -38,50 +42,56 @@
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class OpenAppWarmTest(
- beginRotationName: String,
- beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
- init {
- testApp = StandardAppHelper(instrumentation,
+ rotationName: String,
+ rotation: Int
+) : OpenAppTestBase(rotationName, rotation) {
+ @Test
+ fun test() {
+ val testApp = StandardAppHelper(instrumentation,
"com.android.server.wm.flicker.testapp", "SimpleApp")
- }
- override val transitionToRun: TransitionRunner
- get() = CommonTransitions.openAppWarm(testApp, instrumentation, uiDevice, beginRotation)
- .includeJankyRuns().build()
+ flicker(instrumentation) {
+ withTag { buildTestTag("openAppWarm", testApp, rotation) }
+ repeat { 1 }
+ setup {
+ test {
+ device.wakeUpAndGoToHomeScreen()
+ testApp.open()
+ }
+ eachRun {
+ device.pressHome()
+ this.setRotation(rotation)
+ }
+ }
+ transitions {
+ testApp.open()
+ }
+ teardown {
+ eachRun {
+ this.setRotation(Surface.ROTATION_0)
+ }
+ test {
+ testApp.exit()
+ }
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ appWindowReplacesLauncherAsTopWindow(bugId = 141361128)
+ wallpaperWindowBecomesInvisible(enabled = false)
+ }
- @Test
- fun checkVisibility_wallpaperBecomesInvisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsBelowAppWindow("Wallpaper")
- .then()
- .hidesBelowAppWindow("Wallpaper")
- .forAllEntries()
+ layersTrace {
+ noUncoveredRegions(rotation, bugId = 141361128)
+ // During testing the launcher is always in portrait mode
+ navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation)
+ statusBarLayerRotatesScales(Surface.ROTATION_0, rotation)
+ navBarLayerIsAlwaysVisible(bugId = 141361128)
+ statusBarLayerIsAlwaysVisible(bugId = 141361128)
+ wallpaperLayerBecomesInvisible(bugId = 141361128)
+ }
+ }
}
}
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun checkZOrder_appWindowReplacesLauncherAsTopWindow() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAppWindowOnTop(
- "com.android.launcher3/.Launcher")
- .then()
- .showsAppWindowOnTop(testApp.getPackage())
- .forAllEntries()
- }
- }
-
- @Test
- fun checkVisibility_wallpaperLayerBecomesInvisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer("Wallpaper")
- .then()
- .replaceVisibleLayer("Wallpaper", testApp.getPackage())
- .forAllEntries()
- }
- }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt
index 79321f9..4afabd4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt
@@ -16,66 +16,36 @@
package com.android.server.wm.flicker.pip
-import androidx.test.InstrumentationRegistry
-import androidx.test.filters.LargeTest
-import androidx.test.uiautomator.UiDevice
-import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.dsl.LayersAssertion
import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.WmTraceSubject
-import com.android.server.wm.flicker.helpers.AutomationUtils
+import com.android.server.wm.flicker.dsl.WmAssertion
import com.android.server.wm.flicker.helpers.PipAppHelper
-import org.junit.AfterClass
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-@LargeTest
-@RunWith(Parameterized::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
abstract class PipTestBase(
- beginRotationName: String,
- beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
- init {
- testApp = PipAppHelper(instrumentation)
- }
+ rotationName: String,
+ rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
+ protected val testApp = PipAppHelper(instrumentation)
- @Test
- fun checkVisibility_pipWindowBecomesVisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .skipUntilFirstAssertion()
+ protected fun WmAssertion.pipWindowBecomesVisible() {
+ all("pipWindowBecomesVisible") {
+ this.skipUntilFirstAssertion()
.showsAppWindowOnTop(sPipWindowTitle)
.then()
.hidesAppWindow(sPipWindowTitle)
- .forAllEntries()
}
}
- @Test
- fun checkVisibility_pipLayerBecomesVisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .skipUntilFirstAssertion()
+ protected fun LayersAssertion.pipLayerBecomesVisible() {
+ all("pipLayerBecomesVisible") {
+ this.skipUntilFirstAssertion()
.showsLayer(sPipWindowTitle)
.then()
.hidesLayer(sPipWindowTitle)
- .forAllEntries()
}
}
companion object {
const val sPipWindowTitle = "PipMenuActivity"
-
- @AfterClass
- @JvmStatic
- fun teardown() {
- val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- if (AutomationUtils.hasPipWindow(device)) {
- AutomationUtils.closePipWindow(device)
- }
- }
}
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt
index 89ffb7a..e5a73f7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt
@@ -16,12 +16,21 @@
package com.android.server.wm.flicker.pip
+import android.view.Surface
import androidx.test.filters.FlakyTest
import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
-import com.android.server.wm.flicker.helpers.PipAppHelper
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.closePipWindow
+import com.android.server.wm.flicker.helpers.expandPipWindow
+import com.android.server.wm.flicker.helpers.hasPipWindow
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -37,27 +46,55 @@
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 152738416)
class PipToAppTest(
- beginRotationName: String,
- beginRotation: Int
-) : PipTestBase(beginRotationName, beginRotation) {
- override val transitionToRun: TransitionRunner
- get() = CommonTransitions.exitPipModeToApp(testApp as PipAppHelper, instrumentation,
- uiDevice, beginRotation)
- .includeJankyRuns().build()
-
+ rotationName: String,
+ rotation: Int
+) : PipTestBase(rotationName, rotation) {
@Test
- fun checkVisibility_backgroundWindowVisibleBehindPipLayer() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .skipUntilFirstAssertion()
- .showsAppWindowOnTop(sPipWindowTitle)
- .then()
- .showsBelowAppWindow("Wallpaper")
- .then()
- .showsAppWindowOnTop(testApp.getPackage())
- .then()
- .appWindowNotOnTop(testApp.getPackage())
- .forAllEntries()
+ fun test() {
+ flicker(instrumentation) {
+ withTag { buildTestTag("exitPipModeToApp", testApp, rotation) }
+ repeat { 1 }
+ setup {
+ eachRun {
+ device.wakeUpAndGoToHomeScreen()
+ }
+ }
+ teardown {
+ eachRun {
+ testApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ test {
+ if (device.hasPipWindow()) {
+ device.closePipWindow()
+ }
+ }
+ }
+ transitions {
+ device.pressHome()
+ this.setRotation(rotation)
+ testApp.open()
+ testApp.clickEnterPipButton(device)
+ device.expandPipWindow()
+ device.waitForIdle()
+ testApp.exit()
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ pipWindowBecomesVisible()
+ }
+
+ layersTrace {
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ noUncoveredRegions(rotation)
+ navBarLayerRotatesAndScales(rotation)
+ statusBarLayerRotatesScales(rotation)
+ pipLayerBecomesVisible()
+ }
+ }
}
}
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt
index 8591360..f6d9ce2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt
@@ -16,12 +16,20 @@
package com.android.server.wm.flicker.pip
+import android.view.Surface
import androidx.test.filters.FlakyTest
import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
-import com.android.server.wm.flicker.helpers.PipAppHelper
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.closePipWindow
+import com.android.server.wm.flicker.helpers.hasPipWindow
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -37,24 +45,63 @@
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 152738416)
class PipToHomeTest(
- beginRotationName: String,
- beginRotation: Int
-) : PipTestBase(beginRotationName, beginRotation) {
- override val transitionToRun: TransitionRunner
- get() = CommonTransitions.exitPipModeToHome(testApp as PipAppHelper, instrumentation,
- uiDevice, beginRotation)
- .includeJankyRuns().build()
-
+ rotationName: String,
+ rotation: Int
+) : PipTestBase(rotationName, rotation) {
@Test
- fun checkVisibility_backgroundWindowVisibleBehindPipLayer() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAppWindowOnTop(sPipWindowTitle)
- .then()
- .showsBelowAppWindow("Wallpaper")
- .then()
- .showsAppWindowOnTop("Wallpaper")
- .forAllEntries()
+ fun test() {
+ flicker(instrumentation) {
+ withTag { buildTestTag("exitPipModeToApp", testApp, rotation) }
+ repeat { 1 }
+ setup {
+ eachRun {
+ device.wakeUpAndGoToHomeScreen()
+ device.pressHome()
+ this.setRotation(rotation)
+ testApp.open()
+ }
+ }
+ teardown {
+ eachRun {
+ testApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ test {
+ if (device.hasPipWindow()) {
+ device.closePipWindow()
+ }
+ }
+ }
+ transitions {
+ testApp.clickEnterPipButton(device)
+ testApp.closePipWindow(device)
+ device.waitForIdle()
+ testApp.exit()
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ pipWindowBecomesVisible()
+
+ all {
+ this.showsAppWindowOnTop(sPipWindowTitle)
+ .and()
+ .showsBelowAppWindow("Wallpaper")
+ .then()
+ .showsAboveAppWindow("Wallpaper")
+ }
+ }
+
+ layersTrace {
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ noUncoveredRegions(rotation)
+ navBarLayerRotatesAndScales(rotation)
+ statusBarLayerRotatesScales(rotation)
+ pipLayerBecomesVisible()
+ }
+ }
}
}
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index fb1cb39..239c082 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -16,15 +16,21 @@
package com.android.server.wm.flicker.rotation
-import android.util.Log
-import androidx.test.filters.FlakyTest
+import android.view.Surface
import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.NonRotationTestBase.Companion.SCREENSHOT_LAYER
import com.android.server.wm.flicker.RotationTestBase
import com.android.server.wm.flicker.StandardAppHelper
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WindowUtils
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -44,42 +50,76 @@
beginRotation: Int,
endRotation: Int
) : RotationTestBase(beginRotationName, endRotationName, beginRotation, endRotation) {
- init {
- testApp = StandardAppHelper(instrumentation,
+ @Test
+ fun test() {
+ val testApp = StandardAppHelper(instrumentation,
"com.android.server.wm.flicker.testapp", "SimpleApp")
- }
- override val transitionToRun: TransitionRunner
- get() = CommonTransitions.changeAppRotation(testApp, instrumentation, uiDevice,
- beginRotation, endRotation)
- .includeJankyRuns().build()
+ flicker(instrumentation) {
+ withTag {
+ buildTestTag("changeAppRotation", testApp, beginRotation, endRotation)
+ }
+ repeat { 1 }
+ setup {
+ eachRun {
+ device.wakeUpAndGoToHomeScreen()
+ testApp.open()
+ this.setRotation(beginRotation)
+ }
+ }
+ teardown {
+ eachRun {
+ testApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ }
+ transitions {
+ this.setRotation(endRotation)
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible(bugId = 140855415)
+ statusBarWindowIsAlwaysVisible(bugId = 140855415)
+ }
- @Test
- fun checkPosition_appLayerRotates() {
- val startingPos = WindowUtils.getAppPosition(beginRotation)
- val endingPos = WindowUtils.getAppPosition(endRotation)
- Log.e(TAG, "startingPos=$startingPos endingPos=$endingPos")
- checkResults {
- LayersTraceSubject.assertThat(it)
- .hasVisibleRegion(testApp.getPackage(), startingPos).inTheBeginning()
- LayersTraceSubject.assertThat(it)
- .hasVisibleRegion(testApp.getPackage(), endingPos).atTheEnd()
+ layersTrace {
+ navBarLayerIsAlwaysVisible(bugId = 140855415)
+ statusBarLayerIsAlwaysVisible(bugId = 140855415)
+ noUncoveredRegions(beginRotation, endRotation, allStates = false)
+ navBarLayerRotatesAndScales(beginRotation, endRotation)
+ statusBarLayerRotatesScales(beginRotation, endRotation)
+ }
+
+ layersTrace {
+ val startingPos = WindowUtils.getDisplayBounds(beginRotation)
+ val endingPos = WindowUtils.getDisplayBounds(endRotation)
+
+ start("appLayerRotates_StartingPos") {
+ this.hasVisibleRegion(testApp.getPackage(), startingPos)
+ }
+
+ end("appLayerRotates_EndingPos") {
+ this.hasVisibleRegion(testApp.getPackage(), endingPos)
+ }
+
+ all("screenshotLayerBecomesInvisible", enabled = false) {
+ this.showsLayer(testApp.getPackage())
+ .then()
+ .replaceVisibleLayer(
+ testApp.getPackage(),
+ SCREENSHOT_LAYER)
+ .then()
+ .showsLayer(testApp.getPackage())
+ .and()
+ .showsLayer(SCREENSHOT_LAYER)
+ .then()
+ .replaceVisibleLayer(
+ SCREENSHOT_LAYER,
+ testApp.getPackage()
+ )
+ }
+ }
+ }
}
}
-
- @FlakyTest
- @Test
- fun checkVisibility_screenshotLayerBecomesInvisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer(testApp.getPackage())
- .then()
- .replaceVisibleLayer(testApp.getPackage(), SCREENSHOT_LAYER)
- .then()
- .showsLayer(testApp.getPackage()).and().showsLayer(SCREENSHOT_LAYER)
- .then()
- .replaceVisibleLayer(SCREENSHOT_LAYER, testApp.getPackage())
- .forAllEntries()
- }
- }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index 1cd1998..4746376 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -17,15 +17,24 @@
package com.android.server.wm.flicker.rotation
import android.content.Intent
+import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.view.Surface
-import androidx.test.InstrumentationRegistry
import androidx.test.filters.FlakyTest
import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.RotationTestBase
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WindowUtils
+import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.stopPackage
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import com.android.server.wm.flicker.testapp.ActivityOptions
import org.junit.FixMethodOrder
import org.junit.Test
@@ -42,67 +51,97 @@
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 147659548)
class SeamlessAppRotationTest(
+ testId: String,
private val intent: Intent,
beginRotationName: String,
endRotationName: String,
beginRotation: Int,
endRotation: Int
) : RotationTestBase(beginRotationName, endRotationName, beginRotation, endRotation) {
- override val transitionToRun: TransitionRunner
- get() {
- var intentId = ""
- if (intent.extras?.getBoolean(ActivityOptions.EXTRA_STARVE_UI_THREAD) == true) {
- intentId = "BUSY_UI_THREAD"
- }
- return CommonTransitions.changeAppRotation(intent, intentId,
- InstrumentationRegistry.getContext(), instrumentation, uiDevice,
- beginRotation, endRotation).build()
+ @Test
+ fun test() {
+ var intentId = ""
+ if (intent.extras?.getBoolean(ActivityOptions.EXTRA_STARVE_UI_THREAD) == true) {
+ intentId = "BUSY_UI_THREAD"
}
- @Test
- fun checkPosition_appLayerRotates() {
- val startingPos = WindowUtils.getAppPosition(beginRotation)
- val endingPos = WindowUtils.getAppPosition(endRotation)
- if (startingPos == endingPos) {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .hasVisibleRegion(intent.component?.packageName ?: "", startingPos)
- .forAllEntries()
+ flicker(instrumentation) {
+ withTag {
+ "changeAppRotation_" + intentId + "_" +
+ Surface.rotationToString(beginRotation) + "_" +
+ Surface.rotationToString(endRotation)
}
- } else {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .hasVisibleRegion(intent.component?.packageName ?: "", startingPos)
- .then()
- .hasVisibleRegion(intent.component?.packageName ?: "", endingPos)
- .forAllEntries()
+ repeat { 1 }
+ setup {
+ eachRun {
+ device.wakeUpAndGoToHomeScreen()
+ instrumentation.targetContext.startActivity(intent)
+ device.wait(Until.hasObject(By.pkg(intent.component?.packageName)
+ .depth(0)), APP_LAUNCH_TIMEOUT)
+ this.setRotation(beginRotation)
+ }
}
- }
- }
+ teardown {
+ eachRun {
+ stopPackage(
+ instrumentation.targetContext,
+ intent.component?.packageName
+ ?: error("Unable to determine package name for intent"))
+ this.setRotation(Surface.ROTATION_0)
+ }
+ }
+ transitions {
+ this.setRotation(endRotation)
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible(bugId = 140855415)
+ statusBarWindowIsAlwaysVisible(bugId = 140855415)
+ }
- @Test
- fun checkCoveredRegion_noUncoveredRegions() {
- val startingBounds = WindowUtils.getDisplayBounds(beginRotation)
- val endingBounds = WindowUtils.getDisplayBounds(endRotation)
- if (startingBounds == endingBounds) {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .coversRegion(startingBounds)
- .forAllEntries()
- }
- } else {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .coversRegion(startingBounds)
- .then()
- .coversRegion(endingBounds)
- .forAllEntries()
+ layersTrace {
+ navBarLayerIsAlwaysVisible(bugId = 140855415)
+ statusBarLayerIsAlwaysVisible(bugId = 140855415)
+ noUncoveredRegions(beginRotation, endRotation, allStates = true)
+ navBarLayerRotatesAndScales(beginRotation, endRotation)
+ statusBarLayerRotatesScales(beginRotation, endRotation, enabled = false)
+ }
+
+ layersTrace {
+ all("appLayerRotates"/*, bugId = 147659548*/) {
+ val startingPos = WindowUtils.getDisplayBounds(beginRotation)
+ val endingPos = WindowUtils.getDisplayBounds(endRotation)
+
+ if (startingPos == endingPos) {
+ this.hasVisibleRegion(
+ intent.component?.packageName ?: "",
+ startingPos)
+ } else {
+ this.hasVisibleRegion(intent.component?.packageName ?: "", startingPos)
+ .then()
+ .hasVisibleRegion(intent.component?.packageName
+ ?: "", endingPos)
+ }
+ }
+
+ all("noUncoveredRegions"/*, bugId = 147659548*/) {
+ val startingBounds = WindowUtils.getDisplayBounds(beginRotation)
+ val endingBounds = WindowUtils.getDisplayBounds(endRotation)
+ if (startingBounds == endingBounds) {
+ this.coversRegion(startingBounds)
+ } else {
+ this.coversRegion(startingBounds)
+ .then()
+ .coversRegion(endingBounds)
+ }
+ }
+ }
}
}
}
companion object {
- // launch test activity that supports seamless rotation
+ private const val APP_LAUNCH_TIMEOUT: Long = 10000
// launch test activity that supports seamless rotation with a busy UI thread to miss frames
// when the app is asked to redraw
@@ -110,18 +149,20 @@
@JvmStatic
fun getParams(): Collection<Array<Any>> {
val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90)
- val params: MutableCollection<Array<Any>> = ArrayList()
- val testIntents = ArrayList<Intent>()
+ val params = mutableListOf<Array<Any>>()
+ val testIntents = mutableListOf<Intent>()
// launch test activity that supports seamless rotation
var intent = Intent(Intent.ACTION_MAIN)
intent.component = ActivityOptions.SEAMLESS_ACTIVITY_COMPONENT_NAME
+ intent.flags = FLAG_ACTIVITY_NEW_TASK
testIntents.add(intent)
// launch test activity that supports seamless rotation with a busy UI thread to miss frames
// when the app is asked to redraw
intent = Intent(intent)
intent.putExtra(ActivityOptions.EXTRA_STARVE_UI_THREAD, true)
+ intent.flags = FLAG_ACTIVITY_NEW_TASK
testIntents.add(intent)
for (testIntent in testIntents) {
for (begin in supportedRotations) {
@@ -133,7 +174,13 @@
ActivityOptions.EXTRA_STARVE_UI_THREAD) == true) {
testId += "_" + "BUSY_UI_THREAD"
}
- params.add(arrayOf(testId, testIntent, begin, end))
+ params.add(arrayOf(
+ testId,
+ testIntent,
+ Surface.rotationToString(begin),
+ Surface.rotationToString(end),
+ begin,
+ end))
}
}
}
@@ -141,4 +188,4 @@
return params
}
}
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
index b5611a4..7c19696 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
@@ -16,13 +16,22 @@
package com.android.server.wm.flicker.splitscreen
+import android.os.SystemClock
+import android.view.Surface
import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
import com.android.server.wm.flicker.NonRotationTestBase
import com.android.server.wm.flicker.StandardAppHelper
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.exitSplitScreen
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -37,42 +46,63 @@
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class OpenAppToSplitScreenTest(
- beginRotationName: String,
- beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
- init {
- testApp = StandardAppHelper(instrumentation,
- "com.android.server.wm.flicker.testapp", "SimpleApp")
- }
-
- override val transitionToRun: TransitionRunner
- get() = CommonTransitions.appToSplitScreen(testApp, instrumentation, uiDevice,
- beginRotation).includeJankyRuns().build()
-
+ rotationName: String,
+ rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
@Test
- fun checkVisibility_navBarWindowIsAlwaysVisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
+ fun test() {
+ val testApp = StandardAppHelper(instrumentation,
+ "com.android.server.wm.flicker.testapp", "SimpleApp")
+
+ flicker(instrumentation) {
+ withTag { buildTestTag("appToSplitScreen", testApp, rotation) }
+ repeat { 1 }
+ setup {
+ eachRun {
+ device.wakeUpAndGoToHomeScreen()
+ this.setRotation(rotation)
+ testApp.open()
+ SystemClock.sleep(500)
+ }
+ }
+ teardown {
+ eachRun {
+ device.exitSplitScreen()
+ testApp.exit()
+ }
+ }
+ transitions {
+ device.launchSplitScreen()
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ }
+
+ layersTrace {
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ noUncoveredRegions(rotation)
+ navBarLayerRotatesAndScales(rotation)
+ statusBarLayerRotatesScales(rotation)
+
+ all("dividerLayerBecomesVisible") {
+ this.hidesLayer(DOCKED_STACK_DIVIDER)
+ .then()
+ .showsLayer(DOCKED_STACK_DIVIDER)
+ }
+ }
+ }
}
}
- @Test
- fun checkVisibility_statusBarWindowIsAlwaysVisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries()
- }
- }
-
- @Test
- fun checkVisibility_dividerLayerBecomesVisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .hidesLayer(DOCKED_STACK_DIVIDER)
- .then()
- .showsLayer(DOCKED_STACK_DIVIDER)
- .forAllEntries()
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val supportedRotations = intArrayOf(Surface.ROTATION_0)
+ return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt
index 6b597e5..a93330d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt
@@ -19,24 +19,27 @@
import android.graphics.Region
import android.util.Rational
import android.view.Surface
-import androidx.test.InstrumentationRegistry
import androidx.test.filters.FlakyTest
import androidx.test.filters.LargeTest
-import androidx.test.runner.AndroidJUnit4
-import androidx.test.uiautomator.UiDevice
-import com.android.server.wm.flicker.CommonTransitions
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.uiautomator.By
import com.android.server.wm.flicker.FlickerTestBase
-import com.android.server.wm.flicker.LayersTrace
-import com.android.server.wm.flicker.LayersTraceSubject
import com.android.server.wm.flicker.StandardAppHelper
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.TransitionResult
-import com.android.server.wm.flicker.WindowUtils
-import com.android.server.wm.flicker.WmTraceSubject
-import com.android.server.wm.flicker.helpers.AutomationUtils
+import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.dsl.flicker
import com.android.server.wm.flicker.helpers.ImeAppHelper
-import com.google.common.truth.Truth
-import org.junit.AfterClass
+import com.android.server.wm.flicker.helpers.exitSplitScreen
+import com.android.server.wm.flicker.helpers.isInSplitScreen
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.helpers.resizeSplitScreen
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -53,146 +56,130 @@
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 159096424)
class ResizeSplitScreenTest : FlickerTestBase() {
- init {
- testApp = StandardAppHelper(instrumentation,
+ @Test
+ fun test() {
+ val testAppTop = StandardAppHelper(instrumentation,
"com.android.server.wm.flicker.testapp", "SimpleApp")
- }
+ val testAppBottom = ImeAppHelper(instrumentation)
- override val transitionToRun: TransitionRunner
- get() {
- val bottomApp = ImeAppHelper(instrumentation)
- return CommonTransitions.resizeSplitScreen(testApp, bottomApp, instrumentation,
- uiDevice, Surface.ROTATION_0,
- Rational(1, 3), Rational(2, 3))
- .includeJankyRuns().build()
- }
+ flicker(instrumentation) {
+ withTag {
+ val description = (startRatio.toString().replace("/", "-") + "_to_" +
+ stopRatio.toString().replace("/", "-"))
+ buildTestTag("resizeSplitScreen", testAppTop, rotation,
+ rotation, testAppBottom, description)
+ }
+ repeat { 1 }
+ setup {
+ eachRun {
+ device.wakeUpAndGoToHomeScreen()
+ this.setRotation(rotation)
+ this.launcherStrategy.clearRecentAppsFromOverview()
+ testAppBottom.open()
+ device.pressHome()
+ testAppTop.open()
+ device.waitForIdle()
+ device.launchSplitScreen()
+ val snapshot = device.findObject(By.res(device.launcherPackageName, "snapshot"))
+ snapshot.click()
+ testAppBottom.openIME(device)
+ device.pressBack()
+ device.resizeSplitScreen(startRatio)
+ }
+ }
+ teardown {
+ eachRun {
+ device.exitSplitScreen()
+ device.pressHome()
+ testAppTop.exit()
+ testAppBottom.exit()
+ }
+ test {
+ if (device.isInSplitScreen()) {
+ device.exitSplitScreen()
+ }
+ }
+ }
+ transitions {
+ device.resizeSplitScreen(stopRatio)
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
- @Test
- fun checkVisibility_topAppLayerIsAlwaysVisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer(sSimpleActivity)
- .forAllEntries()
- }
- }
+ all("topAppWindowIsAlwaysVisible", bugId = 156223549) {
+ this.showsAppWindow(sSimpleActivity)
+ }
- @Test
- fun checkVisibility_bottomAppLayerIsAlwaysVisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer(sImeActivity)
- .forAllEntries()
- }
- }
+ all("bottomAppWindowIsAlwaysVisible", bugId = 156223549) {
+ this.showsAppWindow(sImeActivity)
+ }
+ }
- @Test
- fun checkVisibility_dividerLayerIsAlwaysVisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer(DOCKED_STACK_DIVIDER)
- .forAllEntries()
- }
- }
+ layersTrace {
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ noUncoveredRegions(rotation)
+ navBarLayerRotatesAndScales(rotation)
+ statusBarLayerRotatesScales(rotation)
- @Test
- @FlakyTest
- fun checkPosition_appsStartingBounds() {
- val displayBounds = WindowUtils.getDisplayBounds()
- checkResults { result: TransitionResult ->
- val entries = LayersTrace.parseFrom(result.layersTrace,
- result.layersTracePath, result.layersTraceChecksum)
- Truth.assertThat(entries.entries).isNotEmpty()
- val startingDividerBounds = entries.entries[0].getVisibleBounds(
- DOCKED_STACK_DIVIDER).bounds
- val startingTopAppBounds = Region(0, 0, startingDividerBounds.right,
- startingDividerBounds.top + WindowUtils.getDockedStackDividerInset())
- val startingBottomAppBounds = Region(0,
- startingDividerBounds.bottom - WindowUtils.getDockedStackDividerInset(),
- displayBounds.right,
- displayBounds.bottom - WindowUtils.getNavigationBarHeight())
- LayersTraceSubject.assertThat(result)
- .hasVisibleRegion("SimpleActivity", startingTopAppBounds)
- .inTheBeginning()
- LayersTraceSubject.assertThat(result)
- .hasVisibleRegion("ImeActivity", startingBottomAppBounds)
- .inTheBeginning()
- }
- }
+ all("topAppLayerIsAlwaysVisible") {
+ this.showsLayer(sSimpleActivity)
+ }
- @Test
- @FlakyTest
- fun checkPosition_appsEndingBounds() {
- val displayBounds = WindowUtils.getDisplayBounds()
- checkResults { result: TransitionResult ->
- val entries = LayersTrace.parseFrom(result.layersTrace,
- result.layersTracePath, result.layersTraceChecksum)
- Truth.assertThat(entries.entries).isNotEmpty()
- val endingDividerBounds = entries.entries[entries.entries.size - 1].getVisibleBounds(
- DOCKED_STACK_DIVIDER).bounds
- val startingTopAppBounds = Region(0, 0, endingDividerBounds.right,
- endingDividerBounds.top + WindowUtils.getDockedStackDividerInset())
- val startingBottomAppBounds = Region(0,
- endingDividerBounds.bottom - WindowUtils.getDockedStackDividerInset(),
- displayBounds.right,
- displayBounds.bottom - WindowUtils.getNavigationBarHeight())
- LayersTraceSubject.assertThat(result)
- .hasVisibleRegion(sSimpleActivity, startingTopAppBounds)
- .atTheEnd()
- LayersTraceSubject.assertThat(result)
- .hasVisibleRegion(sImeActivity, startingBottomAppBounds)
- .atTheEnd()
- }
- }
+ all("bottomAppLayerIsAlwaysVisible") {
+ this.showsLayer(sImeActivity)
+ }
- @Test
- fun checkVisibility_navBarWindowIsAlwaysVisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE)
- .forAllEntries()
- }
- }
+ all("dividerLayerIsAlwaysVisible") {
+ this.showsLayer(DOCKED_STACK_DIVIDER)
+ }
- @Test
- fun checkVisibility_statusBarWindowIsAlwaysVisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE)
- .forAllEntries()
- }
- }
+ start("appsStartingBounds", enabled = false) {
+ val displayBounds = WindowUtils.displayBounds
+ val entry = this.trace.entries.firstOrNull()
+ ?: throw IllegalStateException("Trace is empty")
+ val dividerBounds = entry.getVisibleBounds(DOCKED_STACK_DIVIDER).bounds
- @Test
- @FlakyTest(bugId = 156223549)
- fun checkVisibility_topAppWindowIsAlwaysVisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAppWindow(sSimpleActivity)
- .forAllEntries()
- }
- }
+ val topAppBounds = Region(0, 0, dividerBounds.right,
+ dividerBounds.top + WindowUtils.dockedStackDividerInset)
+ val bottomAppBounds = Region(0,
+ dividerBounds.bottom - WindowUtils.dockedStackDividerInset,
+ displayBounds.right,
+ displayBounds.bottom - WindowUtils.navigationBarHeight)
+ this.hasVisibleRegion("SimpleActivity", topAppBounds)
+ .and()
+ .hasVisibleRegion("ImeActivity", bottomAppBounds)
+ }
- @Test
- @FlakyTest(bugId = 156223549)
- fun checkVisibility_bottomAppWindowIsAlwaysVisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAppWindow(sImeActivity)
- .forAllEntries()
+ end("appsEndingBounds", enabled = false) {
+ val displayBounds = WindowUtils.displayBounds
+ val entry = this.trace.entries.lastOrNull()
+ ?: throw IllegalStateException("Trace is empty")
+ val dividerBounds = entry.getVisibleBounds(DOCKED_STACK_DIVIDER).bounds
+
+ val topAppBounds = Region(0, 0, dividerBounds.right,
+ dividerBounds.top + WindowUtils.dockedStackDividerInset)
+ val bottomAppBounds = Region(0,
+ dividerBounds.bottom - WindowUtils.dockedStackDividerInset,
+ displayBounds.right,
+ displayBounds.bottom - WindowUtils.navigationBarHeight)
+
+ this.hasVisibleRegion(sSimpleActivity, topAppBounds)
+ .and()
+ .hasVisibleRegion(sImeActivity, bottomAppBounds)
+ }
+ }
+ }
}
}
companion object {
private const val sSimpleActivity = "SimpleActivity"
private const val sImeActivity = "ImeActivity"
-
- @AfterClass
- @JvmStatic
- fun teardown() {
- val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- if (AutomationUtils.isInSplitScreen(device)) {
- AutomationUtils.exitSplitScreen(device)
- }
- }
+ private val rotation = Surface.ROTATION_0
+ private val startRatio = Rational(1, 3)
+ private val stopRatio = Rational(2, 3)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
index fdcafdb..268ba9e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
@@ -17,19 +17,22 @@
package com.android.server.wm.flicker.splitscreen
import android.view.Surface
-import androidx.test.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
-import androidx.test.runner.AndroidJUnit4
-import androidx.test.uiautomator.UiDevice
-import com.android.server.wm.flicker.CommonTransitions
import com.android.server.wm.flicker.FlickerTestBase
-import com.android.server.wm.flicker.LayersTraceSubject
import com.android.server.wm.flicker.StandardAppHelper
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WindowUtils
-import com.android.server.wm.flicker.WmTraceSubject
-import com.android.server.wm.flicker.helpers.AutomationUtils
-import org.junit.AfterClass
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.exitSplitScreen
+import com.android.server.wm.flicker.helpers.isInSplitScreen
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -43,68 +46,63 @@
@RunWith(AndroidJUnit4::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class SplitScreenToLauncherTest : FlickerTestBase() {
- init {
- testApp = StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+ private val rotation: Int = Surface.ROTATION_0
+ @Test
+ fun test() {
+ val testApp = StandardAppHelper(instrumentation,
"com.android.server.wm.flicker.testapp", "SimpleApp")
- }
- override val transitionToRun: TransitionRunner
- get() = CommonTransitions.splitScreenToLauncher(testApp, instrumentation, uiDevice,
- Surface.ROTATION_0).includeJankyRuns().build()
+ flicker(instrumentation) {
+ withTag { buildTestTag("splitScreenToLauncher", testApp, rotation) }
+ repeat { 1 }
+ setup {
+ eachRun {
+ device.wakeUpAndGoToHomeScreen()
+ testApp.open()
+ this.setRotation(rotation)
+ device.launchSplitScreen()
+ device.waitForIdle()
+ }
+ }
+ teardown {
+ eachRun {
+ testApp.exit()
+ }
+ test {
+ if (device.isInSplitScreen()) {
+ device.exitSplitScreen()
+ }
+ }
+ }
+ transitions {
+ device.exitSplitScreen()
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ }
- @Test
- fun checkCoveredRegion_noUncoveredRegions() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .coversRegion(WindowUtils.getDisplayBounds()).forAllEntries()
- }
- }
+ layersTrace {
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ noUncoveredRegions(rotation)
+ navBarLayerRotatesAndScales(rotation)
+ statusBarLayerRotatesScales(rotation)
- @Test
- fun checkVisibility_dividerLayerBecomesInVisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer(DOCKED_STACK_DIVIDER)
- .then()
- .hidesLayer(DOCKED_STACK_DIVIDER)
- .forAllEntries()
- }
- }
+ // b/161435597 causes the test not to work on 90 degrees
+ all("dividerLayerBecomesInvisible") {
+ this.showsLayer(DOCKED_STACK_DIVIDER)
+ .then()
+ .hidesLayer(DOCKED_STACK_DIVIDER)
+ }
- @Test
- fun checkVisibility_appLayerBecomesInVisible() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer(testApp.getPackage())
- .then()
- .hidesLayer(testApp.getPackage())
- .forAllEntries()
- }
- }
-
- @Test
- fun checkVisibility_navBarWindowIsAlwaysVisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
- }
- }
-
- @Test
- fun checkVisibility_statusBarWindowIsAlwaysVisible() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries()
- }
- }
-
- companion object {
- @AfterClass
- @JvmStatic
- fun teardown() {
- val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- if (AutomationUtils.isInSplitScreen(device)) {
- AutomationUtils.exitSplitScreen(device)
+ all("appLayerBecomesInvisible") {
+ this.showsLayer(testApp.getPackage())
+ .then()
+ .hidesLayer(testApp.getPackage())
+ }
+ }
}
}
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 1e7fecf..0f24b0c 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -4226,7 +4226,7 @@
callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS);
}
- // Sanity check before testing started keepalive.
+ // Basic check before testing started keepalive.
try (SocketKeepalive ka = mCm.createSocketKeepalive(
myNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
ka.start(validKaInterval);