summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp1
-rw-r--r--core/api/current.txt10
-rw-r--r--core/api/system-current.txt1
-rw-r--r--core/api/test-current.txt2
-rw-r--r--core/java/android/content/pm/PackageManager.java13
-rw-r--r--core/java/android/content/res/CompatibilityInfo.java31
-rw-r--r--core/java/android/net/http/SslCertificate.java2
-rw-r--r--core/java/android/os/strictmode/IncorrectContextUseViolation.java13
-rw-r--r--core/java/android/view/View.java9
-rw-r--r--core/java/android/view/WindowManager.java41
-rw-r--r--core/java/android/widget/AnalogClock.java114
-rw-r--r--core/res/res/values/attrs.xml1
-rw-r--r--core/res/res/values/public.xml1
-rw-r--r--graphics/java/android/graphics/RenderNode.java33
-rw-r--r--keystore/java/android/security/Credentials.java6
-rw-r--r--keystore/java/android/security/KeyStore.java4
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java36
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt11
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt8
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterLegacySplitScreenTest.kt208
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt98
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenLaunchToSide.kt102
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenNonResizableNotDock.kt101
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottom.kt91
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottomTest.kt95
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenTest.kt153
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitPrimarySplitScreenShowSecondaryFullscreen.kt93
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncher.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncherTest.kt)96
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenTransition.kt99
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableDismissInLegacySplitScreen.kt100
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableDismissInLegacySplitScreenTest.kt92
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableLaunchInLegacySplitScreen.kt100
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableLaunchInLegacySplitScreenTest.kt92
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OpenAppToLegacySplitScreen.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OpenAppToLegacySplitScreenTest.kt)106
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreenTest.kt)4
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppAndEnterSplitScreen.kt95
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppInSplitScreenMode.kt95
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppTest.kt150
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppAndEnterSplitScreen.kt100
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppInSplitScreenMode.kt105
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppTest.kt163
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/SplitScreenTestBase.kt74
-rw-r--r--libs/hwui/Android.bp1
-rw-r--r--libs/hwui/RecordingCanvas.cpp2
-rw-r--r--libs/hwui/RenderProperties.h6
-rw-r--r--libs/hwui/effects/StretchEffect.cpp27
-rw-r--r--libs/hwui/effects/StretchEffect.h66
-rw-r--r--libs/hwui/jni/android_graphics_RenderNode.cpp27
-rw-r--r--libs/hwui/pipeline/skia/GLFunctorDrawable.cpp2
-rw-r--r--libs/hwui/pipeline/skia/RenderNodeDrawable.cpp20
-rw-r--r--native/graphics/jni/Android.bp3
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkCapabilities.java13
-rw-r--r--packages/SystemUI/res/drawable/privacy_item_circle_camera.xml8
-rw-r--r--packages/SystemUI/res/drawable/privacy_item_circle_location.xml8
-rw-r--r--packages/SystemUI/res/drawable/privacy_item_circle_microphone.xml8
-rw-r--r--packages/SystemUI/res/layout/privacy_dialog.xml10
-rw-r--r--packages/SystemUI/res/layout/privacy_dialog_item.xml41
-rw-r--r--packages/SystemUI/res/values/dimens.xml6
-rw-r--r--packages/SystemUI/res/values/styles.xml5
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java528
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenIconControllerTest.java46
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java2
-rw-r--r--services/core/java/com/android/server/wm/CompatModePackages.java86
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java23
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt49
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerExtensions.kt3
-rw-r--r--tests/net/Android.bp1
-rw-r--r--tests/net/java/android/net/Ikev2VpnProfileTest.java2
81 files changed, 2223 insertions, 1607 deletions
diff --git a/Android.bp b/Android.bp
index d170913150c5..dc92586a8d14 100644
--- a/Android.bp
+++ b/Android.bp
@@ -632,6 +632,7 @@ java_defaults {
],
sdk_version: "core_platform",
static_libs: [
+ "bouncycastle-repackaged-unbundled",
"framework-internal-utils",
// If MimeMap ever becomes its own APEX, then this dependency would need to be removed
// in favor of an API stubs dependency in java_library "framework" below.
diff --git a/core/api/current.txt b/core/api/current.txt
index d1b9716b4cd3..3efb78943bd7 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -722,6 +722,7 @@ package android {
field public static final int gwpAsanMode = 16844310; // 0x1010616
field public static final int hand_hour = 16843011; // 0x1010103
field public static final int hand_minute = 16843012; // 0x1010104
+ field public static final int hand_second = 16844323; // 0x1010623
field public static final int handle = 16843354; // 0x101025a
field public static final int handleProfiling = 16842786; // 0x1010022
field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e
@@ -12471,6 +12472,7 @@ package android.content.pm {
field public static final long MAXIMUM_VERIFICATION_TIMEOUT = 3600000L; // 0x36ee80L
field public static final int PERMISSION_DENIED = -1; // 0xffffffff
field public static final int PERMISSION_GRANTED = 0; // 0x0
+ field public static final String PROPERTY_MEDIA_CAPABILITIES = "android.media.PROPERTY_MEDIA_CAPABILITIES";
field public static final int SIGNATURE_FIRST_NOT_SIGNED = -1; // 0xffffffff
field public static final int SIGNATURE_MATCH = 0; // 0x0
field public static final int SIGNATURE_NEITHER_SIGNED = 1; // 0x1
@@ -31862,6 +31864,10 @@ package android.os.strictmode {
public final class ImplicitDirectBootViolation extends android.os.strictmode.Violation {
}
+ public final class IncorrectContextUseViolation extends android.os.strictmode.Violation {
+ ctor public IncorrectContextUseViolation(@NonNull String, @NonNull Throwable);
+ }
+
public class InstanceCountViolation extends android.os.strictmode.Violation {
method public long getNumberOfInstances();
}
@@ -53072,6 +53078,10 @@ package android.widget {
ctor @Deprecated public AnalogClock(android.content.Context, android.util.AttributeSet);
ctor @Deprecated public AnalogClock(android.content.Context, android.util.AttributeSet, int);
ctor @Deprecated public AnalogClock(android.content.Context, android.util.AttributeSet, int, int);
+ method @Deprecated public void setDial(@NonNull android.graphics.drawable.Icon);
+ method @Deprecated public void setHourHand(@NonNull android.graphics.drawable.Icon);
+ method @Deprecated public void setMinuteHand(@NonNull android.graphics.drawable.Icon);
+ method @Deprecated public void setSecondHand(@Nullable android.graphics.drawable.Icon);
}
public class ArrayAdapter<T> extends android.widget.BaseAdapter implements android.widget.Filterable android.widget.ThemedSpinnerAdapter {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 1d13b73b7020..b748b918d1c6 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -7281,6 +7281,7 @@ package android.net {
method @Nullable public String getSsid();
method @NonNull public int[] getTransportTypes();
method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
+ field public static final int NET_CAPABILITY_NOT_VCN_MANAGED = 28; // 0x1c
field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16
field public static final int NET_CAPABILITY_OEM_PRIVATE = 26; // 0x1a
field public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24; // 0x18
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index bc1858b63783..b0ee3f01f210 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -2324,6 +2324,8 @@ package android.view {
}
public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
+ method @Nullable public final android.os.IBinder getWindowContextToken();
+ method public final void setWindowContextToken(@NonNull android.os.IBinder);
field public static final int ACCESSIBILITY_TITLE_CHANGED = 33554432; // 0x2000000
field public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 64; // 0x40
field public CharSequence accessibilityTitle;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 9085ed2be8b1..72fb1cae3871 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -125,6 +125,19 @@ public abstract class PackageManager {
}
/**
+ * &lt;application&gt; level {@link android.content.pm.PackageManager.Property} tag specifying
+ * the XML resource ID containing an application's media capabilities XML file
+ *
+ * For example:
+ * &lt;application&gt;
+ * &lt;property android:name="android.media.PROPERTY_MEDIA_CAPABILITIES"
+ * android:resource="@xml/media_capabilities"&gt;
+ * &lt;application&gt;
+ */
+ public static final String PROPERTY_MEDIA_CAPABILITIES =
+ "android.media.PROPERTY_MEDIA_CAPABILITIES";
+
+ /**
* A property value set within the manifest.
* <p>
* The value of a property will only have a single type, as defined by
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index f6edb2edc5ff..abf694f9742e 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -89,6 +89,11 @@ public class CompatibilityInfo implements Parcelable {
private static final int NEEDS_COMPAT_RES = 16;
/**
+ * Set if the application needs to be forcibly downscaled
+ */
+ private static final int HAS_OVERRIDE_SCALING = 32;
+
+ /**
* The effective screen density we have selected for this application.
*/
public final int applicationDensity;
@@ -107,6 +112,11 @@ public class CompatibilityInfo implements Parcelable {
@UnsupportedAppUsage
public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw,
boolean forceCompat) {
+ this(appInfo, screenLayout, sw, forceCompat, 1f);
+ }
+
+ public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw,
+ boolean forceCompat, float overrideScale) {
int compatFlags = 0;
if (appInfo.targetSdkVersion < VERSION_CODES.O) {
@@ -241,7 +251,12 @@ public class CompatibilityInfo implements Parcelable {
compatFlags |= NEVER_NEEDS_COMPAT;
}
- if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
+ if (overrideScale != 1.0f) {
+ applicationDensity = DisplayMetrics.DENSITY_DEFAULT;
+ applicationScale = overrideScale;
+ applicationInvertedScale = 1.0f / overrideScale;
+ compatFlags |= HAS_OVERRIDE_SCALING;
+ } else if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
applicationDensity = DisplayMetrics.DENSITY_DEVICE;
applicationScale = 1.0f;
applicationInvertedScale = 1.0f;
@@ -277,7 +292,7 @@ public class CompatibilityInfo implements Parcelable {
*/
@UnsupportedAppUsage
public boolean isScalingRequired() {
- return (mCompatibilityFlags&SCALING_REQUIRED) != 0;
+ return (mCompatibilityFlags & (SCALING_REQUIRED | HAS_OVERRIDE_SCALING)) != 0;
}
@UnsupportedAppUsage
@@ -303,7 +318,7 @@ public class CompatibilityInfo implements Parcelable {
*/
@UnsupportedAppUsage
public Translator getTranslator() {
- return isScalingRequired() ? new Translator() : null;
+ return (mCompatibilityFlags & SCALING_REQUIRED) != 0 ? new Translator() : null;
}
/**
@@ -504,6 +519,16 @@ public class CompatibilityInfo implements Parcelable {
if (isScalingRequired()) {
float invertedRatio = applicationInvertedScale;
inoutConfig.densityDpi = (int)((inoutConfig.densityDpi * invertedRatio) + .5f);
+ inoutConfig.screenWidthDp = (int) ((inoutConfig.screenWidthDp * invertedRatio) + .5f);
+ inoutConfig.screenHeightDp = (int) ((inoutConfig.screenHeightDp * invertedRatio) + .5f);
+ inoutConfig.smallestScreenWidthDp =
+ (int) ((inoutConfig.smallestScreenWidthDp * invertedRatio) + .5f);
+ inoutConfig.windowConfiguration.getMaxBounds().scale(invertedRatio);
+ inoutConfig.windowConfiguration.getBounds().scale(invertedRatio);
+ final Rect appBounds = inoutConfig.windowConfiguration.getAppBounds();
+ if (appBounds != null) {
+ appBounds.scale(invertedRatio);
+ }
}
}
diff --git a/core/java/android/net/http/SslCertificate.java b/core/java/android/net/http/SslCertificate.java
index 250cff29944a..a22d41a5ef86 100644
--- a/core/java/android/net/http/SslCertificate.java
+++ b/core/java/android/net/http/SslCertificate.java
@@ -26,7 +26,7 @@ import android.view.View;
import android.widget.TextView;
import com.android.internal.util.HexDump;
-import com.android.org.bouncycastle.asn1.x509.X509Name;
+import com.android.internal.org.bouncycastle.asn1.x509.X509Name;
import java.io.ByteArrayInputStream;
import java.math.BigInteger;
diff --git a/core/java/android/os/strictmode/IncorrectContextUseViolation.java b/core/java/android/os/strictmode/IncorrectContextUseViolation.java
index 647db171e080..11d26cab14b3 100644
--- a/core/java/android/os/strictmode/IncorrectContextUseViolation.java
+++ b/core/java/android/os/strictmode/IncorrectContextUseViolation.java
@@ -16,19 +16,20 @@
package android.os.strictmode;
+import android.annotation.NonNull;
import android.content.Context;
/**
- * Incorrect usage of {@link Context}, such as obtaining a visual service from non-visual
- * {@link Context} instance.
+ * Incorrect usage of {@link Context}, such as obtaining a UI service from non-UI {@link Context}
+ * instance.
+ *
* @see Context#getSystemService(String)
- * @see Context#getDisplayNoVerify()
- * @hide
+ * @see Context#isUiContext(Context)
+ * @see android.os.StrictMode.VmPolicy.Builder#detectIncorrectContextUse()
*/
public final class IncorrectContextUseViolation extends Violation {
- /** @hide */
- public IncorrectContextUseViolation(String message, Throwable originStack) {
+ public IncorrectContextUseViolation(@NonNull String message, @NonNull Throwable originStack) {
super(message);
initCause(originStack);
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 11be792ece42..9a412fcd436a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -21370,6 +21370,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
int height = mBottom - mTop;
int layerType = getLayerType();
+ // Hacky hack: Reset any stretch effects as those are applied during the draw pass
+ // instead of being "stateful" like other RenderNode properties
+ renderNode.clearStretch();
+
final RecordingCanvas canvas = renderNode.beginRecording(width, height);
try {
@@ -22796,6 +22800,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final Rect bounds = drawable.getBounds();
final int width = bounds.width();
final int height = bounds.height();
+
+ // Hacky hack: Reset any stretch effects as those are applied during the draw pass
+ // instead of being "stateful" like other RenderNode properties
+ renderNode.clearStretch();
+
final RecordingCanvas canvas = renderNode.beginRecording(width, height);
// Reverse left/top translation done by drawable canvas, which will
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index fa471fa28c7f..8319b74d9cdf 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -83,6 +83,7 @@ import static android.view.WindowLayoutParamsProto.Y;
import android.Manifest.permission;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
@@ -99,6 +100,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Build;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -2855,12 +2857,14 @@ public interface WindowManager extends ViewManager {
/**
* The token of {@link android.app.WindowContext}. It is usually a
- * {@link android.app.WindowTokenClient} and is used for updating
- * {@link android.content.res.Resources} from {@link Configuration} propagated from the
- * server side.
+ * {@link android.app.WindowTokenClient} and is used for associating the params with an
+ * existing node in the WindowManager hierarchy and getting the corresponding
+ * {@link Configuration} and {@link android.content.res.Resources} values with updates
+ * propagated from the server side.
*
* @hide
*/
+ @Nullable
public IBinder mWindowContextToken = null;
/**
@@ -3547,6 +3551,37 @@ public interface WindowManager extends ViewManager {
return userActivityTimeout;
}
+ /**
+ * Sets the {@link android.app.WindowContext} token.
+ *
+ * @see #getWindowContextToken()
+ *
+ * @hide
+ */
+ @TestApi
+ public final void setWindowContextToken(@NonNull IBinder token) {
+ mWindowContextToken = token;
+ }
+
+ /**
+ * Gets the {@link android.app.WindowContext} token.
+ *
+ * The token is usually a {@link android.app.WindowTokenClient} and is used for associating
+ * the params with an existing node in the WindowManager hierarchy and getting the
+ * corresponding {@link Configuration} and {@link android.content.res.Resources} values with
+ * updates propagated from the server side.
+ *
+ * @see android.app.WindowTokenClient
+ * @see Context#createWindowContext(Display, int, Bundle)
+ *
+ * @hide
+ */
+ @TestApi
+ @Nullable
+ public final IBinder getWindowContextToken() {
+ return mWindowContextToken;
+ }
+
public int describeContents() {
return 0;
}
diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java
index ffdb89de5f59..98738eff83c3 100644
--- a/core/java/android/widget/AnalogClock.java
+++ b/core/java/android/widget/AnalogClock.java
@@ -16,6 +16,8 @@
package android.widget;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -25,8 +27,10 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.text.format.DateUtils;
import android.util.AttributeSet;
+import android.view.RemotableViewMethod;
import android.view.View;
import android.widget.RemoteViews.RemoteView;
@@ -42,25 +46,32 @@ import java.time.ZoneId;
* @attr ref android.R.styleable#AnalogClock_dial
* @attr ref android.R.styleable#AnalogClock_hand_hour
* @attr ref android.R.styleable#AnalogClock_hand_minute
+ * @attr ref android.R.styleable#AnalogClock_hand_second
* @deprecated This widget is no longer supported.
*/
@RemoteView
@Deprecated
public class AnalogClock extends View {
+ /** How often the clock should refresh to make the seconds hand advance at ~15 FPS. */
+ private static final long SECONDS_TICK_FREQUENCY_MS = 1000 / 15;
+
private Clock mClock;
@UnsupportedAppUsage
private Drawable mHourHand;
@UnsupportedAppUsage
private Drawable mMinuteHand;
+ @Nullable
+ private Drawable mSecondHand;
@UnsupportedAppUsage
private Drawable mDial;
private int mDialWidth;
private int mDialHeight;
- private boolean mAttached;
+ private boolean mVisible;
+ private float mSeconds;
private float mMinutes;
private float mHour;
private boolean mChanged;
@@ -101,18 +112,70 @@ public class AnalogClock extends View {
mMinuteHand = context.getDrawable(com.android.internal.R.drawable.clock_hand_minute);
}
+ mSecondHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_second);
+
mClock = Clock.systemDefaultZone();
mDialWidth = mDial.getIntrinsicWidth();
mDialHeight = mDial.getIntrinsicHeight();
}
+ /** Sets the dial of the clock to the specified Icon. */
+ @RemotableViewMethod
+ public void setDial(@NonNull Icon icon) {
+ mDial = icon.loadDrawable(getContext());
+ mDialWidth = mDial.getIntrinsicWidth();
+ mDialHeight = mDial.getIntrinsicHeight();
+
+ mChanged = true;
+ invalidate();
+ }
+
+ /** Sets the hour hand of the clock to the specified Icon. */
+ @RemotableViewMethod
+ public void setHourHand(@NonNull Icon icon) {
+ mHourHand = icon.loadDrawable(getContext());
+
+ mChanged = true;
+ invalidate();
+ }
+
+ /** Sets the minute hand of the clock to the specified Icon. */
+ @RemotableViewMethod
+ public void setMinuteHand(@NonNull Icon icon) {
+ mMinuteHand = icon.loadDrawable(getContext());
+
+ mChanged = true;
+ invalidate();
+ }
+
+ /**
+ * Sets the second hand of the clock to the specified Icon, or hides the second hand if it is
+ * null.
+ */
+ @RemotableViewMethod
+ public void setSecondHand(@Nullable Icon icon) {
+ mSecondHand = icon == null ? null : icon.loadDrawable(getContext());
+ mSecondsTick.run();
+
+ mChanged = true;
+ invalidate();
+ }
+
@Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
+ public void onVisibilityAggregated(boolean isVisible) {
+ super.onVisibilityAggregated(isVisible);
- if (!mAttached) {
- mAttached = true;
+ if (isVisible) {
+ onVisible();
+ } else {
+ onInvisible();
+ }
+ }
+
+ private void onVisible() {
+ if (!mVisible) {
+ mVisible = true;
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
@@ -128,6 +191,8 @@ public class AnalogClock extends View {
// user not the one the context is for.
getContext().registerReceiverAsUser(mIntentReceiver,
android.os.Process.myUserHandle(), filter, null, getHandler());
+
+ mSecondsTick.run();
}
// NOTE: It's safe to do these after registering the receiver since the receiver always runs
@@ -140,12 +205,11 @@ public class AnalogClock extends View {
onTimeChanged();
}
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- if (mAttached) {
+ private void onInvisible() {
+ if (mVisible) {
getContext().unregisterReceiver(mIntentReceiver);
- mAttached = false;
+ removeCallbacks(mSecondsTick);
+ mVisible = false;
}
}
@@ -237,6 +301,20 @@ public class AnalogClock extends View {
minuteHand.draw(canvas);
canvas.restore();
+ final Drawable secondHand = mSecondHand;
+ if (secondHand != null) {
+ canvas.save();
+ canvas.rotate(mSeconds / 60.0f * 360.0f, x, y);
+
+ if (changed) {
+ w = secondHand.getIntrinsicWidth();
+ h = secondHand.getIntrinsicHeight();
+ secondHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2));
+ }
+ secondHand.draw(canvas);
+ canvas.restore();
+ }
+
if (scaled) {
canvas.restore();
}
@@ -250,6 +328,7 @@ public class AnalogClock extends View {
int minute = localDateTime.getMinute();
int second = localDateTime.getSecond();
+ mSeconds = second + localDateTime.getNano() / 1_000_000_000f;
mMinutes = minute + second / 60.0f;
mHour = hour + mMinutes / 60.0f;
mChanged = true;
@@ -271,6 +350,21 @@ public class AnalogClock extends View {
}
};
+ private final Runnable mSecondsTick = new Runnable() {
+ @Override
+ public void run() {
+ if (!mVisible || mSecondHand == null) {
+ return;
+ }
+
+ onTimeChanged();
+
+ invalidate();
+
+ postDelayed(this, SECONDS_TICK_FREQUENCY_MS);
+ }
+ };
+
private void updateContentDescription(long timeMillis) {
final int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_24HOUR;
String contentDescription = DateUtils.formatDateTime(mContext, timeMillis, flags);
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 14f1e0e20ef6..07c3adfb4c69 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4069,6 +4069,7 @@
<attr name="dial" format="reference"/>
<attr name="hand_hour" format="reference"/>
<attr name="hand_minute" format="reference"/>
+ <attr name="hand_second" format="reference"/>
</declare-styleable>
<declare-styleable name="Button">
</declare-styleable>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 9c1c51cdd48e..b76ab3a22a20 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3059,6 +3059,7 @@
<public name="pathAdvancedPattern" />
<public name="sspAdvancedPattern" />
<public name="fontProviderSystemFontFamily" />
+ <public name="hand_second" />
</public-group>
<public-group type="drawable" first-id="0x010800b5">
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index c1310a9214e0..4a92cf11fa5c 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -693,6 +693,32 @@ public final class RenderNode {
throw new IllegalArgumentException("Unrecognized outline?");
}
+ /** @hide */
+ public boolean clearStretch() {
+ return nClearStretch(mNativeRenderNode);
+ }
+
+ /** @hide */
+ public boolean stretch(float left, float top, float right, float bottom,
+ float vecX, float vecY, float maxStretchAmount) {
+ if (1.0 < vecX || vecX < -1.0) {
+ throw new IllegalArgumentException("vecX must be in the range [-1, 1], was " + vecX);
+ }
+ if (1.0 < vecY || vecY < -1.0) {
+ throw new IllegalArgumentException("vecY must be in the range [-1, 1], was " + vecY);
+ }
+ if (top <= bottom || right <= left) {
+ throw new IllegalArgumentException(
+ "Stretch region must not be empty, got "
+ + new RectF(left, top, right, bottom).toString());
+ }
+ if (maxStretchAmount <= 0.0f) {
+ throw new IllegalArgumentException(
+ "The max stretch amount must be >0, got " + maxStretchAmount);
+ }
+ return nStretch(mNativeRenderNode, left, top, right, bottom, vecX, vecY, maxStretchAmount);
+ }
+
/**
* Checks if the RenderNode has a shadow. That is, if the combination of {@link #getElevation()}
* and {@link #getTranslationZ()} is greater than zero, there is an {@link Outline} set with
@@ -1638,6 +1664,13 @@ public final class RenderNode {
private static native boolean nSetOutlineNone(long renderNode);
@CriticalNative
+ private static native boolean nClearStretch(long renderNode);
+
+ @CriticalNative
+ private static native boolean nStretch(long renderNode, float left, float top, float right,
+ float bottom, float vecX, float vecY, float maxStretch);
+
+ @CriticalNative
private static native boolean nHasShadow(long renderNode);
@CriticalNative
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index f41b6081e38c..ae9f866459d6 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -19,9 +19,9 @@ package android.security;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
-import com.android.org.bouncycastle.util.io.pem.PemObject;
-import com.android.org.bouncycastle.util.io.pem.PemReader;
-import com.android.org.bouncycastle.util.io.pem.PemWriter;
+import com.android.internal.org.bouncycastle.util.io.pem.PemObject;
+import com.android.internal.org.bouncycastle.util.io.pem.PemReader;
+import com.android.internal.org.bouncycastle.util.io.pem.PemWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 4a67135227dd..e19d88c182ff 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -45,8 +45,8 @@ import android.security.keystore.KeystoreResponse;
import android.security.keystore.UserNotAuthenticatedException;
import android.util.Log;
-import com.android.org.bouncycastle.asn1.ASN1InputStream;
-import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import java.io.ByteArrayInputStream;
import java.io.IOException;
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index 6ad8d2c0aca3..334b1110d651 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -26,24 +26,24 @@ import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterCertificateChain;
import android.security.keymaster.KeymasterDefs;
-import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
-import com.android.org.bouncycastle.asn1.ASN1InputStream;
-import com.android.org.bouncycastle.asn1.ASN1Integer;
-import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import com.android.org.bouncycastle.asn1.DERBitString;
-import com.android.org.bouncycastle.asn1.DERNull;
-import com.android.org.bouncycastle.asn1.DERSequence;
-import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
-import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import com.android.org.bouncycastle.asn1.x509.Certificate;
-import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import com.android.org.bouncycastle.asn1.x509.TBSCertificate;
-import com.android.org.bouncycastle.asn1.x509.Time;
-import com.android.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
-import com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
-import com.android.org.bouncycastle.jce.X509Principal;
-import com.android.org.bouncycastle.jce.provider.X509CertificateObject;
-import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.Certificate;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.TBSCertificate;
+import com.android.internal.org.bouncycastle.asn1.x509.Time;
+import com.android.internal.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.jce.X509Principal;
+import com.android.internal.org.bouncycastle.jce.provider.X509CertificateObject;
+import com.android.internal.org.bouncycastle.x509.X509V3CertificateGenerator;
import libcore.util.EmptyArray;
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
index ccfdce65f7b2..24b0f3043319 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
@@ -18,10 +18,11 @@ package com.android.wm.shell.flicker
import android.graphics.Region
import android.view.Surface
+import com.android.server.wm.flicker.APP_PAIR_SPLIT_DIVIDER
+import com.android.server.wm.flicker.DOCKED_STACK_DIVIDER
import com.android.server.wm.flicker.dsl.LayersAssertionBuilder
import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.traces.layers.getVisibleBounds
-import com.android.wm.shell.flicker.FlickerTestBase.Companion.DOCKED_STACK_DIVIDER
@JvmOverloads
fun LayersAssertionBuilder.appPairsDividerIsVisible(
@@ -29,7 +30,7 @@ fun LayersAssertionBuilder.appPairsDividerIsVisible(
enabled: Boolean = bugId == 0
) {
end("appPairsDividerIsVisible", bugId, enabled) {
- this.isVisible(FlickerTestBase.APP_PAIR_SPLIT_DIVIDER)
+ this.isVisible(APP_PAIR_SPLIT_DIVIDER)
}
}
@@ -39,7 +40,7 @@ fun LayersAssertionBuilder.appPairsDividerIsInvisible(
enabled: Boolean = bugId == 0
) {
end("appPairsDividerIsInVisible", bugId, enabled) {
- this.notExists(FlickerTestBase.APP_PAIR_SPLIT_DIVIDER)
+ this.notExists(APP_PAIR_SPLIT_DIVIDER)
}
}
@@ -107,7 +108,7 @@ fun LayersAssertionBuilder.appPairsPrimaryBoundsIsVisible(
enabled: Boolean = bugId == 0
) {
end("PrimaryAppBounds", bugId, enabled) {
- val dividerRegion = entry.getVisibleBounds(FlickerTestBase.APP_PAIR_SPLIT_DIVIDER)
+ val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER)
this.hasVisibleRegion(primaryLayerName, getPrimaryRegion(dividerRegion, rotation))
}
}
@@ -120,7 +121,7 @@ fun LayersAssertionBuilder.appPairsSecondaryBoundsIsVisible(
enabled: Boolean = bugId == 0
) {
end("SecondaryAppBounds", bugId, enabled) {
- val dividerRegion = entry.getVisibleBounds(FlickerTestBase.APP_PAIR_SPLIT_DIVIDER)
+ val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER)
this.hasVisibleRegion(secondaryLayerName, getSecondaryRegion(dividerRegion, rotation))
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt
index 3953c1c5a0f4..89bbdb0a2f99 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt
@@ -135,12 +135,4 @@ abstract class FlickerTestBase {
throw RuntimeException(e)
}
}
-
- companion object {
- const val NAVIGATION_BAR_WINDOW_TITLE = "NavigationBar"
- const val STATUS_BAR_WINDOW_TITLE = "StatusBar"
- const val DOCKED_STACK_DIVIDER = "DockedStackDivider"
- const val APP_PAIR_SPLIT_DIVIDER = "AppPairSplitDivider"
- const val IMAGE_WALLPAPER = "ImageWallpaper"
- }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt
index 5cbfec638da5..257350b6950b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt
@@ -21,12 +21,12 @@ import android.os.SystemClock
import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.APP_PAIR_SPLIT_DIVIDER
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.buildTestTag
import com.android.server.wm.flicker.traces.layers.getVisibleBounds
-import com.android.wm.shell.flicker.FlickerTestBase.Companion.APP_PAIR_SPLIT_DIVIDER
import com.android.wm.shell.flicker.appPairsDividerIsVisible
import com.android.wm.shell.flicker.helpers.AppPairsHelper
import org.junit.FixMethodOrder
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt
index f57a000a0ccb..0b001f5ac1b6 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt
@@ -21,12 +21,12 @@ import android.os.SystemClock
import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.APP_PAIR_SPLIT_DIVIDER
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.buildTestTag
import com.android.server.wm.flicker.traces.layers.getVisibleBounds
-import com.android.wm.shell.flicker.FlickerTestBase.Companion.APP_PAIR_SPLIT_DIVIDER
import com.android.wm.shell.flicker.appPairsDividerIsInvisible
import com.android.wm.shell.flicker.helpers.AppPairsHelper
import org.junit.FixMethodOrder
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterLegacySplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterLegacySplitScreenTest.kt
deleted file mode 100644
index dea5c300f590..000000000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterLegacySplitScreenTest.kt
+++ /dev/null
@@ -1,208 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.dsl.runWithFlicker
-import com.android.server.wm.flicker.helpers.canSplitScreen
-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.openQuickstep
-import com.android.server.wm.flicker.helpers.openQuickStepAndClearRecentAppsFromOverview
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.wm.shell.flicker.dockedStackDividerIsInvisible
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper.Companion.TEST_REPETITIONS
-import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
-import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
-import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
-import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
-import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisible
-import com.android.wm.shell.flicker.dockedStackSecondaryBoundsIsVisible
-import org.junit.Assert
-import com.android.wm.shell.flicker.dockedStackDividerBecomesVisible
-import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
-import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test SplitScreen launch.
- * To run this test: `atest WMShellFlickerTests:EnterLegacySplitScreenTest`
- */
-@Presubmit
-@RequiresDevice
-@RunWith(Parameterized::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterLegacySplitScreenTest(
- rotationName: String,
- rotation: Int
-) : SplitScreenTestBase(rotationName, rotation) {
- private val splitScreenSetup: FlickerBuilder
- get() = FlickerBuilder(instrumentation).apply {
- val testLaunchActivity = "launch_splitScreen_test_activity"
- withTestName {
- testLaunchActivity
- }
- setup {
- eachRun {
- uiDevice.wakeUpAndGoToHomeScreen()
- uiDevice.openQuickStepAndClearRecentAppsFromOverview()
- }
- }
- teardown {
- eachRun {
- if (uiDevice.isInSplitScreen()) {
- uiDevice.exitSplitScreen()
- }
- splitScreenApp.exit()
- secondaryApp.exit()
- nonResizeableApp.exit()
- }
- }
- assertions {
- layersTrace {
- navBarLayerIsAlwaysVisible()
- statusBarLayerIsAlwaysVisible()
- }
- windowManagerTrace {
- navBarWindowIsAlwaysVisible()
- statusBarWindowIsAlwaysVisible()
- }
- }
- }
-
- @Test
- fun testEnterSplitScreen_dockActivity() {
- val testTag = "testEnterSplitScreen_dockActivity"
- runWithFlicker(splitScreenSetup) {
- withTestName { testTag }
- repeat {
- TEST_REPETITIONS
- }
- transitions {
- splitScreenApp.launchViaIntent()
- uiDevice.launchSplitScreen()
- }
- assertions {
- layersTrace {
- dockedStackPrimaryBoundsIsVisible(
- rotation, splitScreenApp.defaultWindowName, 169271943)
- dockedStackDividerBecomesVisible()
- visibleLayersShownMoreThanOneConsecutiveEntry(
- listOf(LAUNCHER_PACKAGE_NAME, splitScreenApp.defaultWindowName,
- LIVE_WALLPAPER_PACKAGE_NAME)
- )
- }
- windowManagerTrace {
- end("appWindowIsVisible") {
- isVisible(splitScreenApp.defaultWindowName)
- }
- }
- }
- }
- }
-
- @Test
- fun testEnterSplitScreen_launchToSide() {
- val testTag = "testEnterSplitScreen_launchToSide"
- runWithFlicker(splitScreenSetup) {
- withTestName { testTag }
- repeat {
- TEST_REPETITIONS
- }
- transitions {
- secondaryApp.launchViaIntent()
- splitScreenApp.launchViaIntent()
- uiDevice.launchSplitScreen()
- splitScreenApp.reopenAppFromOverview()
- }
- assertions {
- layersTrace {
- dockedStackPrimaryBoundsIsVisible(
- rotation, splitScreenApp.defaultWindowName, 169271943)
- dockedStackSecondaryBoundsIsVisible(
- rotation, secondaryApp.defaultWindowName, 169271943)
- dockedStackDividerBecomesVisible()
- visibleLayersShownMoreThanOneConsecutiveEntry(
- listOf(LAUNCHER_PACKAGE_NAME, splitScreenApp.defaultWindowName,
- secondaryApp.defaultWindowName)
- )
- }
- windowManagerTrace {
- end("appWindowIsVisible") {
- isVisible(splitScreenApp.defaultWindowName)
- .isVisible(secondaryApp.defaultWindowName)
- }
- visibleWindowsShownMoreThanOneConsecutiveEntry(
- listOf(LAUNCHER_PACKAGE_NAME, splitScreenApp.defaultWindowName,
- secondaryApp.defaultWindowName))
- }
- }
- }
- }
-
- @FlakyTest(bugId = 173875043)
- @Test
- fun testNonResizeableNotDocked() {
- val testTag = "testNonResizeableNotDocked"
- runWithFlicker(splitScreenSetup) {
- withTestName { testTag }
- repeat {
- TEST_REPETITIONS
- }
- transitions {
- nonResizeableApp.launchViaIntent()
- uiDevice.openQuickstep()
- if (uiDevice.canSplitScreen()) {
- Assert.fail("Non-resizeable app should not enter split screen")
- }
- }
- assertions {
- layersTrace {
- dockedStackDividerIsInvisible()
- visibleLayersShownMoreThanOneConsecutiveEntry(
- listOf(LAUNCHER_PACKAGE_NAME, nonResizeableApp.defaultWindowName)
- )
- }
- windowManagerTrace {
- end("appWindowIsVisible") {
- isInvisible(nonResizeableApp.defaultWindowName)
- }
- visibleWindowsShownMoreThanOneConsecutiveEntry(
- listOf(LAUNCHER_PACKAGE_NAME, nonResizeableApp.defaultWindowName))
- }
- }
- }
- }
-
- 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) }
- }
- }
-} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt
new file mode 100644
index 000000000000..5374bd9f40de
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2021 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.wm.shell.flicker.legacysplitscreen
+
+import android.os.Bundle
+import android.platform.test.annotations.Presubmit
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.WALLPAPER_TITLE
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.startRotation
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
+import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
+import com.android.wm.shell.flicker.dockedStackDividerBecomesVisible
+import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisible
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test open activity and dock to primary split screen
+ * To run this test: `atest WMShellFlickerTests:EnterSplitScreenDockActivity`
+ */
+@Presubmit
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class EnterSplitScreenDockActivity(
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
+ companion object : LegacySplitScreenTransition(InstrumentationRegistry.getInstrumentation()) {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
+ withTestName {
+ buildTestTag("testLegacySplitScreenDockActivity", configuration)
+ }
+ repeat { SplitScreenHelper.TEST_REPETITIONS }
+ transitions {
+ device.launchSplitScreen()
+ }
+ assertions {
+ layersTrace {
+ dockedStackPrimaryBoundsIsVisible(
+ configuration.startRotation,
+ splitScreenApp.defaultWindowName, bugId = 169271943)
+ dockedStackDividerBecomesVisible()
+ visibleLayersShownMoreThanOneConsecutiveEntry(
+ listOf(LAUNCHER_PACKAGE_NAME,
+ WALLPAPER_TITLE, LIVE_WALLPAPER_PACKAGE_NAME,
+ splitScreenApp.defaultWindowName),
+ bugId = 178531736
+ )
+ }
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ visibleWindowsShownMoreThanOneConsecutiveEntry(
+ listOf(LAUNCHER_PACKAGE_NAME,
+ WALLPAPER_TITLE, LIVE_WALLPAPER_PACKAGE_NAME,
+ splitScreenApp.defaultWindowName),
+ bugId = 178531736
+ )
+ end("appWindowIsVisible") {
+ isVisible(splitScreenApp.defaultWindowName)
+ }
+ }
+ }
+ }
+ return FlickerTestRunnerFactory.getInstance().buildTest(
+ instrumentation, defaultTransitionSetup, testSpec,
+ repetitions = SplitScreenHelper.TEST_REPETITIONS)
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenLaunchToSide.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenLaunchToSide.kt
new file mode 100644
index 000000000000..d750403d66c6
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenLaunchToSide.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2021 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.wm.shell.flicker.legacysplitscreen
+
+import android.os.Bundle
+import android.platform.test.annotations.Presubmit
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.appWindowBecomesVisible
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.startRotation
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
+import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
+import com.android.wm.shell.flicker.dockedStackDividerBecomesVisible
+import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisible
+import com.android.wm.shell.flicker.dockedStackSecondaryBoundsIsVisible
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test open activity to primary split screen and dock secondary activity to side
+ * To run this test: `atest WMShellFlickerTests:EnterSplitScreenLaunchToSide`
+ */
+@Presubmit
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class EnterSplitScreenLaunchToSide(
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
+ companion object : LegacySplitScreenTransition(InstrumentationRegistry.getInstrumentation()) {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
+ withTestName {
+ buildTestTag("testLegacySplitScreenLaunchToSide", configuration)
+ }
+ repeat { SplitScreenHelper.TEST_REPETITIONS }
+ transitions {
+ device.launchSplitScreen()
+ secondaryApp.reopenAppFromOverview()
+ }
+ assertions {
+ layersTrace {
+ dockedStackPrimaryBoundsIsVisible(
+ configuration.startRotation,
+ splitScreenApp.defaultWindowName, bugId = 169271943)
+ dockedStackSecondaryBoundsIsVisible(
+ configuration.startRotation,
+ secondaryApp.defaultWindowName, bugId = 169271943)
+ dockedStackDividerBecomesVisible()
+ // TODO(b/178447631) Remove Splash Screen from white list when flicker lib
+ // add a wait for splash screen be gone
+ visibleLayersShownMoreThanOneConsecutiveEntry(
+ listOf(LAUNCHER_PACKAGE_NAME, SPLASH_SCREEN_NAME,
+ splitScreenApp.defaultWindowName,
+ secondaryApp.defaultWindowName),
+ bugId = 178447631
+ )
+ }
+ windowManagerTrace {
+ appWindowBecomesVisible(secondaryApp.defaultWindowName)
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ visibleWindowsShownMoreThanOneConsecutiveEntry(
+ listOf(LAUNCHER_PACKAGE_NAME, SPLASH_SCREEN_NAME,
+ splitScreenApp.defaultWindowName,
+ secondaryApp.defaultWindowName)
+ )
+ }
+ }
+ }
+ return FlickerTestRunnerFactory.getInstance().buildTest(
+ instrumentation, defaultTransitionSetup, testSpec,
+ repetitions = SplitScreenHelper.TEST_REPETITIONS)
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenNonResizableNotDock.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenNonResizableNotDock.kt
new file mode 100644
index 000000000000..e3619235ee77
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenNonResizableNotDock.kt
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2021 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.wm.shell.flicker.legacysplitscreen
+
+import android.os.Bundle
+import android.platform.test.annotations.Presubmit
+import android.view.Surface
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.WALLPAPER_TITLE
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.canSplitScreen
+import com.android.server.wm.flicker.helpers.openQuickstep
+import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
+import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
+import com.android.wm.shell.flicker.dockedStackDividerIsInvisible
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import org.junit.Assert
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test open non-resizable activity will auto exit split screen mode
+ * To run this test: `atest WMShellFlickerTests:EnterSplitScreenNonResizableNotDock`
+ */
+@Presubmit
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 173875043)
+class EnterSplitScreenNonResizableNotDock(
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
+ companion object : LegacySplitScreenTransition(InstrumentationRegistry.getInstrumentation()) {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
+ withTestName {
+ buildTestTag("testLegacySplitScreenNonResizeableActivityNotDock", configuration)
+ }
+ repeat { SplitScreenHelper.TEST_REPETITIONS }
+ transitions {
+ nonResizeableApp.launchViaIntent(wmHelper)
+ device.openQuickstep()
+ if (device.canSplitScreen()) {
+ Assert.fail("Non-resizeable app should not enter split screen")
+ }
+ }
+ assertions {
+ layersTrace {
+ dockedStackDividerIsInvisible()
+ visibleLayersShownMoreThanOneConsecutiveEntry(
+ listOf(LAUNCHER_PACKAGE_NAME,
+ SPLASH_SCREEN_NAME,
+ nonResizeableApp.defaultWindowName,
+ splitScreenApp.defaultWindowName),
+ bugId = 178447631
+ )
+ }
+ windowManagerTrace {
+ visibleWindowsShownMoreThanOneConsecutiveEntry(
+ listOf(WALLPAPER_TITLE,
+ LAUNCHER_PACKAGE_NAME,
+ SPLASH_SCREEN_NAME,
+ nonResizeableApp.defaultWindowName,
+ splitScreenApp.defaultWindowName)
+ )
+ end("appWindowIsVisible") {
+ isInvisible(nonResizeableApp.defaultWindowName)
+ }
+ }
+ }
+ }
+ return FlickerTestRunnerFactory.getInstance().buildTest(
+ instrumentation, defaultTransitionSetup, testSpec,
+ repetitions = SplitScreenHelper.TEST_REPETITIONS,
+ supportedRotations = listOf(Surface.ROTATION_0 /* bugId = 178685668 */))
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottom.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottom.kt
new file mode 100644
index 000000000000..6aed83f35327
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottom.kt
@@ -0,0 +1,91 @@
+/*
+ * 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.wm.shell.flicker.legacysplitscreen
+
+import android.os.Bundle
+import android.platform.test.annotations.Presubmit
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.DOCKED_STACK_DIVIDER
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.appWindowBecomesInVisible
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.exitSplitScreenFromBottom
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.layerBecomesInvisible
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
+import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test open resizeable activity split in primary, and drag divider to bottom exit split screen
+ * To run this test: `atest WMShellFlickerTests:ExitLegacySplitScreenFromBottom`
+ */
+@Presubmit
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class ExitLegacySplitScreenFromBottom(
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
+ companion object : LegacySplitScreenTransition(InstrumentationRegistry.getInstrumentation()) {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
+ withTestName {
+ buildTestTag("testExitLegacySplitScreenFromBottom", configuration)
+ }
+ repeat { SplitScreenHelper.TEST_REPETITIONS }
+ transitions {
+ device.launchSplitScreen()
+ device.exitSplitScreenFromBottom()
+ }
+ assertions {
+ layersTrace {
+ layerBecomesInvisible(DOCKED_STACK_DIVIDER)
+ visibleLayersShownMoreThanOneConsecutiveEntry(
+ listOf(LAUNCHER_PACKAGE_NAME, splitScreenApp.defaultWindowName,
+ secondaryApp.defaultWindowName),
+ bugId = 178447631
+ )
+ }
+ windowManagerTrace {
+ appWindowBecomesInVisible(secondaryApp.defaultWindowName)
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ visibleWindowsShownMoreThanOneConsecutiveEntry(
+ listOf(LAUNCHER_PACKAGE_NAME, splitScreenApp.defaultWindowName,
+ secondaryApp.defaultWindowName)
+ )
+ }
+ }
+ }
+ return FlickerTestRunnerFactory.getInstance().buildTest(
+ instrumentation, defaultTransitionSetup, testSpec,
+ repetitions = SplitScreenHelper.TEST_REPETITIONS)
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottomTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottomTest.kt
deleted file mode 100644
index a3b8673d93ed..000000000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottomTest.kt
+++ /dev/null
@@ -1,95 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerTestRunner
-import com.android.server.wm.flicker.FlickerTestRunnerFactory
-import com.android.server.wm.flicker.endRotation
-import com.android.server.wm.flicker.helpers.buildTestTag
-import com.android.server.wm.flicker.helpers.exitSplitScreen
-import com.android.server.wm.flicker.helpers.exitSplitScreenFromBottom
-import com.android.server.wm.flicker.helpers.isInSplitScreen
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.helpers.openQuickStepAndClearRecentAppsFromOverview
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.flicker.repetitions
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test open app to split screen.
- * To run this test: `atest WMShellFlickerTests:ExitLegacySplitScreenFromBottomTest`
- */
-@Presubmit
-@RequiresDevice
-@RunWith(Parameterized::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExitLegacySplitScreenFromBottomTest(
- testSpec: FlickerTestRunnerFactory.TestSpec
-) : FlickerTestRunner(testSpec) {
- companion object {
- @Parameterized.Parameters(name = "{0}")
- @JvmStatic
- fun getParams(): Collection<Array<Any>> {
- val instrumentation = InstrumentationRegistry.getInstrumentation()
- val splitScreenApp = SplitScreenHelper.getPrimary(instrumentation)
- // TODO(b/162923992) Use of multiple segments of flicker spec for testing
- return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation,
- supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90)) {
- configuration ->
- withTestName {
- buildTestTag("exitSplitScreenFromBottom", configuration)
- }
- repeat { configuration.repetitions }
- setup {
- eachRun {
- device.wakeUpAndGoToHomeScreen()
- device.openQuickStepAndClearRecentAppsFromOverview()
- splitScreenApp.launchViaIntent(wmHelper)
- device.launchSplitScreen()
- device.waitForIdle()
- this.setRotation(configuration.endRotation)
- }
- }
- teardown {
- eachRun {
- if (device.isInSplitScreen()) {
- device.exitSplitScreen()
- }
- splitScreenApp.exit()
- }
- }
- transitions {
- device.exitSplitScreenFromBottom()
- }
- assertions {
- windowManagerTrace {
- all("isNotEmpty") { isNotEmpty() }
- }
- }
- }
- }
- }
-} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenTest.kt
deleted file mode 100644
index 701b0d05e65c..000000000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenTest.kt
+++ /dev/null
@@ -1,153 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.util.Rational
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
-import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
-import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
-import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
-import com.android.server.wm.flicker.layerBecomesInvisible
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.dsl.runWithFlicker
-import com.android.server.wm.flicker.helpers.exitSplitScreen
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.helpers.openQuickStepAndClearRecentAppsFromOverview
-import com.android.server.wm.flicker.helpers.resizeSplitScreen
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.wm.shell.flicker.dockedStackDividerIsInvisible
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper.Companion.TEST_REPETITIONS
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test exit SplitScreen mode.
- * To run this test: `atest WMShellFlickerTests:ExitLegacySplitScreenTest`
- */
-@Presubmit
-@RequiresDevice
-@RunWith(Parameterized::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExitLegacySplitScreenTest(
- rotationName: String,
- rotation: Int
-) : SplitScreenTestBase(rotationName, rotation) {
- private val splitScreenSetup: FlickerBuilder
- get() = FlickerBuilder(instrumentation).apply {
- val testLaunchActivity = "launch_splitScreen_test_activity"
- withTestName {
- testLaunchActivity
- }
- setup {
- eachRun {
- uiDevice.wakeUpAndGoToHomeScreen()
- uiDevice.openQuickStepAndClearRecentAppsFromOverview()
- secondaryApp.launchViaIntent()
- splitScreenApp.launchViaIntent()
- uiDevice.launchSplitScreen()
- }
- }
- teardown {
- eachRun {
- splitScreenApp.exit()
- secondaryApp.exit()
- }
- }
- assertions {
- windowManagerTrace {
- visibleWindowsShownMoreThanOneConsecutiveEntry()
- }
- layersTrace {
- visibleLayersShownMoreThanOneConsecutiveEntry(
- listOf(LAUNCHER_PACKAGE_NAME))
- }
- }
- }
-
- @Test
- fun testEnterSplitScreen_exitPrimarySplitScreenMode() {
- val testTag = "testEnterSplitScreen_exitPrimarySplitScreenMode"
- runWithFlicker(splitScreenSetup) {
- withTestName { testTag }
- repeat {
- TEST_REPETITIONS
- }
- transitions {
- uiDevice.exitSplitScreen()
- }
- assertions {
- layersTrace {
- dockedStackDividerIsInvisible()
- layerBecomesInvisible(splitScreenApp.defaultWindowName)
- }
- windowManagerTrace {
- navBarWindowIsAlwaysVisible()
- statusBarWindowIsAlwaysVisible()
- end("appWindowIsInvisible") {
- isInvisible(splitScreenApp.defaultWindowName)
- }
- }
- }
- }
- }
-
- @Test
- @FlakyTest(bugId = 172811376)
- fun testEnterSplitScreen_exitPrimary_showSecondaryAppFullScreen() {
- val testTag = "testEnterSplitScreen_exitPrimary_showSecondaryAppFullScreen"
- runWithFlicker(splitScreenSetup) {
- withTestName { testTag }
- repeat {
- TEST_REPETITIONS
- }
- transitions {
- splitScreenApp.reopenAppFromOverview()
- uiDevice.resizeSplitScreen(startRatio)
- }
- assertions {
- layersTrace {
- dockedStackDividerIsInvisible()
- }
- windowManagerTrace {
- navBarWindowIsAlwaysVisible()
- statusBarWindowIsAlwaysVisible()
- end("appWindowIsVisible") {
- isVisible(splitScreenApp.defaultWindowName)
- }
- }
- }
- }
- }
-
- companion object {
- private val startRatio = Rational(1, 3)
-
- @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/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitPrimarySplitScreenShowSecondaryFullscreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitPrimarySplitScreenShowSecondaryFullscreen.kt
new file mode 100644
index 000000000000..59f6aaf7dd6a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitPrimarySplitScreenShowSecondaryFullscreen.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2021 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.wm.shell.flicker.legacysplitscreen
+
+import android.os.Bundle
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.appWindowBecomesInVisible
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.layerBecomesInvisible
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
+import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
+import com.android.wm.shell.flicker.dockedStackDividerIsInvisible
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test dock activity to primary split screen, and open secondary to side, exit primary split
+ * and test secondary activity become full screen.
+ * To run this test: `atest WMShellFlickerTests:ExitPrimarySplitScreenShowSecondaryFullscreen`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class ExitPrimarySplitScreenShowSecondaryFullscreen(
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
+ companion object : LegacySplitScreenTransition(InstrumentationRegistry.getInstrumentation()) {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
+ withTestName {
+ buildTestTag("testExitPrimarySplitScreenShowSecondaryFullscreen", configuration)
+ }
+ repeat { SplitScreenHelper.TEST_REPETITIONS }
+ transitions {
+ device.launchSplitScreen()
+ secondaryApp.reopenAppFromOverview()
+ // TODO(b/175687842) Can not find Split screen divider, use exit() instead
+ splitScreenApp.exit()
+ }
+ assertions {
+ layersTrace {
+ dockedStackDividerIsInvisible(bugId = 175687842)
+ layerBecomesInvisible(splitScreenApp.defaultWindowName)
+ visibleLayersShownMoreThanOneConsecutiveEntry(
+ listOf(LAUNCHER_PACKAGE_NAME, splitScreenApp.defaultWindowName,
+ secondaryApp.defaultWindowName),
+ bugId = 178447631
+ )
+ }
+ windowManagerTrace {
+ appWindowBecomesInVisible(splitScreenApp.defaultWindowName)
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ visibleWindowsShownMoreThanOneConsecutiveEntry(
+ listOf(LAUNCHER_PACKAGE_NAME, splitScreenApp.defaultWindowName,
+ secondaryApp.defaultWindowName),
+ bugId = 178447631
+ )
+ }
+ }
+ }
+ return FlickerTestRunnerFactory.getInstance().buildTest(
+ instrumentation, defaultTransitionSetup, testSpec,
+ repetitions = SplitScreenHelper.TEST_REPETITIONS)
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncherTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncher.kt
index 4dcbdfff8cd5..03b6edf0ff2a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncherTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncher.kt
@@ -52,13 +52,13 @@ import org.junit.runners.Parameterized
/**
* Test open app to split screen.
- * To run this test: `atest WMShellFlickerTests:LegacySplitScreenToLauncherTest`
+ * To run this test: `atest WMShellFlickerTests:LegacySplitScreenToLauncher`
*/
@Presubmit
@RequiresDevice
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class LegacySplitScreenToLauncherTest(
+class LegacySplitScreenToLauncher(
testSpec: FlickerTestRunnerFactory.TestSpec
) : FlickerTestRunner(testSpec) {
companion object {
@@ -67,68 +67,68 @@ class LegacySplitScreenToLauncherTest(
fun getParams(): Collection<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val launcherPackageName = LauncherStrategyFactory.getInstance(instrumentation)
- .launcherStrategy.supportedLauncherPackage
+ .launcherStrategy.supportedLauncherPackage
val testApp = SimpleAppHelper(instrumentation)
// b/161435597 causes the test not to work on 90 degrees
return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation,
supportedRotations = listOf(Surface.ROTATION_0)) { configuration ->
- withTestName {
- buildTestTag("splitScreenToLauncher", configuration)
+ withTestName {
+ buildTestTag("splitScreenToLauncher", configuration)
+ }
+ repeat { configuration.repetitions }
+ setup {
+ test {
+ device.wakeUpAndGoToHomeScreen()
+ device.openQuickStepAndClearRecentAppsFromOverview()
}
- repeat { configuration.repetitions }
- setup {
- test {
- device.wakeUpAndGoToHomeScreen()
- device.openQuickStepAndClearRecentAppsFromOverview()
- }
- eachRun {
- testApp.launchViaIntent(wmHelper)
- this.setRotation(configuration.endRotation)
- device.launchSplitScreen()
- device.waitForIdle()
- }
+ eachRun {
+ testApp.launchViaIntent(wmHelper)
+ this.setRotation(configuration.endRotation)
+ device.launchSplitScreen()
+ device.waitForIdle()
}
- teardown {
- eachRun {
- testApp.exit()
- }
- test {
- if (device.isInSplitScreen()) {
- device.exitSplitScreen()
- }
+ }
+ teardown {
+ eachRun {
+ testApp.exit()
+ }
+ test {
+ if (device.isInSplitScreen()) {
+ device.exitSplitScreen()
}
}
- transitions {
- device.exitSplitScreen()
+ }
+ transitions {
+ device.exitSplitScreen()
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ visibleWindowsShownMoreThanOneConsecutiveEntry()
}
- assertions {
- windowManagerTrace {
- navBarWindowIsAlwaysVisible()
- statusBarWindowIsAlwaysVisible()
- visibleWindowsShownMoreThanOneConsecutiveEntry()
- }
- layersTrace {
- navBarLayerIsAlwaysVisible()
- statusBarLayerIsAlwaysVisible()
- noUncoveredRegions(configuration.endRotation)
- navBarLayerRotatesAndScales(configuration.endRotation)
- statusBarLayerRotatesScales(configuration.endRotation)
- visibleLayersShownMoreThanOneConsecutiveEntry(
- listOf(launcherPackageName))
+ layersTrace {
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ noUncoveredRegions(configuration.endRotation)
+ navBarLayerRotatesAndScales(configuration.endRotation)
+ statusBarLayerRotatesScales(configuration.endRotation)
+ visibleLayersShownMoreThanOneConsecutiveEntry(
+ listOf(launcherPackageName))
- // b/161435597 causes the test not to work on 90 degrees
- dockedStackDividerBecomesInvisible()
+ // b/161435597 causes the test not to work on 90 degrees
+ dockedStackDividerBecomesInvisible()
- layerBecomesInvisible(testApp.getPackage())
- }
+ layerBecomesInvisible(testApp.getPackage())
+ }
- eventLog {
- focusDoesNotChange(bugId = 151179149)
- }
+ eventLog {
+ focusDoesNotChange(bugId = 151179149)
}
}
+ }
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenTransition.kt
new file mode 100644
index 000000000000..328ff88cd41b
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenTransition.kt
@@ -0,0 +1,99 @@
+/*
+ * 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/LICENSE2.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.wm.shell.flicker.legacysplitscreen
+
+import android.app.Instrumentation
+import android.os.Bundle
+import android.support.test.launcherhelper.LauncherStrategyFactory
+import android.view.Surface
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.openQuickStepAndClearRecentAppsFromOverview
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.startRotation
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+
+abstract class LegacySplitScreenTransition(
+ protected val instrumentation: Instrumentation
+) {
+ internal val splitScreenApp = SplitScreenHelper.getPrimary(instrumentation)
+ internal val secondaryApp = SplitScreenHelper.getSecondary(instrumentation)
+ internal val nonResizeableApp = SplitScreenHelper.getNonResizeable(instrumentation)
+ internal val LAUNCHER_PACKAGE_NAME = LauncherStrategyFactory.getInstance(instrumentation)
+ .launcherStrategy.supportedLauncherPackage
+ internal val LIVE_WALLPAPER_PACKAGE_NAME =
+ "com.breel.wallpapers18.soundviz.wallpaper.variations.SoundVizWallpaperV2"
+ internal val LETTERBOX_NAME = "Letterbox"
+ internal val TOAST_NAME = "Toast"
+ internal val SPLASH_SCREEN_NAME = "Splash Screen"
+
+ internal open val defaultTransitionSetup: FlickerBuilder.(Bundle) -> Unit
+ get() = { configuration ->
+ setup {
+ eachRun {
+ device.wakeUpAndGoToHomeScreen()
+ device.openQuickStepAndClearRecentAppsFromOverview()
+ secondaryApp.launchViaIntent(wmHelper)
+ splitScreenApp.launchViaIntent(wmHelper)
+ this.setRotation(configuration.startRotation)
+ }
+ }
+ teardown {
+ eachRun {
+ splitScreenApp.exit()
+ secondaryApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ }
+ }
+
+ internal open val cleanSetup: FlickerBuilder.(Bundle) -> Unit
+ get() = { configuration ->
+ setup {
+ eachRun {
+ device.wakeUpAndGoToHomeScreen()
+ device.openQuickStepAndClearRecentAppsFromOverview()
+ this.setRotation(configuration.startRotation)
+ }
+ }
+ teardown {
+ eachRun {
+ nonResizeableApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ }
+ }
+
+ internal open val customRotateSetup: FlickerBuilder.(Bundle) -> Unit
+ get() = { configuration ->
+ setup {
+ eachRun {
+ device.wakeUpAndGoToHomeScreen()
+ device.openQuickStepAndClearRecentAppsFromOverview()
+ secondaryApp.launchViaIntent(wmHelper)
+ splitScreenApp.launchViaIntent(wmHelper)
+ }
+ }
+ teardown {
+ eachRun {
+ splitScreenApp.exit()
+ secondaryApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableDismissInLegacySplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableDismissInLegacySplitScreen.kt
new file mode 100644
index 000000000000..42c7b7c032cd
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableDismissInLegacySplitScreen.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2021 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.wm.shell.flicker.legacysplitscreen
+
+import android.os.Bundle
+import android.platform.test.annotations.Presubmit
+import android.view.Surface
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.DOCKED_STACK_DIVIDER
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.appWindowBecomesInVisible
+import com.android.server.wm.flicker.appWindowBecomesVisible
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.layerBecomesInvisible
+import com.android.server.wm.flicker.layerBecomesVisible
+import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
+import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test launch non resizable activity in split screen mode will trigger exit split screen mode
+ * (Non resizable activity launch via recent overview)
+ * To run this test: `atest WMShellFlickerTests:NonResizableDismissInLegacySplitScreen`
+ */
+@Presubmit
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class NonResizableDismissInLegacySplitScreen(
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
+ companion object : LegacySplitScreenTransition(InstrumentationRegistry.getInstrumentation()) {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
+ withTestName {
+ buildTestTag("testNonResizableDismissInLegacySplitScreen", configuration)
+ }
+ repeat { SplitScreenHelper.TEST_REPETITIONS }
+ transitions {
+ nonResizeableApp.launchViaIntent(wmHelper)
+ splitScreenApp.launchViaIntent(wmHelper)
+ device.launchSplitScreen()
+ nonResizeableApp.reopenAppFromOverview()
+ wmHelper.waitForAppTransitionIdle()
+ }
+ assertions {
+ layersTrace {
+ layerBecomesVisible(nonResizeableApp.defaultWindowName)
+ layerBecomesInvisible(splitScreenApp.defaultWindowName)
+ visibleLayersShownMoreThanOneConsecutiveEntry(
+ listOf(DOCKED_STACK_DIVIDER, LAUNCHER_PACKAGE_NAME,
+ LETTERBOX_NAME, TOAST_NAME,
+ splitScreenApp.defaultWindowName,
+ nonResizeableApp.defaultWindowName),
+ bugId = 178447631
+ )
+ }
+ windowManagerTrace {
+ appWindowBecomesVisible(nonResizeableApp.defaultWindowName)
+ appWindowBecomesInVisible(splitScreenApp.defaultWindowName)
+ visibleWindowsShownMoreThanOneConsecutiveEntry(
+ listOf(DOCKED_STACK_DIVIDER, LAUNCHER_PACKAGE_NAME,
+ LETTERBOX_NAME, TOAST_NAME,
+ splitScreenApp.defaultWindowName,
+ nonResizeableApp.defaultWindowName)
+ )
+ }
+ }
+ }
+ return FlickerTestRunnerFactory.getInstance().buildTest(
+ instrumentation, cleanSetup, testSpec,
+ repetitions = SplitScreenHelper.TEST_REPETITIONS,
+ supportedRotations = listOf(Surface.ROTATION_0 /* bugId = 178685668 */))
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableDismissInLegacySplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableDismissInLegacySplitScreenTest.kt
deleted file mode 100644
index 6fca5809b4fa..000000000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableDismissInLegacySplitScreenTest.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2021 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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.dsl.runWithFlicker
-import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
-import com.android.wm.shell.flicker.dockedStackDividerIsInvisible
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test open app to split screen.
- * To run this test: `atest WMShellFlickerTests:NonResizableDismissInLegacySplitScreenTest`
- */
-@Presubmit
-@RequiresDevice
-@RunWith(Parameterized::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class NonResizableDismissInLegacySplitScreenTest(
- rotationName: String,
- rotation: Int
-) : SplitScreenTestBase(rotationName, rotation) {
-
- @Test
- fun testNonResizableDismissInLegacySplitScreenTest() {
- val testTag = "testNonResizableDismissInLegacySplitScreenTest"
-
- runWithFlicker(transitionSetup) {
- withTestName { testTag }
- repeat { SplitScreenHelper.TEST_REPETITIONS }
- transitions {
- nonResizeableApp.launchViaIntent(wmHelper)
- splitScreenApp.launchViaIntent(wmHelper)
- device.launchSplitScreen()
- nonResizeableApp.reopenAppFromOverview()
- }
- assertions {
- layersTrace {
- dockedStackDividerIsInvisible()
- end("appsEndingBounds", enabled = false) {
- val displayBounds = WindowUtils.getDisplayBounds(rotation)
- this.hasVisibleRegion(nonResizeableApp.defaultWindowName, displayBounds)
- }
- visibleLayersShownMoreThanOneConsecutiveEntry(
- listOf(LAUNCHER_PACKAGE_NAME, splitScreenApp.defaultWindowName,
- nonResizeableApp.defaultWindowName, LETTER_BOX_NAME,
- TOAST_NAME, LIVE_WALLPAPER_PACKAGE_NAME),
- bugId = 178447631
- )
- }
- windowManagerTrace {
- end("nonResizeableAppWindowIsVisible") {
- isVisible(nonResizeableApp.defaultWindowName)
- .isInvisible(splitScreenApp.defaultWindowName)
- }
- }
- }
- }
- }
-
- companion object {
- @Parameterized.Parameters(name = "{0}")
- @JvmStatic
- fun getParams(): Collection<Array<Any>> {
- val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90)
- return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
- }
- }
-} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableLaunchInLegacySplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableLaunchInLegacySplitScreen.kt
new file mode 100644
index 000000000000..5b8ec1e9c61e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableLaunchInLegacySplitScreen.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2021 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.wm.shell.flicker.legacysplitscreen
+
+import android.os.Bundle
+import android.platform.test.annotations.Presubmit
+import android.view.Surface
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.DOCKED_STACK_DIVIDER
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.appWindowBecomesInVisible
+import com.android.server.wm.flicker.appWindowBecomesVisible
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.layerBecomesInvisible
+import com.android.server.wm.flicker.layerBecomesVisible
+import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
+import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test launch non resizable activity in split screen mode will trigger exit split screen mode
+ * (Non resizable activity launch via intent)
+ * To run this test: `atest WMShellFlickerTests:NonResizableLaunchInLegacySplitScreen`
+ */
+@Presubmit
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class NonResizableLaunchInLegacySplitScreen(
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
+ companion object : LegacySplitScreenTransition(InstrumentationRegistry.getInstrumentation()) {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
+ withTestName {
+ buildTestTag("testNonResizableLaunchInLegacySplitScreen", configuration)
+ }
+ repeat { SplitScreenHelper.TEST_REPETITIONS }
+ transitions {
+ splitScreenApp.launchViaIntent(wmHelper)
+ device.launchSplitScreen()
+ nonResizeableApp.launchViaIntent(wmHelper)
+ wmHelper.waitForAppTransitionIdle()
+ }
+ assertions {
+ layersTrace {
+ layerBecomesVisible(nonResizeableApp.defaultWindowName)
+ layerBecomesInvisible(splitScreenApp.defaultWindowName)
+ visibleLayersShownMoreThanOneConsecutiveEntry(
+ listOf(DOCKED_STACK_DIVIDER,
+ LAUNCHER_PACKAGE_NAME,
+ LETTERBOX_NAME,
+ nonResizeableApp.defaultWindowName,
+ splitScreenApp.defaultWindowName)
+ )
+ }
+ windowManagerTrace {
+ appWindowBecomesVisible(nonResizeableApp.defaultWindowName)
+ appWindowBecomesInVisible(splitScreenApp.defaultWindowName)
+ visibleWindowsShownMoreThanOneConsecutiveEntry(
+ listOf(DOCKED_STACK_DIVIDER,
+ LAUNCHER_PACKAGE_NAME,
+ LETTERBOX_NAME,
+ nonResizeableApp.defaultWindowName,
+ splitScreenApp.defaultWindowName)
+ )
+ }
+ }
+ }
+ return FlickerTestRunnerFactory.getInstance().buildTest(
+ instrumentation, cleanSetup, testSpec,
+ repetitions = SplitScreenHelper.TEST_REPETITIONS,
+ supportedRotations = listOf(Surface.ROTATION_0 /* bugId = 178685668 */))
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableLaunchInLegacySplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableLaunchInLegacySplitScreenTest.kt
deleted file mode 100644
index deae41fae0ca..000000000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/NonResizableLaunchInLegacySplitScreenTest.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2021 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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.dsl.runWithFlicker
-import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
-import com.android.wm.shell.flicker.dockedStackDividerIsInvisible
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test open app to split screen.
- * To run this test: `atest WMShellFlickerTests:NonResizableLaunchInLegacySplitScreenTest`
- */
-@Presubmit
-@RequiresDevice
-@RunWith(Parameterized::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class NonResizableLaunchInLegacySplitScreenTest(
- rotationName: String,
- rotation: Int
-) : SplitScreenTestBase(rotationName, rotation) {
-
- @Test
- fun testNonResizableLaunchInLegacySplitScreenTest() {
- val testTag = "testNonResizableLaunchInLegacySplitScreenTest"
-
- runWithFlicker(transitionSetup) {
- withTestName { testTag }
- repeat { SplitScreenHelper.TEST_REPETITIONS }
- transitions {
- nonResizeableApp.launchViaIntent(wmHelper)
- splitScreenApp.launchViaIntent(wmHelper)
- device.launchSplitScreen()
- nonResizeableApp.reopenAppFromOverview()
- }
- assertions {
- layersTrace {
- dockedStackDividerIsInvisible()
- end("appsEndingBounds", enabled = false) {
- val displayBounds = WindowUtils.getDisplayBounds(rotation)
- this.hasVisibleRegion(nonResizeableApp.defaultWindowName, displayBounds)
- }
- visibleLayersShownMoreThanOneConsecutiveEntry(
- listOf(LAUNCHER_PACKAGE_NAME, splitScreenApp.defaultWindowName,
- nonResizeableApp.defaultWindowName, LETTER_BOX_NAME,
- TOAST_NAME, LIVE_WALLPAPER_PACKAGE_NAME),
- bugId = 178447631
- )
- }
- windowManagerTrace {
- end("nonResizeableAppWindowIsVisible") {
- isVisible(nonResizeableApp.defaultWindowName)
- .isInvisible(splitScreenApp.defaultWindowName)
- }
- }
- }
- }
- }
-
- companion object {
- @Parameterized.Parameters(name = "{0}")
- @JvmStatic
- fun getParams(): Collection<Array<Any>> {
- val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90)
- return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
- }
- }
-} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OpenAppToLegacySplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OpenAppToLegacySplitScreen.kt
index 6200a69b795e..c802ffef204f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OpenAppToLegacySplitScreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OpenAppToLegacySplitScreen.kt
@@ -16,94 +16,84 @@
package com.android.wm.shell.flicker.legacysplitscreen
+import android.os.Bundle
import android.platform.test.annotations.Presubmit
-import android.view.Surface
import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.appWindowBecomesVisible
-import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
-import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
-import com.android.server.wm.flicker.layerBecomesVisible
+import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.focusChanges
+import com.android.server.wm.flicker.helpers.buildTestTag
import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.dsl.runWithFlicker
-import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.layerBecomesVisible
import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.startRotation
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
import com.android.wm.shell.flicker.appPairsDividerBecomesVisible
import com.android.wm.shell.flicker.helpers.SplitScreenHelper
import org.junit.FixMethodOrder
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
/**
* Test open app to split screen.
- * To run this test: `atest WMShellFlickerTests:OpenAppToLegacySplitScreenTest`
+ * To run this test: `atest WMShellFlickerTests:OpenAppToLegacySplitScreen`
*/
@Presubmit
@RequiresDevice
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenAppToLegacySplitScreenTest(
- rotationName: String,
- rotation: Int
-) : SplitScreenTestBase(rotationName, rotation) {
- @Test
- fun OpenAppToLegacySplitScreenTest() {
- val testTag = "OpenAppToLegacySplitScreenTest"
- val helper = WindowManagerStateHelper()
- runWithFlicker(transitionSetup) {
- withTestName { testTag }
- repeat { SplitScreenHelper.TEST_REPETITIONS }
- setup {
- eachRun {
- splitScreenApp.launchViaIntent(wmHelper)
- device.pressHome()
- this.setRotation(rotation)
+class OpenAppToLegacySplitScreen(
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
+ companion object : LegacySplitScreenTransition(InstrumentationRegistry.getInstrumentation()) {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val wmHelper = WindowManagerStateHelper()
+ val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
+ withTestName {
+ buildTestTag("testOpenAppToLegacySplitScreen", configuration)
}
- }
- transitions {
- device.launchSplitScreen()
- helper.waitForAppTransitionIdle()
- }
- assertions {
- windowManagerTrace {
- visibleWindowsShownMoreThanOneConsecutiveEntry(
- listOf(LAUNCHER_PACKAGE_NAME, splitScreenApp.defaultWindowName,
- LETTER_BOX_NAME)
- )
- appWindowBecomesVisible(splitScreenApp.getPackage())
+ repeat { SplitScreenHelper.TEST_REPETITIONS }
+ transitions {
+ device.launchSplitScreen()
+ wmHelper.waitForAppTransitionIdle()
}
+ assertions {
+ windowManagerTrace {
+ visibleWindowsShownMoreThanOneConsecutiveEntry(
+ listOf(LAUNCHER_PACKAGE_NAME, splitScreenApp.defaultWindowName),
+ bugId = 178447631)
+ appWindowBecomesVisible(splitScreenApp.getPackage())
+ }
- layersTrace {
- navBarLayerIsAlwaysVisible()
- noUncoveredRegions(rotation, enabled = false)
- statusBarLayerIsAlwaysVisible()
- visibleLayersShownMoreThanOneConsecutiveEntry(
- listOf(LAUNCHER_PACKAGE_NAME, splitScreenApp.defaultWindowName,
- LETTER_BOX_NAME))
- appPairsDividerBecomesVisible()
- layerBecomesVisible(splitScreenApp.getPackage())
- }
+ layersTrace {
+ noUncoveredRegions(configuration.startRotation, enabled = false)
+ statusBarLayerIsAlwaysVisible()
+ appPairsDividerBecomesVisible()
+ layerBecomesVisible(splitScreenApp.getPackage())
+ visibleLayersShownMoreThanOneConsecutiveEntry(
+ listOf(LAUNCHER_PACKAGE_NAME, splitScreenApp.defaultWindowName),
+ bugId = 178447631)
+ }
- eventLog {
- focusChanges(splitScreenApp.`package`,
+ eventLog {
+ focusChanges(splitScreenApp.`package`,
"recents_animation_input_consumer", "NexusLauncherActivity",
bugId = 151179149)
+ }
}
}
- }
- }
-
- companion object {
- @Parameterized.Parameters(name = "{0}")
- @JvmStatic
- fun getParams(): Collection<Array<Any>> {
- // TODO(b/161435597) causes the test not to work on 90 degrees
- val supportedRotations = intArrayOf(Surface.ROTATION_0)
- return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+ return FlickerTestRunnerFactory.getInstance().buildTest(
+ instrumentation, defaultTransitionSetup, testSpec,
+ repetitions = SplitScreenHelper.TEST_REPETITIONS)
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt
index 95c1c16385c4..54a37d71868d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt
@@ -58,7 +58,7 @@ import org.junit.runners.Parameterized
/**
* Test split screen resizing window transitions.
- * To run this test: `atest WMShellFlickerTests:ResizeLegacySplitScreenTest`
+ * To run this test: `atest WMShellFlickerTests:ResizeLegacySplitScreen`
*
* Currently it runs only in 0 degrees because of b/156100803
*/
@@ -67,7 +67,7 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 159096424)
-class ResizeLegacySplitScreenTest(
+class ResizeLegacySplitScreen(
testSpec: FlickerTestRunnerFactory.TestSpec
) : FlickerTestRunner(testSpec) {
companion object {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppAndEnterSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppAndEnterSplitScreen.kt
new file mode 100644
index 000000000000..214269e13203
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppAndEnterSplitScreen.kt
@@ -0,0 +1,95 @@
+/*
+ * 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.wm.shell.flicker.legacysplitscreen
+
+import android.os.Bundle
+import android.platform.test.annotations.Presubmit
+import android.view.Surface
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.appWindowBecomesVisible
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.endRotation
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.startRotation
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.dockedStackDividerIsVisible
+import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisible
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test dock activity to primary split screen and rotate
+ * To run this test: `atest WMShellFlickerTests:RotateOneLaunchedAppAndEnterSplitScreen`
+ */
+@Presubmit
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class RotateOneLaunchedAppAndEnterSplitScreen(
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
+ companion object : LegacySplitScreenTransition(InstrumentationRegistry.getInstrumentation()) {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
+ withTestName {
+ buildTestTag("testRotateOneLaunchedAppAndEnterSplitScreen", configuration)
+ }
+ repeat { SplitScreenHelper.TEST_REPETITIONS }
+ transitions {
+ device.launchSplitScreen()
+ this.setRotation(configuration.startRotation)
+ }
+ assertions {
+ layersTrace {
+ dockedStackDividerIsVisible(bugId = 175687842)
+ dockedStackPrimaryBoundsIsVisible(
+ configuration.startRotation,
+ splitScreenApp.defaultWindowName, bugId = 175687842)
+ navBarLayerRotatesAndScales(
+ configuration.startRotation,
+ configuration.endRotation, bugId = 169271943)
+ statusBarLayerRotatesScales(
+ configuration.startRotation,
+ configuration.endRotation, bugId = 169271943)
+ }
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ appWindowBecomesVisible(splitScreenApp.defaultWindowName)
+ }
+ }
+ }
+ return FlickerTestRunnerFactory.getInstance().buildTest(
+ instrumentation, customRotateSetup, testSpec,
+ repetitions = SplitScreenHelper.TEST_REPETITIONS,
+ supportedRotations = listOf(Surface.ROTATION_0 /* bugId = 178685668 */))
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppInSplitScreenMode.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppInSplitScreenMode.kt
new file mode 100644
index 000000000000..4290c923b38d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppInSplitScreenMode.kt
@@ -0,0 +1,95 @@
+/*
+ * 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.wm.shell.flicker.legacysplitscreen
+
+import android.os.Bundle
+import android.platform.test.annotations.Presubmit
+import android.view.Surface
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.appWindowBecomesVisible
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.endRotation
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.startRotation
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.dockedStackDividerIsVisible
+import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisible
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Rotate
+ * To run this test: `atest WMShellFlickerTests:RotateOneLaunchedAppInSplitScreenMode`
+ */
+@Presubmit
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class RotateOneLaunchedAppInSplitScreenMode(
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
+ companion object : LegacySplitScreenTransition(InstrumentationRegistry.getInstrumentation()) {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
+ withTestName {
+ buildTestTag("testRotateOneLaunchedAppInSplitScreenMode", configuration)
+ }
+ repeat { SplitScreenHelper.TEST_REPETITIONS }
+ transitions {
+ this.setRotation(configuration.startRotation)
+ device.launchSplitScreen()
+ }
+ assertions {
+ layersTrace {
+ dockedStackDividerIsVisible(bugId = 175687842)
+ dockedStackPrimaryBoundsIsVisible(
+ configuration.startRotation,
+ splitScreenApp.defaultWindowName, bugId = 175687842)
+ navBarLayerRotatesAndScales(
+ configuration.startRotation,
+ configuration.endRotation, bugId = 169271943)
+ statusBarLayerRotatesScales(
+ configuration.startRotation,
+ configuration.endRotation, bugId = 169271943)
+ }
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ appWindowBecomesVisible(splitScreenApp.defaultWindowName)
+ }
+ }
+ }
+ return FlickerTestRunnerFactory.getInstance().buildTest(
+ instrumentation, customRotateSetup, testSpec,
+ repetitions = SplitScreenHelper.TEST_REPETITIONS,
+ supportedRotations = listOf(Surface.ROTATION_0 /* bugId = 178685668 */))
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppTest.kt
deleted file mode 100644
index 07571c3218a8..000000000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppTest.kt
+++ /dev/null
@@ -1,150 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.dsl.runWithFlicker
-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.openQuickStepAndClearRecentAppsFromOverview
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
-import com.android.wm.shell.flicker.dockedStackDividerIsVisible
-import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisible
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test open app to split screen.
- * To run this test: `atest WMShellFlickerTests:RotateOneLaunchedAppTest`
- */
-@Presubmit
-@RequiresDevice
-@RunWith(Parameterized::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class RotateOneLaunchedAppTest(
- rotationName: String,
- rotation: Int
-) : SplitScreenTestBase(rotationName, rotation) {
- private val splitScreenRotationSetup: FlickerBuilder
- get() = FlickerBuilder(instrumentation).apply {
- val testSetupRotation = "testSetupRotation"
- withTestName {
- testSetupRotation
- }
- setup {
- test {
- uiDevice.wakeUpAndGoToHomeScreen()
- uiDevice.openQuickStepAndClearRecentAppsFromOverview()
- }
- }
- teardown {
- eachRun {
- if (uiDevice.isInSplitScreen()) {
- uiDevice.exitSplitScreen()
- }
- setRotation(Surface.ROTATION_0)
- splitScreenApp.exit()
- secondaryApp.exit()
- }
- }
- }
-
- @Test
- fun testRotateInSplitScreenMode() {
- val testTag = "testEnterSplitScreen_launchToSide"
- runWithFlicker(splitScreenRotationSetup) {
- withTestName { testTag }
- repeat {
- SplitScreenHelper.TEST_REPETITIONS
- }
- transitions {
- splitScreenApp.launchViaIntent()
- uiDevice.launchSplitScreen()
- setRotation(rotation)
- }
- assertions {
- layersTrace {
- navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation, 169271943)
- statusBarLayerRotatesScales(Surface.ROTATION_0, rotation, 169271943)
- dockedStackDividerIsVisible()
- dockedStackPrimaryBoundsIsVisible(
- rotation, splitScreenApp.defaultWindowName, 169271943)
- }
- windowManagerTrace {
- navBarWindowIsAlwaysVisible()
- statusBarWindowIsAlwaysVisible()
- end("appWindowIsVisible") {
- isVisible(splitScreenApp.defaultWindowName)
- }
- }
- }
- }
- }
-
- @Test
- fun testRotateAndEnterSplitScreenMode() {
- val testTag = "testRotateAndEnterSplitScreenMode"
- runWithFlicker(splitScreenRotationSetup) {
- withTestName { testTag }
- repeat {
- SplitScreenHelper.TEST_REPETITIONS
- }
- transitions {
- splitScreenApp.launchViaIntent()
- setRotation(rotation)
- uiDevice.launchSplitScreen()
- }
- assertions {
- layersTrace {
- navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation, 169271943)
- statusBarLayerRotatesScales(Surface.ROTATION_0, rotation, 169271943)
- dockedStackDividerIsVisible()
- dockedStackPrimaryBoundsIsVisible(
- rotation, splitScreenApp.defaultWindowName, 169271943)
- }
- windowManagerTrace {
- navBarWindowIsAlwaysVisible()
- statusBarWindowIsAlwaysVisible()
- end("appWindowIsVisible") {
- isVisible(splitScreenApp.defaultWindowName)
- }
- }
- }
- }
- }
-
- companion object {
- @Parameterized.Parameters(name = "{0}")
- @JvmStatic
- fun getParams(): Collection<Array<Any>> {
- val supportedRotations = intArrayOf(Surface.ROTATION_90, Surface.ROTATION_270)
- return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
- }
- }
-} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppAndEnterSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppAndEnterSplitScreen.kt
new file mode 100644
index 000000000000..4095b9a2e61e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppAndEnterSplitScreen.kt
@@ -0,0 +1,100 @@
+/*
+ * 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.wm.shell.flicker.legacysplitscreen
+
+import android.os.Bundle
+import android.platform.test.annotations.Presubmit
+import android.view.Surface
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.appWindowBecomesVisible
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.endRotation
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.startRotation
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.dockedStackDividerIsVisible
+import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisible
+import com.android.wm.shell.flicker.dockedStackSecondaryBoundsIsVisible
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test open app to split screen.
+ * To run this test: `atest WMShellFlickerTests:RotateTwoLaunchedAppAndEnterSplitScreen`
+ */
+@Presubmit
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class RotateTwoLaunchedAppAndEnterSplitScreen(
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
+ companion object : LegacySplitScreenTransition(InstrumentationRegistry.getInstrumentation()) {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
+ withTestName {
+ buildTestTag("testRotateTwoLaunchedAppAndEnterSplitScreen", configuration)
+ }
+ repeat { SplitScreenHelper.TEST_REPETITIONS }
+ transitions {
+ this.setRotation(configuration.startRotation)
+ device.launchSplitScreen()
+ secondaryApp.reopenAppFromOverview()
+ }
+ assertions {
+ layersTrace {
+ dockedStackDividerIsVisible(bugId = 175687842)
+ dockedStackPrimaryBoundsIsVisible(
+ configuration.startRotation,
+ splitScreenApp.defaultWindowName, 175687842)
+ dockedStackSecondaryBoundsIsVisible(
+ configuration.startRotation,
+ secondaryApp.defaultWindowName, bugId = 175687842)
+ navBarLayerRotatesAndScales(
+ configuration.startRotation,
+ configuration.endRotation, bugId = 169271943)
+ statusBarLayerRotatesScales(
+ configuration.startRotation,
+ configuration.endRotation, bugId = 169271943)
+ }
+ windowManagerTrace {
+ appWindowBecomesVisible(secondaryApp.defaultWindowName)
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ }
+ }
+ }
+ return FlickerTestRunnerFactory.getInstance().buildTest(
+ instrumentation, customRotateSetup, testSpec,
+ repetitions = SplitScreenHelper.TEST_REPETITIONS,
+ supportedRotations = listOf(Surface.ROTATION_0 /* bugId = 178685668 */))
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppInSplitScreenMode.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppInSplitScreenMode.kt
new file mode 100644
index 000000000000..aebf6067615e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppInSplitScreenMode.kt
@@ -0,0 +1,105 @@
+/*
+ * 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.wm.shell.flicker.legacysplitscreen
+
+import android.os.Bundle
+import android.platform.test.annotations.Presubmit
+import android.view.Surface
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.appWindowBecomesVisible
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.endRotation
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.startRotation
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.dockedStackDividerIsVisible
+import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisible
+import com.android.wm.shell.flicker.dockedStackSecondaryBoundsIsVisible
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test open app to split screen.
+ * To run this test: `atest WMShellFlickerTests:RotateTwoLaunchedAppInSplitScreenMode`
+ */
+@Presubmit
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class RotateTwoLaunchedAppInSplitScreenMode(
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
+ companion object : LegacySplitScreenTransition(InstrumentationRegistry.getInstrumentation()) {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
+ withTestName {
+ buildTestTag("testRotateTwoLaunchedAppInSplitScreenMode", configuration)
+ }
+ repeat { SplitScreenHelper.TEST_REPETITIONS }
+ setup {
+ eachRun {
+ device.launchSplitScreen()
+ splitScreenApp.reopenAppFromOverview()
+ this.setRotation(configuration.startRotation)
+ }
+ }
+ transitions {
+ this.setRotation(configuration.startRotation)
+ }
+ assertions {
+ layersTrace {
+ dockedStackDividerIsVisible(bugId = 175687842)
+ dockedStackPrimaryBoundsIsVisible(
+ configuration.startRotation,
+ splitScreenApp.defaultWindowName, bugId = 175687842)
+ dockedStackSecondaryBoundsIsVisible(
+ configuration.startRotation,
+ secondaryApp.defaultWindowName, bugId = 175687842)
+ navBarLayerRotatesAndScales(
+ configuration.startRotation,
+ configuration.endRotation, bugId = 169271943)
+ statusBarLayerRotatesScales(
+ configuration.startRotation,
+ configuration.endRotation, bugId = 169271943)
+ }
+ windowManagerTrace {
+ appWindowBecomesVisible(secondaryApp.defaultWindowName)
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ }
+ }
+ }
+ return FlickerTestRunnerFactory.getInstance().buildTest(
+ instrumentation, customRotateSetup, testSpec,
+ repetitions = SplitScreenHelper.TEST_REPETITIONS,
+ supportedRotations = listOf(Surface.ROTATION_0 /* bugId = 178685668 */))
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppTest.kt
deleted file mode 100644
index d8014d37dfad..000000000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppTest.kt
+++ /dev/null
@@ -1,163 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.dsl.runWithFlicker
-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.openQuickStepAndClearRecentAppsFromOverview
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
-import com.android.wm.shell.flicker.dockedStackDividerIsVisible
-import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisible
-import com.android.wm.shell.flicker.dockedStackSecondaryBoundsIsVisible
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test open app to split screen.
- * To run this test: `atest WMShellFlickerTests:RotateTwoLaunchedAppTest`
- */
-@Presubmit
-@RequiresDevice
-@RunWith(Parameterized::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class RotateTwoLaunchedAppTest(
- rotationName: String,
- rotation: Int
-) : SplitScreenTestBase(rotationName, rotation) {
- private val splitScreenRotationSetup: FlickerBuilder
- get() = FlickerBuilder(instrumentation).apply {
- val testSetupRotation = "testSetupRotation"
- withTestName {
- testSetupRotation
- }
- setup {
- test {
- uiDevice.wakeUpAndGoToHomeScreen()
- uiDevice.openQuickStepAndClearRecentAppsFromOverview()
- }
- }
- teardown {
- eachRun {
- if (uiDevice.isInSplitScreen()) {
- uiDevice.exitSplitScreen()
- }
- setRotation(Surface.ROTATION_0)
- splitScreenApp.exit()
- secondaryApp.exit()
- }
- }
- }
-
- @Test
- fun testRotateInSplitScreenMode() {
- val testTag = "testRotateInSplitScreenMode"
- runWithFlicker(splitScreenRotationSetup) {
- withTestName { testTag }
- repeat {
- SplitScreenHelper.TEST_REPETITIONS
- }
- transitions {
- secondaryApp.launchViaIntent()
- splitScreenApp.launchViaIntent()
- uiDevice.launchSplitScreen()
- splitScreenApp.reopenAppFromOverview()
- setRotation(rotation)
- }
- assertions {
- layersTrace {
- navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation, 169271943)
- statusBarLayerRotatesScales(Surface.ROTATION_0, rotation, 169271943)
- dockedStackDividerIsVisible()
- dockedStackPrimaryBoundsIsVisible(
- rotation, splitScreenApp.defaultWindowName, 169271943)
- dockedStackSecondaryBoundsIsVisible(
- rotation, secondaryApp.defaultWindowName, 169271943)
- }
- windowManagerTrace {
- navBarWindowIsAlwaysVisible()
- statusBarWindowIsAlwaysVisible()
- end("appWindowIsVisible") {
- isVisible(splitScreenApp.defaultWindowName)
- .isVisible(secondaryApp.defaultWindowName)
- }
- }
- }
- }
- }
-
- @FlakyTest(bugId = 173875043)
- @Test
- fun testRotateAndEnterSplitScreenMode() {
- val testTag = "testRotateAndEnterSplitScreenMode"
- runWithFlicker(splitScreenRotationSetup) {
- withTestName { testTag }
- repeat {
- SplitScreenHelper.TEST_REPETITIONS
- }
- transitions {
- secondaryApp.launchViaIntent()
- splitScreenApp.launchViaIntent()
- setRotation(rotation)
- uiDevice.launchSplitScreen()
- splitScreenApp.reopenAppFromOverview()
- }
- assertions {
- layersTrace {
- navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation, 169271943)
- statusBarLayerRotatesScales(Surface.ROTATION_0, rotation, 169271943)
- dockedStackDividerIsVisible()
- dockedStackPrimaryBoundsIsVisible(
- rotation, splitScreenApp.defaultWindowName, 169271943)
- dockedStackSecondaryBoundsIsVisible(
- rotation, secondaryApp.defaultWindowName, 169271943)
- }
- windowManagerTrace {
- navBarWindowIsAlwaysVisible()
- statusBarWindowIsAlwaysVisible()
- end("appWindowIsVisible") {
- isVisible(splitScreenApp.defaultWindowName)
- .isVisible(secondaryApp.defaultWindowName)
- }
- }
- }
- }
- }
-
- companion object {
- @Parameterized.Parameters(name = "{0}")
- @JvmStatic
- fun getParams(): Collection<Array<Any>> {
- val supportedRotations = intArrayOf(Surface.ROTATION_90, Surface.ROTATION_270)
- return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
- }
- }
-} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/SplitScreenTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/SplitScreenTestBase.kt
deleted file mode 100644
index 01db4ed6253e..000000000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/SplitScreenTestBase.kt
+++ /dev/null
@@ -1,74 +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.wm.shell.flicker.legacysplitscreen
-
-import android.support.test.launcherhelper.LauncherStrategyFactory
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.exitSplitScreen
-import com.android.server.wm.flicker.helpers.isInSplitScreen
-import com.android.server.wm.flicker.helpers.openQuickStepAndClearRecentAppsFromOverview
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
-import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
-import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
-import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
-import com.android.wm.shell.flicker.NonRotationTestBase
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-
-abstract class SplitScreenTestBase(
- rotationName: String,
- rotation: Int
-) : NonRotationTestBase(rotationName, rotation) {
- protected val splitScreenApp = SplitScreenHelper.getPrimary(instrumentation)
- protected val secondaryApp = SplitScreenHelper.getSecondary(instrumentation)
- protected val nonResizeableApp = SplitScreenHelper.getNonResizeable(instrumentation)
- protected val LAUNCHER_PACKAGE_NAME = LauncherStrategyFactory.getInstance(instrumentation)
- .launcherStrategy.supportedLauncherPackage
- protected val LIVE_WALLPAPER_PACKAGE_NAME =
- "com.breel.wallpapers18.soundviz.wallpaper.variations.SoundVizWallpaperV2"
- protected val LETTER_BOX_NAME = "Letterbox"
- protected val TOAST_NAME = "Toast"
-
- protected val transitionSetup: FlickerBuilder
- get() = FlickerBuilder(instrumentation).apply {
- setup {
- eachRun {
- uiDevice.wakeUpAndGoToHomeScreen()
- uiDevice.openQuickStepAndClearRecentAppsFromOverview()
- }
- }
- teardown {
- eachRun {
- if (uiDevice.isInSplitScreen()) {
- uiDevice.exitSplitScreen()
- }
- splitScreenApp.exit()
- nonResizeableApp.exit()
- }
- }
- assertions {
- layersTrace {
- navBarLayerIsAlwaysVisible()
- statusBarLayerIsAlwaysVisible()
- }
- windowManagerTrace {
- navBarWindowIsAlwaysVisible()
- statusBarWindowIsAlwaysVisible()
- }
- }
- }
-}
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 615bf4de9fcc..ce1d96c167d7 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -435,6 +435,7 @@ cc_defaults {
"canvas/CanvasFrontend.cpp",
"canvas/CanvasOpBuffer.cpp",
"canvas/CanvasOpRasterizer.cpp",
+ "effects/StretchEffect.cpp",
"pipeline/skia/SkiaDisplayList.cpp",
"pipeline/skia/SkiaRecordingCanvas.cpp",
"pipeline/skia/RenderNodeDrawable.cpp",
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 96118aaec29b..64b8b711f0a8 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -561,7 +561,7 @@ public:
return;
}
c->concat(invertedMatrix);
- mLayerSurface->draw(c, deviceBounds.fLeft, deviceBounds.fTop, nullptr);
+ mLayerSurface->draw(c, deviceBounds.fLeft, deviceBounds.fTop);
} else {
c->drawDrawable(drawable.get());
}
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index aeb60e6ce355..609706e2e49d 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -23,6 +23,7 @@
#include "Outline.h"
#include "Rect.h"
#include "RevealClip.h"
+#include "effects/StretchEffect.h"
#include "utils/MathUtils.h"
#include "utils/PaintUtils.h"
@@ -98,6 +99,10 @@ public:
SkImageFilter* getImageFilter() const { return mImageFilter.get(); }
+ const StretchEffect& getStretchEffect() const { return mStretchEffect; }
+
+ StretchEffect& mutableStretchEffect() { return mStretchEffect; }
+
// Sets alpha, xfermode, and colorfilter from an SkPaint
// paint may be NULL, in which case defaults will be set
bool setFromPaint(const SkPaint* paint);
@@ -124,6 +129,7 @@ private:
SkBlendMode mMode;
sk_sp<SkColorFilter> mColorFilter;
sk_sp<SkImageFilter> mImageFilter;
+ StretchEffect mStretchEffect;
};
/*
diff --git a/libs/hwui/effects/StretchEffect.cpp b/libs/hwui/effects/StretchEffect.cpp
new file mode 100644
index 000000000000..51cbc7592861
--- /dev/null
+++ b/libs/hwui/effects/StretchEffect.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "StretchEffect.h"
+
+namespace android::uirenderer {
+
+sk_sp<SkImageFilter> StretchEffect::getImageFilter() const {
+ // TODO: Implement & Cache
+ // Probably need to use mutable to achieve caching
+ return nullptr;
+}
+
+} // namespace android::uirenderer \ No newline at end of file
diff --git a/libs/hwui/effects/StretchEffect.h b/libs/hwui/effects/StretchEffect.h
new file mode 100644
index 000000000000..7dfd6398765a
--- /dev/null
+++ b/libs/hwui/effects/StretchEffect.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include "utils/MathUtils.h"
+
+#include <SkPoint.h>
+#include <SkRect.h>
+#include <SkImageFilter.h>
+
+namespace android::uirenderer {
+
+// TODO: Inherit from base RenderEffect type?
+class StretchEffect {
+public:
+ enum class StretchInterpolator {
+ SmoothStep,
+ };
+
+ bool isEmpty() const {
+ return MathUtils::isZero(stretchDirection.x())
+ && MathUtils::isZero(stretchDirection.y());
+ }
+
+ void setEmpty() {
+ *this = StretchEffect{};
+ }
+
+ void mergeWith(const StretchEffect& other) {
+ if (other.isEmpty()) {
+ return;
+ }
+ if (isEmpty()) {
+ *this = other;
+ return;
+ }
+ stretchDirection += other.stretchDirection;
+ if (isEmpty()) {
+ return setEmpty();
+ }
+ stretchArea.join(other.stretchArea);
+ maxStretchAmount = std::max(maxStretchAmount, other.maxStretchAmount);
+ }
+
+ sk_sp<SkImageFilter> getImageFilter() const;
+
+ SkRect stretchArea {0, 0, 0, 0};
+ SkVector stretchDirection {0, 0};
+ float maxStretchAmount = 0;
+};
+
+} // namespace android::uirenderer
diff --git a/libs/hwui/jni/android_graphics_RenderNode.cpp b/libs/hwui/jni/android_graphics_RenderNode.cpp
index 8b35d96aeac8..80239687a7fb 100644
--- a/libs/hwui/jni/android_graphics_RenderNode.cpp
+++ b/libs/hwui/jni/android_graphics_RenderNode.cpp
@@ -166,6 +166,31 @@ static jboolean android_view_RenderNode_setOutlineNone(CRITICAL_JNI_PARAMS_COMMA
return true;
}
+static jboolean android_view_RenderNode_clearStretch(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ auto& stretch = renderNode->mutateStagingProperties()
+ .mutateLayerProperties().mutableStretchEffect();
+ if (stretch.isEmpty()) {
+ return false;
+ }
+ stretch.setEmpty();
+ renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+ return true;
+}
+
+static jboolean android_view_RenderNode_stretch(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
+ jfloat left, jfloat top, jfloat right, jfloat bottom, jfloat vX, jfloat vY, jfloat max) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().mutateLayerProperties().mutableStretchEffect().mergeWith(
+ StretchEffect{
+ .stretchArea = SkRect::MakeLTRB(left, top, right, bottom),
+ .stretchDirection = {.fX = vX, .fY = vY},
+ .maxStretchAmount = max
+ });
+ renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+ return true;
+}
+
static jboolean android_view_RenderNode_hasShadow(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().hasShadow();
@@ -678,6 +703,8 @@ static const JNINativeMethod gMethods[] = {
{ "nSetOutlinePath", "(JJF)Z", (void*) android_view_RenderNode_setOutlinePath },
{ "nSetOutlineEmpty", "(J)Z", (void*) android_view_RenderNode_setOutlineEmpty },
{ "nSetOutlineNone", "(J)Z", (void*) android_view_RenderNode_setOutlineNone },
+ { "nClearStretch", "(J)Z", (void*) android_view_RenderNode_clearStretch },
+ { "nStretch", "(JFFFFFFF)Z", (void*) android_view_RenderNode_stretch },
{ "nHasShadow", "(J)Z", (void*) android_view_RenderNode_hasShadow },
{ "nSetSpotShadowColor", "(JI)Z", (void*) android_view_RenderNode_setSpotShadowColor },
{ "nGetSpotShadowColor", "(J)I", (void*) android_view_RenderNode_getSpotShadowColor },
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
index c6c9e9dc869a..71f533c3fc4f 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
@@ -194,7 +194,7 @@ void GLFunctorDrawable::onDraw(SkCanvas* canvas) {
canvas->concat(invertedMatrix);
const SkIRect deviceBounds = canvas->getDeviceClipBounds();
- tmpSurface->draw(canvas, deviceBounds.fLeft, deviceBounds.fTop, nullptr);
+ tmpSurface->draw(canvas, deviceBounds.fLeft, deviceBounds.fTop);
}
}
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index 75815bb6e63d..c01021221f37 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -20,6 +20,8 @@
#include "SkiaDisplayList.h"
#include "utils/TraceUtils.h"
+#include <include/effects/SkImageFilters.h>
+
#include <optional>
namespace android {
@@ -171,11 +173,25 @@ static bool layerNeedsPaint(const LayerProperties& properties, float alphaMultip
SkPaint* paint) {
if (alphaMultiplier < 1.0f || properties.alpha() < 255 ||
properties.xferMode() != SkBlendMode::kSrcOver || properties.getColorFilter() != nullptr ||
- properties.getImageFilter() != nullptr) {
+ properties.getImageFilter() != nullptr || !properties.getStretchEffect().isEmpty()) {
paint->setAlpha(properties.alpha() * alphaMultiplier);
paint->setBlendMode(properties.xferMode());
paint->setColorFilter(sk_ref_sp(properties.getColorFilter()));
- paint->setImageFilter(sk_ref_sp(properties.getImageFilter()));
+
+ sk_sp<SkImageFilter> imageFilter = sk_ref_sp(properties.getImageFilter());
+ sk_sp<SkImageFilter> stretchFilter = properties.getStretchEffect().getImageFilter();
+ sk_sp<SkImageFilter> filter;
+ if (imageFilter && stretchFilter) {
+ filter = SkImageFilters::Compose(
+ std::move(stretchFilter),
+ std::move(imageFilter)
+ );
+ } else if (stretchFilter) {
+ filter = std::move(stretchFilter);
+ } else {
+ filter = std::move(imageFilter);
+ }
+ paint->setImageFilter(std::move(filter));
return true;
}
return false;
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp
index d464587cb6c8..3d633ea7089d 100644
--- a/native/graphics/jni/Android.bp
+++ b/native/graphics/jni/Android.bp
@@ -27,14 +27,13 @@ cc_library_shared {
],
shared_libs: [
- "libandroid_runtime",
"libhwui",
"liblog",
],
header_libs: [
- "libhwui_internal_headers",
"jni_headers",
+ "libhwui_internal_headers",
],
static_libs: ["libarect"],
diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
index 0832152d6ab6..8bfa77acd36d 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
@@ -401,11 +401,18 @@ public final class NetworkCapabilities implements Parcelable {
public static final int NET_CAPABILITY_VEHICLE_INTERNAL = 27;
/**
- * Indicates that this network is not managed by a Virtual Carrier Network (VCN).
- *
- * TODO(b/177299683): Add additional clarifying javadoc.
+ * Indicates that this network is not subsumed by a Virtual Carrier Network (VCN).
+ * <p>
+ * To provide an experience on a VCN similar to a single traditional carrier network, in
+ * some cases the system sets this bit is set by default in application's network requests,
+ * and may choose to remove it at its own discretion when matching the request to a network.
+ * <p>
+ * Applications that want to know about a Virtual Carrier Network's underlying networks,
+ * for example to use them for multipath purposes, should remove this bit from their network
+ * requests ; the system will not add it back once removed.
* @hide
*/
+ @SystemApi
public static final int NET_CAPABILITY_NOT_VCN_MANAGED = 28;
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
diff --git a/packages/SystemUI/res/drawable/privacy_item_circle_camera.xml b/packages/SystemUI/res/drawable/privacy_item_circle_camera.xml
index cf6413642c63..5cb6f4626b36 100644
--- a/packages/SystemUI/res/drawable/privacy_item_circle_camera.xml
+++ b/packages/SystemUI/res/drawable/privacy_item_circle_camera.xml
@@ -21,16 +21,16 @@
>
<shape android:shape="oval">
<size
- android:height="28dp"
- android:width="28dp"
+ android:height="@dimen/ongoing_appops_dialog_circle_size"
+ android:width="@dimen/ongoing_appops_dialog_circle_size"
/>
<solid android:color="@color/privacy_circle_camera" />
</shape>
</item>
<item android:id="@id/icon"
android:gravity="center"
- android:width="20dp"
- android:height="20dp"
+ android:width="@dimen/ongoing_appops_dialog_icon_size"
+ android:height="@dimen/ongoing_appops_dialog_icon_size"
android:drawable="@*android:drawable/perm_group_camera"
/>
</layer-list> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/privacy_item_circle_location.xml b/packages/SystemUI/res/drawable/privacy_item_circle_location.xml
index 0a6a4a31d0a5..28466c8a29b3 100644
--- a/packages/SystemUI/res/drawable/privacy_item_circle_location.xml
+++ b/packages/SystemUI/res/drawable/privacy_item_circle_location.xml
@@ -21,16 +21,16 @@
>
<shape android:shape="oval">
<size
- android:height="28dp"
- android:width="28dp"
+ android:height="@dimen/ongoing_appops_dialog_circle_size"
+ android:width="@dimen/ongoing_appops_dialog_circle_size"
/>
<solid android:color="@color/privacy_circle_microphone_location" />
</shape>
</item>
<item android:id="@id/icon"
android:gravity="center"
- android:width="20dp"
- android:height="20dp"
+ android:width="@dimen/ongoing_appops_dialog_icon_size"
+ android:height="@dimen/ongoing_appops_dialog_icon_size"
android:drawable="@*android:drawable/perm_group_microphone"
/>
</layer-list> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/privacy_item_circle_microphone.xml b/packages/SystemUI/res/drawable/privacy_item_circle_microphone.xml
index 0a6a4a31d0a5..28466c8a29b3 100644
--- a/packages/SystemUI/res/drawable/privacy_item_circle_microphone.xml
+++ b/packages/SystemUI/res/drawable/privacy_item_circle_microphone.xml
@@ -21,16 +21,16 @@
>
<shape android:shape="oval">
<size
- android:height="28dp"
- android:width="28dp"
+ android:height="@dimen/ongoing_appops_dialog_circle_size"
+ android:width="@dimen/ongoing_appops_dialog_circle_size"
/>
<solid android:color="@color/privacy_circle_microphone_location" />
</shape>
</item>
<item android:id="@id/icon"
android:gravity="center"
- android:width="20dp"
- android:height="20dp"
+ android:width="@dimen/ongoing_appops_dialog_icon_size"
+ android:height="@dimen/ongoing_appops_dialog_icon_size"
android:drawable="@*android:drawable/perm_group_microphone"
/>
</layer-list> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/privacy_dialog.xml b/packages/SystemUI/res/layout/privacy_dialog.xml
index 5db247e25d50..4d77a0d75689 100644
--- a/packages/SystemUI/res/layout/privacy_dialog.xml
+++ b/packages/SystemUI/res/layout/privacy_dialog.xml
@@ -22,7 +22,13 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/ongoing_appops_dialog_side_margins"
android:layout_marginEnd="@dimen/ongoing_appops_dialog_side_margins"
+ android:layout_marginTop="8dp"
android:orientation="vertical"
- android:padding = "8dp"
+ android:paddingLeft="@dimen/ongoing_appops_dialog_side_padding"
+ android:paddingRight="@dimen/ongoing_appops_dialog_side_padding"
+ android:paddingBottom="12dp"
+ android:paddingTop="8dp"
android:background="@drawable/privacy_dialog_bg"
-/> \ No newline at end of file
+/>
+<!-- 12dp padding bottom so there's 20dp total under the icon -->
+<!-- 8dp padding top, as there's 4dp margin in each row --> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/privacy_dialog_item.xml b/packages/SystemUI/res/layout/privacy_dialog_item.xml
index 882e9680407e..91ffe225fac6 100644
--- a/packages/SystemUI/res/layout/privacy_dialog_item.xml
+++ b/packages/SystemUI/res/layout/privacy_dialog_item.xml
@@ -16,19 +16,22 @@
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/privacy_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:orientation="horizontal"
- android:layout_marginTop="8dp"
+ android:layout_marginTop="4dp"
+ android:importantForAccessibility="yes"
+ android:focusable="true"
>
+ <!-- 4dp marginTop makes 20dp minimum between icons -->
<ImageView
android:id="@+id/icon"
- android:layout_width="24dp"
- android:layout_height="24dp"
+ android:layout_width="@dimen/ongoing_appops_dialog_circle_size"
+ android:layout_height="@dimen/ongoing_appops_dialog_circle_size"
android:layout_gravity="center_vertical"
- android:layout_marginStart="12dp"
- android:layout_marginEnd="12dp"
+ android:importantForAccessibility="no"
/>
<TextView
@@ -38,25 +41,21 @@
android:layout_width="0dp"
android:layout_weight="1"
android:layout_gravity="center_vertical"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:textDirection="locale"
+ android:textAlignment="viewStart"
android:gravity="start | center_vertical"
- android:textAppearance="@style/TextAppearance.QS.TileLabel"
+ android:textAppearance="@style/TextAppearance.PrivacyDialog"
+ android:lineHeight="20sp"
/>
- <FrameLayout
- android:id="@+id/link"
- android:layout_width="48dp"
- android:layout_height="48dp"
+ <ImageView
+ android:layout_height="24dp"
+ android:layout_width="24dp"
android:layout_gravity="center_vertical"
- android:background="?android:attr/selectableItemBackground"
- >
-
- <ImageView
- android:layout_height="24dp"
- android:layout_width="24dp"
- android:layout_gravity="center"
- android:src="@*android:drawable/ic_chevron_end"
- android:tint="?android:attr/textColorPrimary"
- />
- </FrameLayout>
+ android:src="@*android:drawable/ic_chevron_end"
+ android:tint="?android:attr/textColorPrimary"
+ />
</LinearLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e5109307c4f4..1fac96bb181d 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1181,6 +1181,12 @@
<dimen name="ongoing_appops_dialog_side_margins">@dimen/notification_shade_content_margin_horizontal</dimen>
+ <dimen name="ongoing_appops_dialog_circle_size">32dp</dimen>
+
+ <dimen name="ongoing_appops_dialog_icon_size">20dp</dimen>
+
+ <dimen name="ongoing_appops_dialog_side_padding">16dp</dimen>
+
<!-- Size of the RAT type for CellularTile -->
<dimen name="celltile_rat_type_size">10sp</dimen>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index db260ce1b7b4..ad4e78e8e507 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -745,4 +745,9 @@
* Title: headline, medium 20sp
* Message: body, 16 sp -->
<style name="Theme.ControlsRequestDialog" parent="@*android:style/Theme.DeviceDefault.Dialog.Alert"/>
+
+ <style name="TextAppearance.PrivacyDialog">
+ <item name="android:textSize">14sp</item>
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+ </style>
</resources>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 9908e672535f..d9a1eb6c0b28 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1909,12 +1909,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
/**
- * Whether to show the lock icon on lock screen and bouncer. This depends on the enrolled
- * biometrics to the device.
+ * Whether to show the lock icon on lock screen and bouncer.
*/
- public boolean shouldShowLockIcon() {
- return isFaceAuthEnabledForUser(KeyguardUpdateMonitor.getCurrentUser())
- && !isUdfpsEnrolled();
+ public boolean canShowLockIcon() {
+ if (mLockScreenMode == LOCK_SCREEN_MODE_LAYOUT_1) {
+ return isFaceAuthEnabledForUser(KeyguardUpdateMonitor.getCurrentUser())
+ && !isUdfpsEnrolled();
+ }
+ return true;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
index 66c535f869f0..c3d6a848202f 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
@@ -24,7 +24,6 @@ import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.view.WindowInsets
import android.widget.ImageView
@@ -66,9 +65,8 @@ class PrivacyDialog(
super.onCreate(savedInstanceState)
window?.apply {
attributes.fitInsetsTypes = attributes.fitInsetsTypes or WindowInsets.Type.statusBars()
- setLayout(MATCH_PARENT, WRAP_CONTENT)
+ setLayout(context.resources.getDimensionPixelSize(R.dimen.qs_panel_width), WRAP_CONTENT)
setGravity(Gravity.TOP or Gravity.CENTER_HORIZONTAL)
- setBackgroundDrawable(null)
}
setContentView(R.layout.privacy_dialog)
@@ -130,7 +128,7 @@ class PrivacyDialog(
)
} ?: firstLine
newView.requireViewById<TextView>(R.id.text).text = finalText
- newView.requireViewById<View>(R.id.link).apply {
+ newView.apply {
tag = element.type.permGroupName
setOnClickListener(clickListener)
}
@@ -154,9 +152,7 @@ class PrivacyDialog(
}
private val clickListener = View.OnClickListener { v ->
- if (v.id == R.id.link) {
- v.tag?.let { activityStarter(it as String) }
- }
+ v.tag?.let { activityStarter(it as String) }
}
/** */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java b/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java
index 1ec043cb7670..e4ae560ba69b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java
@@ -23,8 +23,6 @@ import android.view.ViewGroup;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
-import com.android.systemui.statusbar.phone.LockIcon;
-import com.android.systemui.statusbar.phone.LockscreenLockIconController;
import com.android.systemui.statusbar.phone.NotificationPanelView;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
import com.android.systemui.statusbar.phone.StatusBarWindowView;
@@ -41,7 +39,6 @@ public class SuperStatusBarViewFactory {
private final Context mContext;
private final InjectionInflationController mInjectionInflationController;
- private final LockscreenLockIconController mLockIconController;
private final NotificationShelfComponent.Builder mNotificationShelfComponentBuilder;
private NotificationShadeWindowView mNotificationShadeWindowView;
@@ -51,11 +48,9 @@ public class SuperStatusBarViewFactory {
@Inject
public SuperStatusBarViewFactory(Context context,
InjectionInflationController injectionInflationController,
- NotificationShelfComponent.Builder notificationShelfComponentBuilder,
- LockscreenLockIconController lockIconController) {
+ NotificationShelfComponent.Builder notificationShelfComponentBuilder) {
mContext = context;
mInjectionInflationController = injectionInflationController;
- mLockIconController = lockIconController;
mNotificationShelfComponentBuilder = notificationShelfComponentBuilder;
}
@@ -77,10 +72,6 @@ public class SuperStatusBarViewFactory {
throw new IllegalStateException(
"R.layout.super_notification_shade could not be properly inflated");
}
- LockIcon lockIcon = mNotificationShadeWindowView.findViewById(R.id.lock_icon);
- if (lockIcon != null) {
- mLockIconController.attach(lockIcon);
- }
return mNotificationShadeWindowView;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index e1eaf3c17357..f289b9f20211 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -71,7 +71,7 @@ public final class DozeServiceHost implements DozeHost {
"persist.sysui.wake_performs_auth", true);
private boolean mDozingRequested;
private boolean mPulsing;
- private WakefulnessLifecycle mWakefulnessLifecycle;
+ private final WakefulnessLifecycle mWakefulnessLifecycle;
private final SysuiStatusBarStateController mStatusBarStateController;
private final DeviceProvisionedController mDeviceProvisionedController;
private final HeadsUpManagerPhone mHeadsUpManagerPhone;
@@ -86,9 +86,8 @@ public final class DozeServiceHost implements DozeHost {
private final NotificationShadeWindowController mNotificationShadeWindowController;
private final NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
private NotificationShadeWindowViewController mNotificationShadeWindowViewController;
- private final LockscreenLockIconController mLockscreenLockIconController;
private final AuthController mAuthController;
- private NotificationIconAreaController mNotificationIconAreaController;
+ private final NotificationIconAreaController mNotificationIconAreaController;
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private NotificationPanelViewController mNotificationPanel;
private View mAmbientIndicationContainer;
@@ -109,7 +108,6 @@ public final class DozeServiceHost implements DozeHost {
PulseExpansionHandler pulseExpansionHandler,
NotificationShadeWindowController notificationShadeWindowController,
NotificationWakeUpCoordinator notificationWakeUpCoordinator,
- LockscreenLockIconController lockscreenLockIconController,
AuthController authController,
NotificationIconAreaController notificationIconAreaController) {
super();
@@ -129,7 +127,6 @@ public final class DozeServiceHost implements DozeHost {
mPulseExpansionHandler = pulseExpansionHandler;
mNotificationShadeWindowController = notificationShadeWindowController;
mNotificationWakeUpCoordinator = notificationWakeUpCoordinator;
- mLockscreenLockIconController = lockscreenLockIconController;
mAuthController = authController;
mNotificationIconAreaController = notificationIconAreaController;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
index eceac3240ebc..4b70de997906 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
@@ -37,12 +37,10 @@ import androidx.annotation.Nullable;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardSecurityModel;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.settingslib.Utils;
import com.android.systemui.R;
-import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -52,18 +50,20 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator.WakeUpListener;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
+import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
import com.android.systemui.statusbar.policy.AccessibilityController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.ViewController;
import java.util.Optional;
import javax.inject.Inject;
-/** Controls the {@link LockIcon} in the lockscreen. */
-@SysUISingleton
-public class LockscreenLockIconController {
+/** Controls the {@link LockIcon} on the lockscreen. */
+@StatusBarComponent.StatusBarScope
+public class LockscreenLockIconController extends ViewController<LockIcon> {
private final LockscreenGestureLogger mLockscreenGestureLogger;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -79,7 +79,6 @@ public class LockscreenLockIconController {
private final KeyguardStateController mKeyguardStateController;
private final Resources mResources;
private final HeadsUpManagerPhone mHeadsUpManagerPhone;
- private final KeyguardSecurityModel mKeyguardSecurityModel;
private boolean mKeyguardShowing;
private boolean mKeyguardJustShown;
private boolean mBlockUpdates;
@@ -92,231 +91,13 @@ public class LockscreenLockIconController {
private boolean mBouncerShowingScrimmed;
private boolean mFingerprintUnlock;
private int mStatusBarState = StatusBarState.SHADE;
- private LockIcon mLockIcon;
-
- private View.OnAttachStateChangeListener mOnAttachStateChangeListener =
- new View.OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(View v) {
- mStatusBarStateController.addCallback(mSBStateListener);
- mConfigurationController.addCallback(mConfigurationListener);
- mNotificationWakeUpCoordinator.addListener(mWakeUpListener);
- mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback);
- mKeyguardStateController.addCallback(mKeyguardMonitorCallback);
-
- mDockManager.ifPresent(dockManager -> dockManager.addListener(mDockEventListener));
-
- mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
- mConfigurationListener.onThemeChanged();
-
- updateColor();
- update();
- }
-
- @Override
- public void onViewDetachedFromWindow(View v) {
- mStatusBarStateController.removeCallback(mSBStateListener);
- mConfigurationController.removeCallback(mConfigurationListener);
- mNotificationWakeUpCoordinator.removeListener(mWakeUpListener);
- mKeyguardUpdateMonitor.removeCallback(mUpdateMonitorCallback);
- mKeyguardStateController.removeCallback(mKeyguardMonitorCallback);
-
- mDockManager.ifPresent(dockManager -> dockManager.removeListener(mDockEventListener));
- }
- };
-
- private final StatusBarStateController.StateListener mSBStateListener =
- new StatusBarStateController.StateListener() {
- @Override
- public void onDozingChanged(boolean isDozing) {
- setDozing(isDozing);
- }
-
- @Override
- public void onDozeAmountChanged(float linear, float eased) {
- if (mLockIcon != null) {
- mLockIcon.setDozeAmount(eased);
- }
- }
-
- @Override
- public void onStateChanged(int newState) {
- setStatusBarState(newState);
- }
- };
-
- private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
- private int mDensity;
-
- @Override
- public void onUiModeChanged() {
- updateColor();
- }
-
- @Override
- public void onOverlayChanged() {
- updateColor();
- }
-
- @Override
- public void onDensityOrFontScaleChanged() {
- if (mLockIcon == null) {
- return;
- }
-
- ViewGroup.LayoutParams lp = mLockIcon.getLayoutParams();
- if (lp == null) {
- return;
- }
- lp.width = mLockIcon.getResources().getDimensionPixelSize(R.dimen.keyguard_lock_width);
- lp.height = mLockIcon.getResources().getDimensionPixelSize(
- R.dimen.keyguard_lock_height);
- mLockIcon.setLayoutParams(lp);
- update(true /* force */);
- }
-
- @Override
- public void onLocaleListChanged() {
- if (mLockIcon == null) {
- return;
- }
-
- mLockIcon.setContentDescription(
- mLockIcon.getResources().getText(R.string.accessibility_unlock_button));
- update(true /* force */);
- }
-
- @Override
- public void onConfigChanged(Configuration newConfig) {
- final int density = newConfig.densityDpi;
- if (density != mDensity) {
- mDensity = density;
- update();
- }
- }
- };
-
- private final WakeUpListener mWakeUpListener = new WakeUpListener() {
- @Override
- public void onPulseExpansionChanged(boolean expandingChanged) {
- }
-
- @Override
- public void onFullyHiddenChanged(boolean isFullyHidden) {
- if (mKeyguardBypassController.getBypassEnabled()) {
- boolean changed = updateIconVisibility();
- if (changed) {
- update();
- }
- }
- }
- };
-
- private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
- new KeyguardUpdateMonitorCallback() {
- @Override
- public void onSimStateChanged(int subId, int slotId, int simState) {
- mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
- update();
- }
-
- @Override
- public void onKeyguardVisibilityChanged(boolean showing) {
- update();
- }
-
- @Override
- public void onBiometricRunningStateChanged(boolean running,
- BiometricSourceType biometricSourceType) {
- update();
- }
-
- @Override
- public void onStrongAuthStateChanged(int userId) {
- update();
- }
- };
-
- private final DockManager.DockEventListener mDockEventListener =
- event -> {
- boolean docked =
- event == DockManager.STATE_DOCKED || event == DockManager.STATE_DOCKED_HIDE;
- if (docked != mDocked) {
- mDocked = docked;
- update();
- }
- };
-
- private final KeyguardStateController.Callback mKeyguardMonitorCallback =
- new KeyguardStateController.Callback() {
- @Override
- public void onKeyguardShowingChanged() {
- boolean force = false;
- boolean wasShowing = mKeyguardShowing;
- mKeyguardShowing = mKeyguardStateController.isShowing();
- if (!wasShowing && mKeyguardShowing && mBlockUpdates) {
- mBlockUpdates = false;
- force = true;
- }
- if (!wasShowing && mKeyguardShowing) {
- setBouncerHideAmount(KeyguardBouncer.EXPANSION_HIDDEN);
- mKeyguardJustShown = true;
- }
- update(force);
- }
-
- @Override
- public void onKeyguardFadingAwayChanged() {
- if (!mKeyguardStateController.isKeyguardFadingAway()) {
- if (mBlockUpdates) {
- mBlockUpdates = false;
- update(true /* force */);
- }
- }
- }
-
- @Override
- public void onUnlockedChanged() {
- update();
- }
- };
-
- private final View.AccessibilityDelegate mAccessibilityDelegate =
- new View.AccessibilityDelegate() {
- @Override
- public void onInitializeAccessibilityNodeInfo(View host,
- AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(host, info);
- boolean fingerprintRunning =
- mKeyguardUpdateMonitor.isFingerprintDetectionRunning();
- // Only checking if unlocking with Biometric is allowed (no matter strong or
- // non-strong as long as primary auth, i.e. PIN/pattern/password, is not
- // required), so it's ok to pass true for isStrongBiometric to
- // isUnlockingWithBiometricAllowed() to bypass the check of whether non-strong
- // biometric is allowed
- boolean unlockingAllowed = mKeyguardUpdateMonitor
- .isUnlockingWithBiometricAllowed(true /* isStrongBiometric */);
- if (fingerprintRunning && unlockingAllowed) {
- AccessibilityNodeInfo.AccessibilityAction unlock =
- new AccessibilityNodeInfo.AccessibilityAction(
- AccessibilityNodeInfo.ACTION_CLICK,
- mResources.getString(
- R.string.accessibility_unlock_without_fingerprint));
- info.addAction(unlock);
- info.setHintText(mResources.getString(
- R.string.accessibility_waiting_for_fingerprint));
- } else if (getState() == STATE_SCANNING_FACE) {
- //Avoid 'button' to be spoken for scanning face
- info.setClassName(LockIcon.class.getName());
- info.setContentDescription(mResources.getString(
- R.string.accessibility_scanning_face));
- }
- }
- };
private int mLastState;
+ private boolean mDozing;
@Inject
- public LockscreenLockIconController(LockscreenGestureLogger lockscreenGestureLogger,
+ public LockscreenLockIconController(
+ @Nullable LockIcon view,
+ LockscreenGestureLogger lockscreenGestureLogger,
KeyguardUpdateMonitor keyguardUpdateMonitor,
LockPatternUtils lockPatternUtils,
ShadeController shadeController,
@@ -329,8 +110,8 @@ public class LockscreenLockIconController {
@Nullable DockManager dockManager,
KeyguardStateController keyguardStateController,
@Main Resources resources,
- HeadsUpManagerPhone headsUpManagerPhone,
- KeyguardSecurityModel keyguardSecurityModel) {
+ HeadsUpManagerPhone headsUpManagerPhone) {
+ super(view);
mLockscreenGestureLogger = lockscreenGestureLogger;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mLockPatternUtils = lockPatternUtils;
@@ -345,32 +126,52 @@ public class LockscreenLockIconController {
mKeyguardStateController = keyguardStateController;
mResources = resources;
mHeadsUpManagerPhone = headsUpManagerPhone;
- mKeyguardSecurityModel = keyguardSecurityModel;
+
+ if (view == null) {
+ return;
+ }
mKeyguardIndicationController.setLockIconController(this);
}
- /**
- * Associate the controller with a {@link LockIcon}
- *
- * TODO: change to an init method and inject the view.
- */
- public void attach(LockIcon lockIcon) {
- mLockIcon = lockIcon;
-
- mLockIcon.setOnClickListener(this::handleClick);
- mLockIcon.setOnLongClickListener(this::handleLongClick);
- mLockIcon.setAccessibilityDelegate(mAccessibilityDelegate);
-
- if (mLockIcon.isAttachedToWindow()) {
- mOnAttachStateChangeListener.onViewAttachedToWindow(mLockIcon);
+ @Override
+ protected void onInit() {
+ if (mView == null) {
+ return;
}
- mLockIcon.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
+ mView.setOnClickListener(this::handleClick);
+ mView.setOnLongClickListener(this::handleLongClick);
+ mView.setAccessibilityDelegate(mAccessibilityDelegate);
+ }
+
+ @Override
+ protected void onViewAttached() {
setStatusBarState(mStatusBarStateController.getState());
+ mDozing = mStatusBarStateController.isDozing();
+ mStatusBarStateController.addCallback(mSBStateListener);
+ mConfigurationController.addCallback(mConfigurationListener);
+ mNotificationWakeUpCoordinator.addListener(mWakeUpListener);
+ mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback);
+ mKeyguardStateController.addCallback(mKeyguardMonitorCallback);
+
+ mDockManager.ifPresent(dockManager -> dockManager.addListener(mDockEventListener));
+
+ mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
+ mConfigurationListener.onThemeChanged();
+
+ updateColor();
+ update();
}
- public LockIcon getView() {
- return mLockIcon;
+ @Override
+ protected void onViewDetached() {
+ mStatusBarStateController.removeCallback(mSBStateListener);
+ mConfigurationController.removeCallback(mConfigurationListener);
+ mNotificationWakeUpCoordinator.removeListener(mWakeUpListener);
+ mKeyguardUpdateMonitor.removeCallback(mUpdateMonitorCallback);
+ mKeyguardStateController.removeCallback(mKeyguardMonitorCallback);
+
+ mDockManager.ifPresent(dockManager -> dockManager.removeListener(mDockEventListener));
}
/**
@@ -430,31 +231,30 @@ public class LockscreenLockIconController {
}
private void updateColor() {
- if (mLockIcon == null) {
+ if (mView == null) {
return;
}
-
int iconColor = -1;
if (mBouncerHiddenAmount == KeyguardBouncer.EXPANSION_VISIBLE) {
- TypedArray typedArray = mLockIcon.getContext().getTheme().obtainStyledAttributes(
+ TypedArray typedArray = mView.getContext().getTheme().obtainStyledAttributes(
null, new int[]{ android.R.attr.textColorPrimary }, 0, 0);
iconColor = typedArray.getColor(0, Color.WHITE);
typedArray.recycle();
} else if (mBouncerHiddenAmount == KeyguardBouncer.EXPANSION_HIDDEN) {
iconColor = Utils.getColorAttrDefaultColor(
- mLockIcon.getContext(), com.android.systemui.R.attr.wallpaperTextColor);
+ mView.getContext(), com.android.systemui.R.attr.wallpaperTextColor);
} else {
// bouncer is transitioning
- TypedArray typedArray = mLockIcon.getContext().getTheme().obtainStyledAttributes(
+ TypedArray typedArray = mView.getContext().getTheme().obtainStyledAttributes(
null, new int[]{ android.R.attr.textColorPrimary }, 0, 0);
int bouncerIconColor = typedArray.getColor(0, Color.WHITE);
typedArray.recycle();
int keyguardIconColor = Utils.getColorAttrDefaultColor(
- mLockIcon.getContext(), com.android.systemui.R.attr.wallpaperTextColor);
+ mView.getContext(), com.android.systemui.R.attr.wallpaperTextColor);
iconColor = (int) new ArgbEvaluator().evaluate(
mBouncerHiddenAmount, bouncerIconColor, keyguardIconColor);
}
- mLockIcon.updateColor(iconColor);
+ mView.updateColor(iconColor);
}
/**
@@ -497,14 +297,16 @@ public class LockscreenLockIconController {
}
private void update(boolean force) {
+ if (mView == null) {
+ return;
+ }
int state = getState();
boolean shouldUpdate = mLastState != state || force;
if (mBlockUpdates && canBlockUpdates()) {
shouldUpdate = false;
}
- if (shouldUpdate && mLockIcon != null && mLockIcon.getVisibility() != GONE) {
- mLockIcon.update(state,
- mStatusBarStateController.isDozing(), mKeyguardJustShown);
+ if (shouldUpdate && mView.getVisibility() != GONE) {
+ mView.update(state, mDozing, mKeyguardJustShown);
}
mLastState = state;
mKeyguardJustShown = false;
@@ -531,10 +333,6 @@ public class LockscreenLockIconController {
return mKeyguardShowing || mKeyguardStateController.isKeyguardFadingAway();
}
- private void setDozing(boolean isDozing) {
- update();
- }
-
/** Set the StatusBarState. */
private void setStatusBarState(int statusBarState) {
mStatusBarState = statusBarState;
@@ -546,17 +344,16 @@ public class LockscreenLockIconController {
* @return true if the visibility changed
*/
private boolean updateIconVisibility() {
- if (mLockIcon == null) {
+ if (mView == null) {
return false;
}
-
- if (!mKeyguardUpdateMonitor.shouldShowLockIcon()) {
- boolean changed = mLockIcon.getVisibility() != GONE;
- mLockIcon.setVisibility(GONE);
+ if (!mKeyguardUpdateMonitor.canShowLockIcon()) {
+ boolean changed = mView.getVisibility() != GONE;
+ mView.setVisibility(GONE);
return changed;
}
- boolean onAodOrDocked = mStatusBarStateController.isDozing() || mDocked;
+ boolean onAodOrDocked = mDozing || mDocked;
boolean invisible = onAodOrDocked || mWakeAndUnlockRunning || mShowingLaunchAffordance;
boolean fingerprintOrBypass = mFingerprintUnlock
|| mKeyguardBypassController.getBypassEnabled();
@@ -569,21 +366,202 @@ public class LockscreenLockIconController {
invisible = true;
}
}
- return mLockIcon.updateIconVisibility(!invisible);
+ return mView.updateIconVisibility(!invisible);
}
private void updateClickability() {
- if (mAccessibilityController == null) {
+ if (mView == null) {
return;
}
boolean canLock = mKeyguardStateController.isMethodSecure()
&& mKeyguardStateController.canDismissLockScreen();
boolean clickToUnlock = mAccessibilityController.isAccessibilityEnabled();
- if (mLockIcon != null) {
- mLockIcon.setClickable(clickToUnlock);
- mLockIcon.setLongClickable(canLock && !clickToUnlock);
- mLockIcon.setFocusable(mAccessibilityController.isAccessibilityEnabled());
- }
+ mView.setClickable(clickToUnlock);
+ mView.setLongClickable(canLock && !clickToUnlock);
+ mView.setFocusable(mAccessibilityController.isAccessibilityEnabled());
}
+ private final StatusBarStateController.StateListener mSBStateListener =
+ new StatusBarStateController.StateListener() {
+ @Override
+ public void onDozingChanged(boolean isDozing) {
+ if (mDozing != isDozing) {
+ mDozing = isDozing;
+ update();
+ }
+ }
+
+ @Override
+ public void onDozeAmountChanged(float linear, float eased) {
+ if (mView != null) {
+ mView.setDozeAmount(eased);
+ }
+ }
+
+ @Override
+ public void onStateChanged(int newState) {
+ setStatusBarState(newState);
+ }
+ };
+
+ private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
+ private int mDensity;
+
+ @Override
+ public void onUiModeChanged() {
+ updateColor();
+ }
+
+ @Override
+ public void onOverlayChanged() {
+ updateColor();
+ }
+
+ @Override
+ public void onDensityOrFontScaleChanged() {
+ ViewGroup.LayoutParams lp = mView.getLayoutParams();
+ if (lp == null) {
+ return;
+ }
+ lp.width = mView.getResources().getDimensionPixelSize(R.dimen.keyguard_lock_width);
+ lp.height = mView.getResources().getDimensionPixelSize(
+ R.dimen.keyguard_lock_height);
+ mView.setLayoutParams(lp);
+ update(true /* force */);
+ }
+
+ @Override
+ public void onLocaleListChanged() {
+ mView.setContentDescription(
+ mView.getResources().getText(R.string.accessibility_unlock_button));
+ update(true /* force */);
+ }
+
+ @Override
+ public void onConfigChanged(Configuration newConfig) {
+ final int density = newConfig.densityDpi;
+ if (density != mDensity) {
+ mDensity = density;
+ update();
+ }
+ }
+ };
+
+ private final WakeUpListener mWakeUpListener = new WakeUpListener() {
+ @Override
+ public void onPulseExpansionChanged(boolean expandingChanged) {
+ }
+
+ @Override
+ public void onFullyHiddenChanged(boolean isFullyHidden) {
+ if (mKeyguardBypassController.getBypassEnabled()) {
+ boolean changed = updateIconVisibility();
+ if (changed) {
+ update();
+ }
+ }
+ }
+ };
+
+ private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
+ new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onSimStateChanged(int subId, int slotId, int simState) {
+ mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
+ update();
+ }
+
+ @Override
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ update();
+ }
+
+ @Override
+ public void onBiometricRunningStateChanged(boolean running,
+ BiometricSourceType biometricSourceType) {
+ update();
+ }
+
+ @Override
+ public void onStrongAuthStateChanged(int userId) {
+ update();
+ }
+ };
+
+ private final DockManager.DockEventListener mDockEventListener =
+ event -> {
+ boolean docked =
+ event == DockManager.STATE_DOCKED || event == DockManager.STATE_DOCKED_HIDE;
+ if (docked != mDocked) {
+ mDocked = docked;
+ update();
+ }
+ };
+
+ private final KeyguardStateController.Callback mKeyguardMonitorCallback =
+ new KeyguardStateController.Callback() {
+ @Override
+ public void onKeyguardShowingChanged() {
+ boolean force = false;
+ boolean wasShowing = mKeyguardShowing;
+ mKeyguardShowing = mKeyguardStateController.isShowing();
+ if (!wasShowing && mKeyguardShowing && mBlockUpdates) {
+ mBlockUpdates = false;
+ force = true;
+ }
+ if (!wasShowing && mKeyguardShowing) {
+ setBouncerHideAmount(KeyguardBouncer.EXPANSION_HIDDEN);
+ mKeyguardJustShown = true;
+ }
+ update(force);
+ }
+
+ @Override
+ public void onKeyguardFadingAwayChanged() {
+ if (!mKeyguardStateController.isKeyguardFadingAway()) {
+ if (mBlockUpdates) {
+ mBlockUpdates = false;
+ update(true /* force */);
+ }
+ }
+ }
+
+ @Override
+ public void onUnlockedChanged() {
+ update();
+ }
+ };
+
+ private final View.AccessibilityDelegate mAccessibilityDelegate =
+ new View.AccessibilityDelegate() {
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host,
+ AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ boolean fingerprintRunning =
+ mKeyguardUpdateMonitor.isFingerprintDetectionRunning();
+ // Only checking if unlocking with Biometric is allowed (no matter strong or
+ // non-strong as long as primary auth, i.e. PIN/pattern/password, is not
+ // required), so it's ok to pass true for isStrongBiometric to
+ // isUnlockingWithBiometricAllowed() to bypass the check of whether non-strong
+ // biometric is allowed
+ boolean unlockingAllowed = mKeyguardUpdateMonitor
+ .isUnlockingWithBiometricAllowed(true /* isStrongBiometric */);
+ if (fingerprintRunning && unlockingAllowed) {
+ AccessibilityNodeInfo.AccessibilityAction unlock =
+ new AccessibilityNodeInfo.AccessibilityAction(
+ AccessibilityNodeInfo.ACTION_CLICK,
+ mResources.getString(
+ R.string.accessibility_unlock_without_fingerprint));
+ info.addAction(unlock);
+ info.setHintText(mResources.getString(
+ R.string.accessibility_waiting_for_fingerprint));
+ } else if (getState() == STATE_SCANNING_FACE) {
+ //Avoid 'button' to be spoken for scanning face
+ info.setClassName(LockIcon.class.getName());
+ info.setContentDescription(mResources.getString(
+ R.string.accessibility_scanning_face));
+ }
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index b24d0e7762ad..a5284f1421a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -910,7 +910,7 @@ public class NotificationPanelViewController extends PanelViewController {
clockPreferredY, hasCustomClock(),
hasVisibleNotifications, mInterpolatedDarkAmount, mEmptyDragAmount,
bypassEnabled, getUnlockedStackScrollerPadding(),
- mUpdateMonitor.shouldShowLockIcon(),
+ mUpdateMonitor.canShowLockIcon(),
getQsExpansionFraction(),
mDisplayCutoutTopInset);
mClockPositionAlgorithm.run(mClockPositionResult);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 83651398be43..4a3d8d67e85d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -368,7 +368,6 @@ public class StatusBar extends SystemUI implements DemoMode,
protected NotificationShadeWindowController mNotificationShadeWindowController;
protected StatusBarWindowController mStatusBarWindowController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
- private final LockscreenLockIconController mLockscreenLockIconController;
@VisibleForTesting
DozeServiceHost mDozeServiceHost;
private boolean mWakeUpComingFromTouch;
@@ -415,6 +414,7 @@ public class StatusBar extends SystemUI implements DemoMode,
// expanded notifications
// the sliding/resizing panel within the notification window
protected NotificationPanelViewController mNotificationPanelViewController;
+ protected LockscreenLockIconController mLockscreenLockIconController;
// settings
private QSPanelController mQSPanelController;
@@ -725,7 +725,6 @@ public class StatusBar extends SystemUI implements DemoMode,
Lazy<AssistManager> assistManagerLazy,
ConfigurationController configurationController,
NotificationShadeWindowController notificationShadeWindowController,
- LockscreenLockIconController lockscreenLockIconController,
DozeParameters dozeParameters,
ScrimController scrimController,
@Nullable KeyguardLiftController keyguardLiftController,
@@ -807,7 +806,6 @@ public class StatusBar extends SystemUI implements DemoMode,
mAssistManagerLazy = assistManagerLazy;
mConfigurationController = configurationController;
mNotificationShadeWindowController = notificationShadeWindowController;
- mLockscreenLockIconController = lockscreenLockIconController;
mDozeServiceHost = dozeServiceHost;
mPowerManager = powerManager;
mDozeParameters = dozeParameters;
@@ -1173,9 +1171,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mScrimController.setScrimVisibleListener(scrimsVisible -> {
mNotificationShadeWindowController.setScrimsVisibility(scrimsVisible);
- if (mNotificationShadeWindowView != null) {
- mLockscreenLockIconController.onScrimVisibilityChanged(scrimsVisible);
- }
+ mLockscreenLockIconController.onScrimVisibilityChanged(scrimsVisible);
});
mScrimController.attachViews(scrimBehind, scrimInFront, scrimForBubble);
@@ -1208,9 +1204,6 @@ public class StatusBar extends SystemUI implements DemoMode,
createUserSwitcher();
}
- mNotificationPanelViewController.setLaunchAffordanceListener(
- mLockscreenLockIconController::onShowingLaunchAffordanceChanged);
-
// Set up the quick settings tile panel
final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame);
if (container != null) {
@@ -1490,6 +1483,11 @@ public class StatusBar extends SystemUI implements DemoMode,
mStatusBarWindowController = statusBarComponent.getStatusBarWindowController();
mPhoneStatusBarWindow = mSuperStatusBarViewFactory.getStatusBarWindowView();
mNotificationPanelViewController = statusBarComponent.getNotificationPanelViewController();
+ mLockscreenLockIconController = statusBarComponent.getLockscreenLockIconController();
+ mLockscreenLockIconController.init();
+
+ mNotificationPanelViewController.setLaunchAffordanceListener(
+ mLockscreenLockIconController::onShowingLaunchAffordanceChanged);
}
protected void startKeyguard() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
index 802da3e8c21c..ecd9613f84b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone.dagger;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import com.android.systemui.statusbar.phone.LockscreenLockIconController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController;
@@ -73,4 +74,9 @@ public interface StatusBarComponent {
@StatusBarScope
NotificationPanelViewController getNotificationPanelViewController();
+ /**
+ * Creates a LockscreenLockIconController.
+ */
+ @StatusBarScope
+ LockscreenLockIconController getLockscreenLockIconController();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 26e19596b577..9e9533d0e199 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -77,7 +77,6 @@ import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import com.android.systemui.statusbar.phone.KeyguardLiftController;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.LightsOutNotifController;
-import com.android.systemui.statusbar.phone.LockscreenLockIconController;
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
@@ -167,7 +166,6 @@ public interface StatusBarPhoneModule {
Lazy<AssistManager> assistManagerLazy,
ConfigurationController configurationController,
NotificationShadeWindowController notificationShadeWindowController,
- LockscreenLockIconController lockscreenLockIconController,
DozeParameters dozeParameters,
ScrimController scrimController,
@Nullable KeyguardLiftController keyguardLiftController,
@@ -248,7 +246,6 @@ public interface StatusBarPhoneModule {
assistManagerLazy,
configurationController,
notificationShadeWindowController,
- lockscreenLockIconController,
dozeParameters,
scrimController,
keyguardLiftController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index 37d8c9ae2958..781abe6cef3e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -16,6 +16,10 @@
package com.android.systemui.statusbar.phone.dagger;
+import android.annotation.Nullable;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.LockIcon;
import com.android.systemui.statusbar.phone.NotificationPanelView;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
@@ -32,4 +36,12 @@ public abstract class StatusBarViewModule {
return notificationShadeWindowView.getNotificationPanelView();
}
+ /** */
+ @Provides
+ @StatusBarComponent.StatusBarScope
+ @Nullable
+ public static LockIcon getLockIcon(
+ NotificationShadeWindowView notificationShadeWindowView) {
+ return notificationShadeWindowView.findViewById(R.id.lock_icon);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
index 9762ffffb02e..eb5dd4e6fef6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
@@ -72,7 +72,7 @@ class PrivacyDialogTest : SysuiTestCase() {
)
dialog = PrivacyDialog(context, list, starter)
dialog.show()
- dialog.requireViewById<View>(R.id.link).callOnClick()
+ dialog.requireViewById<View>(R.id.privacy_item).callOnClick()
verify(starter).invoke(PrivacyType.TYPE_MICROPHONE.permGroupName)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index 23c093033ae0..bdde82289e86 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -88,7 +88,6 @@ public class DozeServiceHostTest extends SysuiTestCase {
@Mock private NotificationPanelViewController mNotificationPanel;
@Mock private View mAmbientIndicationContainer;
@Mock private BiometricUnlockController mBiometricUnlockController;
- @Mock private LockscreenLockIconController mLockscreenLockIconController;
@Mock private AuthController mAuthController;
@Before
@@ -100,7 +99,7 @@ public class DozeServiceHostTest extends SysuiTestCase {
mKeyguardViewMediator, () -> mAssistManager, mDozeScrimController,
mKeyguardUpdateMonitor, mPulseExpansionHandler,
mNotificationShadeWindowController, mNotificationWakeUpCoordinator,
- mLockscreenLockIconController, mAuthController, mNotificationIconAreaController);
+ mAuthController, mNotificationIconAreaController);
mDozeServiceHost.initialize(
mStatusBar,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenIconControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenIconControllerTest.java
index 95a35050c09e..60af16acbb7e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenIconControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenIconControllerTest.java
@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.phone;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -30,12 +29,12 @@ import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardSecurityModel;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dock.DockManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.policy.AccessibilityController;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -45,6 +44,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -64,7 +64,7 @@ public class LockscreenIconControllerTest extends SysuiTestCase {
@Mock
private KeyguardIndicationController mKeyguardIndicationController;
@Mock
- private LockIcon mLockIcon; // TODO: make this not a mock once inject is removed.
+ private LockIcon mLockIcon;
@Mock
private StatusBarStateController mStatusBarStateController;
@Mock
@@ -81,34 +81,36 @@ public class LockscreenIconControllerTest extends SysuiTestCase {
private Resources mResources;
@Mock
private HeadsUpManagerPhone mHeadsUpManagerPhone;
- @Mock
- private KeyguardSecurityModel mKeyguardSecurityModel;
private LockscreenLockIconController mLockIconController;
+
+ @Captor ArgumentCaptor<OnAttachStateChangeListener> mOnAttachStateChangeCaptor;
+ @Captor ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerCaptor;
+
private OnAttachStateChangeListener mOnAttachStateChangeListener;
+ private StatusBarStateController.StateListener mStatusBarStateListener;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- when(mKeyguardUpdateMonitor.shouldShowLockIcon()).thenReturn(true);
+ when(mKeyguardUpdateMonitor.canShowLockIcon()).thenReturn(true);
when(mLockIcon.getContext()).thenReturn(mContext);
- mLockIconController = new LockscreenLockIconController(
+ mLockIconController = new LockscreenLockIconController(mLockIcon,
mLockscreenGestureLogger, mKeyguardUpdateMonitor, mLockPatternUtils,
mShadeController, mAccessibilityController, mKeyguardIndicationController,
mStatusBarStateController, mConfigurationController, mNotificationWakeUpCoordinator,
mKeyguardBypassController, mDockManager, mKeyguardStateController, mResources,
- mHeadsUpManagerPhone, mKeyguardSecurityModel);
+ mHeadsUpManagerPhone);
- ArgumentCaptor<OnAttachStateChangeListener> onAttachStateChangeListenerArgumentCaptor =
- ArgumentCaptor.forClass(OnAttachStateChangeListener.class);
+ when(mLockIcon.isAttachedToWindow()).thenReturn(true);
+ mLockIconController.init();
- doNothing().when(mLockIcon)
- .addOnAttachStateChangeListener(
- onAttachStateChangeListenerArgumentCaptor.capture());
- mLockIconController.attach(mLockIcon);
-
- mOnAttachStateChangeListener = onAttachStateChangeListenerArgumentCaptor.getValue();
+ verify(mLockIcon).addOnAttachStateChangeListener(
+ mOnAttachStateChangeCaptor.capture());
+ mOnAttachStateChangeListener = mOnAttachStateChangeCaptor.getValue();
+ verify(mStatusBarStateController).addCallback(mStateListenerCaptor.capture());
+ mStatusBarStateListener = mStateListenerCaptor.getValue();
}
@Test
@@ -133,23 +135,17 @@ public class LockscreenIconControllerTest extends SysuiTestCase {
@Test
public void testVisibility_Dozing() {
- ArgumentCaptor<StatusBarStateController.StateListener> sBStateListenerCaptor =
- ArgumentCaptor.forClass(StatusBarStateController.StateListener.class);
-
- mOnAttachStateChangeListener.onViewAttachedToWindow(mLockIcon);
- verify(mStatusBarStateController).addCallback(sBStateListenerCaptor.capture());
-
when(mStatusBarStateController.isDozing()).thenReturn(true);
- sBStateListenerCaptor.getValue().onDozingChanged(true);
+ mStatusBarStateListener.onDozingChanged(true);
verify(mLockIcon).updateIconVisibility(false);
}
@Test
public void testVisibility_doNotShowLockIcon() {
- when(mKeyguardUpdateMonitor.shouldShowLockIcon()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.canShowLockIcon()).thenReturn(false);
+ mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
- mOnAttachStateChangeListener.onViewAttachedToWindow(mLockIcon);
verify(mLockIcon).setVisibility(View.GONE);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 2c781bad10c2..cae488a561a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -386,7 +386,6 @@ public class StatusBarTest extends SysuiTestCase {
() -> mAssistManager,
configurationController,
mNotificationShadeWindowController,
- mLockscreenLockIconController,
mDozeParameters,
mScrimController,
mKeyguardLiftController,
@@ -436,6 +435,7 @@ public class StatusBarTest extends SysuiTestCase {
// initialized automatically.
mStatusBar.mNotificationShadeWindowView = mNotificationShadeWindowView;
mStatusBar.mNotificationPanelViewController = mNotificationPanelViewController;
+ mStatusBar.mLockscreenLockIconController = mLockscreenLockIconController;
mStatusBar.mDozeScrimController = mDozeScrimController;
mStatusBar.mPresenter = mNotificationPresenter;
mStatusBar.mKeyguardIndicationController = mKeyguardIndicationController;
diff --git a/services/core/java/com/android/server/wm/CompatModePackages.java b/services/core/java/com/android/server/wm/CompatModePackages.java
index dbad8b364270..a725dd34fbf6 100644
--- a/services/core/java/com/android/server/wm/CompatModePackages.java
+++ b/services/core/java/com/android/server/wm/CompatModePackages.java
@@ -24,6 +24,9 @@ import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
import android.app.ActivityManager;
import android.app.AppGlobals;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.Disabled;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.res.CompatibilityInfo;
@@ -32,6 +35,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.AtomicFile;
import android.util.Slog;
import android.util.SparseArray;
@@ -63,6 +67,58 @@ public final class CompatModePackages {
// Compatibility state: compatibility mode is enabled.
private static final int COMPAT_FLAG_ENABLED = 1<<1;
+ /**
+ * CompatModePackages#DOWNSCALED is the gatekeeper of all per-app buffer downscaling
+ * changes. Disabling this change will prevent the following scaling factors from working:
+ * CompatModePackages#DOWNSCALE_87_5
+ * CompatModePackages#DOWNSCALE_75
+ * CompatModePackages#DOWNSCALE_62_5
+ * CompatModePackages#DOWNSCALE_50
+ *
+ * If CompatModePackages#DOWNSCALED is enabled for an app package, then the app will be forcibly
+ * resized to the highest enabled scaling factor e.g. 87.5% if both 87.5% and 75% were
+ * enabled.
+ */
+ @ChangeId
+ @Disabled
+ private static final long DOWNSCALED = 168419799L;
+
+ /**
+ * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
+ * CompatModePackages#DOWNSCALE_87_5 for a package will force the app to assume it's
+ * running on a display with 87.5% the vertical and horizontal resolution of the real display.
+ */
+ @ChangeId
+ @Disabled
+ private static final long DOWNSCALE_87_5 = 176926753L;
+
+ /**
+ * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
+ * CompatModePackages#DOWNSCALE_75 for a package will force the app to assume it's
+ * running on a display with 75% the vertical and horizontal resolution of the real display.
+ */
+ @ChangeId
+ @Disabled
+ private static final long DOWNSCALE_75 = 176926829L;
+
+ /**
+ * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
+ * CompatModePackages#DOWNSCALE_62_5 for a package will force the app to assume it's
+ * running on a display with 62.5% the vertical and horizontal resolution of the real display.
+ */
+ @ChangeId
+ @Disabled
+ private static final long DOWNSCALE_62_5 = 176926771L;
+
+ /**
+ * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
+ * CompatModePackages#DOWNSCALE_50 for a package will force the app to assume it's
+ * running on a display with 50% vertical and horizontal resolution of the real display.
+ */
+ @ChangeId
+ @Disabled
+ private static final long DOWNSCALE_50 = 176926741L;
+
private final HashMap<String, Integer> mPackages = new HashMap<String, Integer>();
private static final int MSG_WRITE = 300;
@@ -191,11 +247,39 @@ public final class CompatModePackages {
mHandler.sendMessageDelayed(msg, 10000);
}
+ float getCompatScale(String packageName, int uid) {
+ if (!CompatChanges.isChangeEnabled(
+ DOWNSCALED, packageName, UserHandle.getUserHandleForUid(uid))) {
+ return 1f;
+ }
+ if (CompatChanges.isChangeEnabled(
+ DOWNSCALE_87_5, packageName, UserHandle.getUserHandleForUid(uid))) {
+ // 8/7 == (1 / 0.875) ~= 1.14285714286
+ return 8f / 7f;
+ }
+ if (CompatChanges.isChangeEnabled(
+ DOWNSCALE_75, packageName, UserHandle.getUserHandleForUid(uid))) {
+ // 4/3 == (1 / 0.75) ~= 1.333333333
+ return 4f / 3f;
+ }
+ if (CompatChanges.isChangeEnabled(
+ DOWNSCALE_62_5, packageName, UserHandle.getUserHandleForUid(uid))) {
+ // (1 / 0.625) == 1.6
+ return 1.6f;
+ }
+ if (CompatChanges.isChangeEnabled(
+ DOWNSCALE_50, packageName, UserHandle.getUserHandleForUid(uid))) {
+ return 2f;
+ }
+ return 1f;
+ }
+
public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
final Configuration globalConfig = mService.getGlobalConfiguration();
+ final float requestedScale = getCompatScale(ai.packageName, ai.uid);
CompatibilityInfo ci = new CompatibilityInfo(ai, globalConfig.screenLayout,
globalConfig.smallestScreenWidthDp,
- (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0);
+ (getPackageFlags(ai.packageName) & COMPAT_FLAG_ENABLED) != 0, requestedScale);
//Slog.i(TAG, "*********** COMPAT FOR PKG " + ai.packageName + ": " + ci);
return ci;
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index f2be5ffb2ab2..025037688c8c 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -441,6 +441,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
float mGlobalScale=1;
float mLastGlobalScale=1;
float mInvGlobalScale=1;
+ float mOverrideScale = 1;
float mHScale=1, mVScale=1;
float mLastHScale=1, mLastVScale=1;
final Matrix mTmpMatrix = new Matrix();
@@ -1014,6 +1015,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mLastRequestedWidth = 0;
mLastRequestedHeight = 0;
mLayer = 0;
+ mOverrideScale = mWmService.mAtmService.mCompatModePackages.getCompatScale(
+ mAttrs.packageName, s.mUid);
// Make sure we initial all fields before adding to parentWindow, to prevent exception
// during onDisplayChanged.
@@ -1046,8 +1049,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mSession.windowAddedLocked(mAttrs.packageName);
}
+ /**
+ * @return {@code true} if the application runs in size compatibility mode or has an app level
+ * scaling override set.
+ * @see CompatModePackages#getCompatScale
+ * @see android.content.res.CompatibilityInfo#supportsScreen
+ * @see ActivityRecord#inSizeCompatMode()
+ */
boolean inSizeCompatMode() {
- return inSizeCompatMode(mAttrs, mActivityRecord);
+ return mOverrideScale != 1f || inSizeCompatMode(mAttrs, mActivityRecord);
}
/**
@@ -1682,7 +1692,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
void prelayout() {
if (inSizeCompatMode()) {
- mGlobalScale = mToken.getSizeCompatScale();
+ if (mOverrideScale != 1f) {
+ mGlobalScale = mToken.hasSizeCompatBounds()
+ ? mToken.getSizeCompatScale() * mOverrideScale
+ : mOverrideScale;
+ } else {
+ mGlobalScale = mToken.getSizeCompatScale();
+ }
mInvGlobalScale = 1 / mGlobalScale;
} else {
mGlobalScale = mInvGlobalScale = 1;
@@ -2640,8 +2656,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// scaling but the existing logic doesn't expect that. The result is that the already-
// scaled region ends up getting sent to surfaceflinger which then applies the scale
// (again). Until this is resolved, apply an inverse-scale here.
- if (mActivityRecord != null && mActivityRecord.hasSizeCompatBounds()
- && mGlobalScale != 1.f) {
+ if (mInvGlobalScale != 1.f) {
region.scale(mInvGlobalScale);
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
index ba12fbed2b2f..6b6d21bc6e54 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -21,9 +21,12 @@ import com.android.server.wm.flicker.dsl.EventLogAssertionBuilder
import com.android.server.wm.flicker.dsl.LayersAssertionBuilder
import com.android.server.wm.flicker.dsl.WmAssertionBuilder
import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.NAV_BAR_LAYER_NAME
+import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.NAV_BAR_WINDOW_NAME
+import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.STATUS_BAR_LAYER_NAME
+import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.STATUS_BAR_WINDOW_NAME
-const val NAVIGATION_BAR_WINDOW_TITLE = "NavigationBar"
-const val STATUS_BAR_WINDOW_TITLE = "StatusBar"
+const val APP_PAIR_SPLIT_DIVIDER = "AppPairSplitDivider"
const val DOCKED_STACK_DIVIDER = "DockedStackDivider"
const val WALLPAPER_TITLE = "Wallpaper"
@@ -33,7 +36,7 @@ fun WmAssertionBuilder.statusBarWindowIsAlwaysVisible(
enabled: Boolean = bugId == 0
) {
all("statusBarWindowIsAlwaysVisible", bugId, enabled) {
- this.showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE)
+ this.showsAboveAppWindow(STATUS_BAR_WINDOW_NAME)
}
}
@@ -43,7 +46,7 @@ fun WmAssertionBuilder.navBarWindowIsAlwaysVisible(
enabled: Boolean = bugId == 0
) {
all("navBarWindowIsAlwaysVisible", bugId, enabled) {
- this.showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE)
+ this.showsAboveAppWindow(NAV_BAR_WINDOW_NAME)
}
}
@@ -113,6 +116,18 @@ fun WmAssertionBuilder.appWindowBecomesVisible(
}
}
+fun WmAssertionBuilder.appWindowBecomesInVisible(
+ appName: String,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("appWindowBecomesInVisible", bugId, enabled) {
+ this.showsAppWindow(appName)
+ .then()
+ .hidesAppWindow(appName)
+ }
+}
+
@JvmOverloads
fun LayersAssertionBuilder.noUncoveredRegions(
beginRotation: Int,
@@ -151,15 +166,15 @@ fun LayersAssertionBuilder.navBarLayerIsAlwaysVisible(
) {
if (rotatesScreen) {
all("navBarLayerIsAlwaysVisible", bugId, enabled) {
- this.showsLayer(NAVIGATION_BAR_WINDOW_TITLE)
+ this.showsLayer(NAV_BAR_LAYER_NAME)
.then()
- .hidesLayer(NAVIGATION_BAR_WINDOW_TITLE)
+ .hidesLayer(NAV_BAR_LAYER_NAME)
.then()
- .showsLayer(NAVIGATION_BAR_WINDOW_TITLE)
+ .showsLayer(NAV_BAR_LAYER_NAME)
}
} else {
all("navBarLayerIsAlwaysVisible", bugId, enabled) {
- this.showsLayer(NAVIGATION_BAR_WINDOW_TITLE)
+ this.showsLayer(NAV_BAR_LAYER_NAME)
}
}
}
@@ -172,15 +187,15 @@ fun LayersAssertionBuilder.statusBarLayerIsAlwaysVisible(
) {
if (rotatesScreen) {
all("statusBarLayerIsAlwaysVisible", bugId, enabled) {
- this.showsLayer(STATUS_BAR_WINDOW_TITLE)
+ this.showsLayer(STATUS_BAR_LAYER_NAME)
.then()
- hidesLayer(STATUS_BAR_WINDOW_TITLE)
+ hidesLayer(STATUS_BAR_LAYER_NAME)
.then()
- .showsLayer(STATUS_BAR_WINDOW_TITLE)
+ .showsLayer(STATUS_BAR_LAYER_NAME)
}
} else {
all("statusBarLayerIsAlwaysVisible", bugId, enabled) {
- this.showsLayer(STATUS_BAR_WINDOW_TITLE)
+ this.showsLayer(STATUS_BAR_LAYER_NAME)
}
}
}
@@ -196,15 +211,15 @@ fun LayersAssertionBuilder.navBarLayerRotatesAndScales(
val endingPos = WindowUtils.getNavigationBarPosition(endRotation)
start("navBarLayerRotatesAndScales_StartingPos", bugId, enabled) {
- this.hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
+ this.hasVisibleRegion(NAV_BAR_LAYER_NAME, startingPos)
}
end("navBarLayerRotatesAndScales_EndingPost", bugId, enabled) {
- this.hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, endingPos)
+ this.hasVisibleRegion(NAV_BAR_LAYER_NAME, endingPos)
}
if (startingPos == endingPos) {
all("navBarLayerRotatesAndScales", enabled = false, bugId = 167747321) {
- this.hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
+ this.hasVisibleRegion(NAV_BAR_LAYER_NAME, startingPos)
}
}
}
@@ -220,10 +235,10 @@ fun LayersAssertionBuilder.statusBarLayerRotatesScales(
val endingPos = WindowUtils.getStatusBarPosition(endRotation)
start("statusBarLayerRotatesScales_StartingPos", bugId, enabled) {
- this.hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, startingPos)
+ this.hasVisibleRegion(STATUS_BAR_LAYER_NAME, startingPos)
}
end("statusBarLayerRotatesScales_EndingPos", bugId, enabled) {
- this.hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, endingPos)
+ this.hasVisibleRegion(STATUS_BAR_LAYER_NAME, endingPos)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerExtensions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerExtensions.kt
index b569edac1a95..1a4744980b1e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerExtensions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerExtensions.kt
@@ -41,6 +41,9 @@ fun Flicker.setRotation(rotation: Int) {
wmHelper.waitForRotation(rotation)
wmHelper.waitForNavBarStatusBarVisible()
wmHelper.waitForAppTransitionIdle()
+
+ // Ensure WindowManagerService wait until all animations have completed
+ instrumentation.getUiAutomation().syncInputTransactions()
} catch (e: RemoteException) {
throw RuntimeException(e)
}
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index f6a2846c9b3c..e630da04a512 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -53,6 +53,7 @@ android_test {
jarjar_rules: "jarjar-rules.txt",
static_libs: [
"androidx.test.rules",
+ "bouncycastle-repackaged-unbundled",
"FrameworksNetCommonTests",
"frameworks-base-testutils",
"frameworks-net-integration-testutils",
diff --git a/tests/net/java/android/net/Ikev2VpnProfileTest.java b/tests/net/java/android/net/Ikev2VpnProfileTest.java
index 076e41d33a8d..1abd39a32bdf 100644
--- a/tests/net/java/android/net/Ikev2VpnProfileTest.java
+++ b/tests/net/java/android/net/Ikev2VpnProfileTest.java
@@ -30,7 +30,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.internal.net.VpnProfile;
import com.android.net.module.util.ProxyUtils;
-import com.android.org.bouncycastle.x509.X509V1CertificateGenerator;
+import com.android.internal.org.bouncycastle.x509.X509V1CertificateGenerator;
import org.junit.Before;
import org.junit.Test;