diff options
53 files changed, 1150 insertions, 557 deletions
diff --git a/api/OWNERS b/api/OWNERS index a0272709ffc0..4d8ed0347f43 100644 --- a/api/OWNERS +++ b/api/OWNERS @@ -4,3 +4,6 @@ hansson@google.com file:platform/packages/modules/common:/OWNERS per-file Android.bp = file:platform/build/soong:/OWNERS + +# For metalava team to disable lint checks in platform +per-file Android.bp = aurimas@google.com,emberrose@google.com,sjgilbert@google.com
\ No newline at end of file diff --git a/core/api/current.txt b/core/api/current.txt index 67a544ce4059..894910d3bf89 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -11874,6 +11874,7 @@ package android.content.pm { field public static final String FEATURE_SENSOR_GYROSCOPE = "android.hardware.sensor.gyroscope"; field public static final String FEATURE_SENSOR_GYROSCOPE_LIMITED_AXES = "android.hardware.sensor.gyroscope_limited_axes"; field public static final String FEATURE_SENSOR_GYROSCOPE_LIMITED_AXES_UNCALIBRATED = "android.hardware.sensor.gyroscope_limited_axes_uncalibrated"; + field public static final String FEATURE_SENSOR_HEADING = "android.hardware.sensor.heading"; field public static final String FEATURE_SENSOR_HEART_RATE = "android.hardware.sensor.heartrate"; field public static final String FEATURE_SENSOR_HEART_RATE_ECG = "android.hardware.sensor.heartrate.ecg"; field public static final String FEATURE_SENSOR_HINGE_ANGLE = "android.hardware.sensor.hinge_angle"; @@ -11894,6 +11895,7 @@ package android.content.pm { field public static final String FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma"; field public static final String FEATURE_TELEPHONY_DATA = "android.hardware.telephony.data"; field public static final String FEATURE_TELEPHONY_EUICC = "android.hardware.telephony.euicc"; + field public static final String FEATURE_TELEPHONY_EUICC_MEP = "android.hardware.telephony.euicc.mep"; field public static final String FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm"; field public static final String FEATURE_TELEPHONY_IMS = "android.hardware.telephony.ims"; field public static final String FEATURE_TELEPHONY_MBMS = "android.hardware.telephony.mbms"; @@ -15476,7 +15478,7 @@ package android.graphics { ctor public SurfaceTexture(boolean); method public void attachToGLContext(int); method public void detachFromGLContext(); - method public long getDataSpace(); + method public int getDataSpace(); method public long getTimestamp(); method public void getTransformMatrix(float[]); method public boolean isReleased(); @@ -16711,49 +16713,49 @@ package android.hardware { } public final class DataSpace { - method public static long getRange(long); - method public static long getStandard(long); - method public static long getTransfer(long); - method public static long pack(long, long, long); - field public static final long DATASPACE_ADOBE_RGB = 151715840L; // 0x90b0000L - field public static final long DATASPACE_BT2020 = 147193856L; // 0x8c60000L - field public static final long DATASPACE_BT2020_PQ = 163971072L; // 0x9c60000L - field public static final long DATASPACE_BT601_525 = 281280512L; // 0x10c40000L - field public static final long DATASPACE_BT601_625 = 281149440L; // 0x10c20000L - field public static final long DATASPACE_BT709 = 281083904L; // 0x10c10000L - field public static final long DATASPACE_DCI_P3 = 155844608L; // 0x94a0000L - field public static final long DATASPACE_DISPLAY_P3 = 143261696L; // 0x88a0000L - field public static final long DATASPACE_JFIF = 146931712L; // 0x8c20000L - field public static final long DATASPACE_SCRGB = 411107328L; // 0x18810000L - field public static final long DATASPACE_SCRGB_LINEAR = 406913024L; // 0x18410000L - field public static final long DATASPACE_SRGB = 142671872L; // 0x8810000L - field public static final long DATASPACE_SRGB_LINEAR = 138477568L; // 0x8410000L - field public static final long DATASPACE_UNKNOWN = 0L; // 0x0L - field public static final long RANGE_EXTENDED = 402653184L; // 0x18000000L - field public static final long RANGE_FULL = 134217728L; // 0x8000000L - field public static final long RANGE_LIMITED = 268435456L; // 0x10000000L - field public static final long RANGE_UNSPECIFIED = 0L; // 0x0L - field public static final long STANDARD_ADOBE_RGB = 720896L; // 0xb0000L - field public static final long STANDARD_BT2020 = 393216L; // 0x60000L - field public static final long STANDARD_BT2020_CONSTANT_LUMINANCE = 458752L; // 0x70000L - field public static final long STANDARD_BT470M = 524288L; // 0x80000L - field public static final long STANDARD_BT601_525 = 262144L; // 0x40000L - field public static final long STANDARD_BT601_525_UNADJUSTED = 327680L; // 0x50000L - field public static final long STANDARD_BT601_625 = 131072L; // 0x20000L - field public static final long STANDARD_BT601_625_UNADJUSTED = 196608L; // 0x30000L - field public static final long STANDARD_BT709 = 65536L; // 0x10000L - field public static final long STANDARD_DCI_P3 = 655360L; // 0xa0000L - field public static final long STANDARD_FILM = 589824L; // 0x90000L - field public static final long STANDARD_UNSPECIFIED = 0L; // 0x0L - field public static final long TRANSFER_GAMMA2_2 = 16777216L; // 0x1000000L - field public static final long TRANSFER_GAMMA2_6 = 20971520L; // 0x1400000L - field public static final long TRANSFER_GAMMA2_8 = 25165824L; // 0x1800000L - field public static final long TRANSFER_HLG = 33554432L; // 0x2000000L - field public static final long TRANSFER_LINEAR = 4194304L; // 0x400000L - field public static final long TRANSFER_SMPTE_170M = 12582912L; // 0xc00000L - field public static final long TRANSFER_SRGB = 8388608L; // 0x800000L - field public static final long TRANSFER_ST2084 = 29360128L; // 0x1c00000L - field public static final long TRANSFER_UNSPECIFIED = 0L; // 0x0L + method public static int getRange(int); + method public static int getStandard(int); + method public static int getTransfer(int); + method public static int pack(int, int, int); + field public static final int DATASPACE_ADOBE_RGB = 151715840; // 0x90b0000 + field public static final int DATASPACE_BT2020 = 147193856; // 0x8c60000 + field public static final int DATASPACE_BT2020_PQ = 163971072; // 0x9c60000 + field public static final int DATASPACE_BT601_525 = 281280512; // 0x10c40000 + field public static final int DATASPACE_BT601_625 = 281149440; // 0x10c20000 + field public static final int DATASPACE_BT709 = 281083904; // 0x10c10000 + field public static final int DATASPACE_DCI_P3 = 155844608; // 0x94a0000 + field public static final int DATASPACE_DISPLAY_P3 = 143261696; // 0x88a0000 + field public static final int DATASPACE_JFIF = 146931712; // 0x8c20000 + field public static final int DATASPACE_SCRGB = 411107328; // 0x18810000 + field public static final int DATASPACE_SCRGB_LINEAR = 406913024; // 0x18410000 + field public static final int DATASPACE_SRGB = 142671872; // 0x8810000 + field public static final int DATASPACE_SRGB_LINEAR = 138477568; // 0x8410000 + field public static final int DATASPACE_UNKNOWN = 0; // 0x0 + field public static final int RANGE_EXTENDED = 402653184; // 0x18000000 + field public static final int RANGE_FULL = 134217728; // 0x8000000 + field public static final int RANGE_LIMITED = 268435456; // 0x10000000 + field public static final int RANGE_UNSPECIFIED = 0; // 0x0 + field public static final int STANDARD_ADOBE_RGB = 720896; // 0xb0000 + field public static final int STANDARD_BT2020 = 393216; // 0x60000 + field public static final int STANDARD_BT2020_CONSTANT_LUMINANCE = 458752; // 0x70000 + field public static final int STANDARD_BT470M = 524288; // 0x80000 + field public static final int STANDARD_BT601_525 = 262144; // 0x40000 + field public static final int STANDARD_BT601_525_UNADJUSTED = 327680; // 0x50000 + field public static final int STANDARD_BT601_625 = 131072; // 0x20000 + field public static final int STANDARD_BT601_625_UNADJUSTED = 196608; // 0x30000 + field public static final int STANDARD_BT709 = 65536; // 0x10000 + field public static final int STANDARD_DCI_P3 = 655360; // 0xa0000 + field public static final int STANDARD_FILM = 589824; // 0x90000 + field public static final int STANDARD_UNSPECIFIED = 0; // 0x0 + field public static final int TRANSFER_GAMMA2_2 = 16777216; // 0x1000000 + field public static final int TRANSFER_GAMMA2_6 = 20971520; // 0x1400000 + field public static final int TRANSFER_GAMMA2_8 = 25165824; // 0x1800000 + field public static final int TRANSFER_HLG = 33554432; // 0x2000000 + field public static final int TRANSFER_LINEAR = 4194304; // 0x400000 + field public static final int TRANSFER_SMPTE_170M = 12582912; // 0xc00000 + field public static final int TRANSFER_SRGB = 8388608; // 0x800000 + field public static final int TRANSFER_ST2084 = 29360128; // 0x1c00000 + field public static final int TRANSFER_UNSPECIFIED = 0; // 0x0 } public class GeomagneticField { @@ -18166,14 +18168,21 @@ package android.hardware.camera2.params { method @Nullable public android.view.Surface getSurface(); method public int getSurfaceGroupId(); method @NonNull public java.util.List<android.view.Surface> getSurfaces(); + method public int getTimestampBase(); method public void removeSensorPixelModeUsed(int); method public void removeSurface(@NonNull android.view.Surface); method public void setDynamicRangeProfile(int); method public void setPhysicalCameraId(@Nullable String); method public void setStreamUseCase(int); + method public void setTimestampBase(int); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR; field public static final int SURFACE_GROUP_ID_NONE = -1; // 0xffffffff + field public static final int TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED = 4; // 0x4 + field public static final int TIMESTAMP_BASE_DEFAULT = 0; // 0x0 + field public static final int TIMESTAMP_BASE_MONOTONIC = 2; // 0x2 + field public static final int TIMESTAMP_BASE_REALTIME = 3; // 0x3 + field public static final int TIMESTAMP_BASE_SENSOR = 1; // 0x1 } public final class RecommendedStreamConfigurationMap { @@ -20853,7 +20862,7 @@ package android.media { public abstract class Image implements java.lang.AutoCloseable { method public abstract void close(); method public android.graphics.Rect getCropRect(); - method public long getDataSpace(); + method public int getDataSpace(); method @NonNull public android.hardware.SyncFence getFence() throws java.io.IOException; method public abstract int getFormat(); method @Nullable public android.hardware.HardwareBuffer getHardwareBuffer(); @@ -20862,7 +20871,7 @@ package android.media { method public abstract long getTimestamp(); method public abstract int getWidth(); method public void setCropRect(android.graphics.Rect); - method public void setDataSpace(long); + method public void setDataSpace(int); method public void setFence(@NonNull android.hardware.SyncFence) throws java.io.IOException; method public void setTimestamp(long); } @@ -20878,7 +20887,7 @@ package android.media { method public android.media.Image acquireNextImage(); method public void close(); method public void discardFreeBuffers(); - method public long getDataSpace(); + method public int getDataSpace(); method public int getHardwareBufferFormat(); method public int getHeight(); method public int getImageFormat(); @@ -20894,7 +20903,7 @@ package android.media { public static final class ImageReader.Builder { ctor public ImageReader.Builder(@IntRange(from=1) int, @IntRange(from=1) int); method @NonNull public android.media.ImageReader build(); - method @NonNull public android.media.ImageReader.Builder setDefaultDataSpace(long); + method @NonNull public android.media.ImageReader.Builder setDefaultDataSpace(int); method @NonNull public android.media.ImageReader.Builder setDefaultHardwareBufferFormat(int); method @NonNull public android.media.ImageReader.Builder setImageFormat(int); method @NonNull public android.media.ImageReader.Builder setMaxImages(int); @@ -20908,7 +20917,7 @@ package android.media { public class ImageWriter implements java.lang.AutoCloseable { method public void close(); method public android.media.Image dequeueInputImage(); - method public long getDataSpace(); + method public int getDataSpace(); method public int getFormat(); method public int getHardwareBufferFormat(); method public int getHeight(); @@ -20924,7 +20933,7 @@ package android.media { public static final class ImageWriter.Builder { ctor public ImageWriter.Builder(@NonNull android.view.Surface); method @NonNull public android.media.ImageWriter build(); - method @NonNull public android.media.ImageWriter.Builder setDataSpace(long); + method @NonNull public android.media.ImageWriter.Builder setDataSpace(int); method @NonNull public android.media.ImageWriter.Builder setHardwareBufferFormat(int); method @NonNull public android.media.ImageWriter.Builder setImageFormat(int); method @NonNull public android.media.ImageWriter.Builder setMaxImages(@IntRange(from=1) int); @@ -41026,6 +41035,7 @@ package android.telephony { field public static final String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool"; field public static final String KEY_CARRIER_SUPPORTS_OPP_DATA_AUTO_PROVISIONING_BOOL = "carrier_supports_opp_data_auto_provisioning_bool"; field public static final String KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL = "carrier_supports_ss_over_ut_bool"; + field public static final String KEY_CARRIER_SUPPORTS_TETHERING_BOOL = "carrier_supports_tethering_bool"; field public static final String KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL = "carrier_use_ims_first_for_emergency_bool"; field public static final String KEY_CARRIER_USSD_METHOD_INT = "carrier_ussd_method_int"; field @Deprecated public static final String KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL = "carrier_ut_provisioning_required_bool"; @@ -49125,6 +49135,7 @@ package android.view { method @NonNull public android.view.SurfaceControl.Transaction setBufferTransform(@NonNull android.view.SurfaceControl, int); method @NonNull public android.view.SurfaceControl.Transaction setCrop(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Rect); method @NonNull public android.view.SurfaceControl.Transaction setDamageRegion(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Region); + method @NonNull public android.view.SurfaceControl.Transaction setDataSpace(@NonNull android.view.SurfaceControl, int); method @NonNull public android.view.SurfaceControl.Transaction setFrameRate(@NonNull android.view.SurfaceControl, @FloatRange(from=0.0) float, int); method @NonNull public android.view.SurfaceControl.Transaction setFrameRate(@NonNull android.view.SurfaceControl, @FloatRange(from=0.0) float, int, int); method @NonNull public android.view.SurfaceControl.Transaction setGeometry(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Rect, @Nullable android.graphics.Rect, int); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 9aebb206ed0b..ce549c380af8 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -75,6 +75,7 @@ import android.os.storage.StorageManager; import android.os.storage.VolumeInfo; import android.permission.PermissionManager; import android.telephony.TelephonyManager; +import android.telephony.UiccCardInfo; import android.telephony.gba.GbaService; import android.telephony.ims.ImsService; import android.telephony.ims.ProvisioningManager; @@ -3185,6 +3186,13 @@ public abstract class PackageManager { @SdkConstant(SdkConstantType.FEATURE) public static final String FEATURE_SENSOR_HINGE_ANGLE = "android.hardware.sensor.hinge_angle"; + /** + * Feature for {@link #getSystemAvailableFeatures} and + * {@link #hasSystemFeature}: The device includes a heading sensor. + */ + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_SENSOR_HEADING = "android.hardware.sensor.heading"; + /** * Feature for {@link #getSystemAvailableFeatures} and * {@link #hasSystemFeature}: The device supports exposing head tracker sensors from peripheral @@ -3266,6 +3274,20 @@ public abstract class PackageManager { /** * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device + * supports multiple enabled profiles on eUICCs. + * + * <p>Devices declaring this feature must have an implementation of the + * {@link UiccCardInfo#getPorts}, + * {@link UiccCardInfo#isMultipleEnabledProfilesSupported} and + * {@link android.telephony.euicc.EuiccManager#switchToSubscription (with portIndex)}. + * + * This feature should only be defined if {@link #FEATURE_TELEPHONY_EUICC} have been defined. + */ + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_TELEPHONY_EUICC_MEP = "android.hardware.telephony.euicc.mep"; + + /** + * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device * supports cell-broadcast reception using the MBMS APIs. * * <p>This feature should only be defined if both {@link #FEATURE_TELEPHONY_SUBSCRIPTION} diff --git a/core/java/android/hardware/DataSpace.java b/core/java/android/hardware/DataSpace.java index 65383c54e2b6..4411918db1ad 100644 --- a/core/java/android/hardware/DataSpace.java +++ b/core/java/android/hardware/DataSpace.java @@ -15,7 +15,7 @@ */ package android.hardware; -import android.annotation.LongDef; +import android.annotation.IntDef; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -62,7 +62,7 @@ import java.lang.annotation.RetentionPolicy; public final class DataSpace { /** @hide */ @Retention(RetentionPolicy.SOURCE) - @LongDef(flag = true, value = { + @IntDef(flag = true, value = { STANDARD_UNSPECIFIED, STANDARD_BT709, STANDARD_BT601_625, @@ -78,12 +78,12 @@ public final class DataSpace { }) public @interface DataSpaceStandard {}; - private static final long STANDARD_MASK = 63 << 16; + private static final int STANDARD_MASK = 63 << 16; /** * Chromacity coordinates are unknown or are determined by the application. */ - public static final long STANDARD_UNSPECIFIED = 0 << 16; + public static final int STANDARD_UNSPECIFIED = 0 << 16; /** * Use the unadjusted {@code KR = 0.2126}, {@code KB = 0.0722} luminance interpretation * for RGB conversion. @@ -95,7 +95,7 @@ public final class DataSpace { * red 0.640 0.330 * white (D65) 0.3127 0.3290 </pre> */ - public static final long STANDARD_BT709 = 1 << 16; + public static final int STANDARD_BT709 = 1 << 16; /** * Use the adjusted {@code KR = 0.299}, {@code KB = 0.114} luminance interpretation * for RGB conversion from the one purely determined by the primaries @@ -109,7 +109,7 @@ public final class DataSpace { * red 0.640 0.330 * white (D65) 0.3127 0.3290 </pre> */ - public static final long STANDARD_BT601_625 = 2 << 16; + public static final int STANDARD_BT601_625 = 2 << 16; /** * Use the unadjusted {@code KR = 0.222}, {@code KB = 0.071} luminance interpretation * for RGB conversion. @@ -121,7 +121,7 @@ public final class DataSpace { * red 0.640 0.330 * white (D65) 0.3127 0.3290 </pre> */ - public static final long STANDARD_BT601_625_UNADJUSTED = 3 << 16; + public static final int STANDARD_BT601_625_UNADJUSTED = 3 << 16; /** * Use the adjusted {@code KR = 0.299}, {@code KB = 0.114} luminance interpretation * for RGB conversion from the one purely determined by the primaries @@ -135,7 +135,7 @@ public final class DataSpace { * red 0.630 0.340 * white (D65) 0.3127 0.3290 </pre> */ - public static final long STANDARD_BT601_525 = 4 << 16; + public static final int STANDARD_BT601_525 = 4 << 16; /** * Use the unadjusted {@code KR = 0.212}, {@code KB = 0.087} luminance interpretation * for RGB conversion (as in SMPTE 240M). @@ -147,7 +147,7 @@ public final class DataSpace { * red 0.630 0.340 * white (D65) 0.3127 0.3290 </pre> */ - public static final long STANDARD_BT601_525_UNADJUSTED = 5 << 16; + public static final int STANDARD_BT601_525_UNADJUSTED = 5 << 16; /** * Use the unadjusted {@code KR = 0.2627}, {@code KB = 0.0593} luminance interpretation * for RGB conversion. @@ -159,7 +159,7 @@ public final class DataSpace { * red 0.708 0.292 * white (D65) 0.3127 0.3290 </pre> */ - public static final long STANDARD_BT2020 = 6 << 16; + public static final int STANDARD_BT2020 = 6 << 16; /** * Use the unadjusted {@code KR = 0.2627}, {@code KB = 0.0593} luminance interpretation * for RGB conversion using the linear domain. @@ -171,7 +171,7 @@ public final class DataSpace { * red 0.708 0.292 * white (D65) 0.3127 0.3290 </pre> */ - public static final long STANDARD_BT2020_CONSTANT_LUMINANCE = 7 << 16; + public static final int STANDARD_BT2020_CONSTANT_LUMINANCE = 7 << 16; /** * Use the unadjusted {@code KR = 0.30}, {@code KB = 0.11} luminance interpretation * for RGB conversion. @@ -183,7 +183,7 @@ public final class DataSpace { * red 0.67 0.33 * white (C) 0.310 0.316 </pre> */ - public static final long STANDARD_BT470M = 8 << 16; + public static final int STANDARD_BT470M = 8 << 16; /** * Use the unadjusted {@code KR = 0.254}, {@code KB = 0.068} luminance interpretation * for RGB conversion. @@ -195,7 +195,7 @@ public final class DataSpace { * red 0.681 0.319 * white (C) 0.310 0.316 </pre> */ - public static final long STANDARD_FILM = 9 << 16; + public static final int STANDARD_FILM = 9 << 16; /** * SMPTE EG 432-1 and SMPTE RP 431-2. * @@ -206,7 +206,7 @@ public final class DataSpace { * red 0.680 0.320 * white (D65) 0.3127 0.3290 </pre> */ - public static final long STANDARD_DCI_P3 = 10 << 16; + public static final int STANDARD_DCI_P3 = 10 << 16; /** * Adobe RGB primaries. * @@ -217,11 +217,11 @@ public final class DataSpace { * red 0.640 0.330 * white (D65) 0.3127 0.3290 </pre> */ - public static final long STANDARD_ADOBE_RGB = 11 << 16; + public static final int STANDARD_ADOBE_RGB = 11 << 16; /** @hide */ @Retention(RetentionPolicy.SOURCE) - @LongDef(flag = true, value = { + @IntDef(flag = true, value = { TRANSFER_UNSPECIFIED, TRANSFER_LINEAR, TRANSFER_SRGB, @@ -234,13 +234,13 @@ public final class DataSpace { }) public @interface DataSpaceTransfer {}; - private static final long TRANSFER_MASK = 31 << 22; + private static final int TRANSFER_MASK = 31 << 22; /** * Transfer characteristics are unknown or are determined by the * application. */ - public static final long TRANSFER_UNSPECIFIED = 0 << 22; + public static final int TRANSFER_UNSPECIFIED = 0 << 22; /** * Linear transfer. * @@ -250,7 +250,7 @@ public final class DataSpace { * L - luminance of image 0 <= L <= 1 for conventional colorimetry * E - corresponding electrical signal}</pre> */ - public static final long TRANSFER_LINEAR = 1 << 22; + public static final int TRANSFER_LINEAR = 1 << 22; /** * sRGB transfer. * @@ -263,7 +263,7 @@ public final class DataSpace { * * Use for RGB formats. */ - public static final long TRANSFER_SRGB = 2 << 22; + public static final int TRANSFER_SRGB = 2 << 22; /** * SMPTE 170M transfer. * @@ -276,7 +276,7 @@ public final class DataSpace { * * Use for YCbCr formats. */ - public static final long TRANSFER_SMPTE_170M = 3 << 22; + public static final int TRANSFER_SMPTE_170M = 3 << 22; /** * Display gamma 2.2. * @@ -286,7 +286,7 @@ public final class DataSpace { * L - luminance of image 0 <= L <= 1 for conventional colorimetry * E - corresponding electrical signal}</pre> */ - public static final long TRANSFER_GAMMA2_2 = 4 << 22; + public static final int TRANSFER_GAMMA2_2 = 4 << 22; /** * Display gamma 2.6. * @@ -296,7 +296,7 @@ public final class DataSpace { * L - luminance of image 0 <= L <= 1 for conventional colorimetry * E - corresponding electrical signal}</pre> */ - public static final long TRANSFER_GAMMA2_6 = 5 << 22; + public static final int TRANSFER_GAMMA2_6 = 5 << 22; /** * Display gamma 2.8. * @@ -306,7 +306,7 @@ public final class DataSpace { * L - luminance of image 0 <= L <= 1 for conventional colorimetry * E - corresponding electrical signal}</pre> */ - public static final long TRANSFER_GAMMA2_8 = 6 << 22; + public static final int TRANSFER_GAMMA2_8 = 6 << 22; /** * SMPTE ST 2084 (Dolby Perceptual Quantizer). * @@ -322,7 +322,7 @@ public final class DataSpace { * L = 1 corresponds to 10000 cd/m2 * E - corresponding electrical signal}</pre> */ - public static final long TRANSFER_ST2084 = 7 << 22; + public static final int TRANSFER_ST2084 = 7 << 22; /** * ARIB STD-B67 Hybrid Log Gamma. * @@ -338,11 +338,11 @@ public final class DataSpace { * to reference white level of 100 cd/m2 * E - corresponding electrical signal}</pre> */ - public static final long TRANSFER_HLG = 8 << 22; + public static final int TRANSFER_HLG = 8 << 22; /** @hide */ @Retention(RetentionPolicy.SOURCE) - @LongDef(flag = true, value = { + @IntDef(flag = true, value = { RANGE_UNSPECIFIED, RANGE_FULL, RANGE_LIMITED, @@ -350,17 +350,17 @@ public final class DataSpace { }) public @interface DataSpaceRange {}; - private static final long RANGE_MASK = 7 << 27; + private static final int RANGE_MASK = 7 << 27; /** * Range characteristics are unknown or are determined by the application. */ - public static final long RANGE_UNSPECIFIED = 0 << 27; + public static final int RANGE_UNSPECIFIED = 0 << 27; /** * Full range uses all values for Y, Cb and Cr from * {@code 0} to {@code 2^b-1}, where b is the bit depth of the color format. */ - public static final long RANGE_FULL = 1 << 27; + public static final int RANGE_FULL = 1 << 27; /** * Limited range uses values {@code 16/256*2^b} to {@code 235/256*2^b} for Y, and * {@code 1/16*2^b} to {@code 15/16*2^b} for Cb, Cr, R, G and B, where b is the bit depth of @@ -374,7 +374,7 @@ public final class DataSpace { * Luma (Y) samples should range from 64 to 940, inclusive * Chroma (Cb, Cr) samples should range from 64 to 960, inclusive. </p> */ - public static final long RANGE_LIMITED = 2 << 27; + public static final int RANGE_LIMITED = 2 << 27; /** * Extended range is used for scRGB only. * @@ -383,11 +383,11 @@ public final class DataSpace { * color outside the sRGB gamut. [-0.5, 7.5] is the scRGB range. * Used to blend/merge multiple dataspaces on a single display.</p> */ - public static final long RANGE_EXTENDED = 3 << 27; + public static final int RANGE_EXTENDED = 3 << 27; /** @hide */ @Retention(RetentionPolicy.SOURCE) - @LongDef(flag = true, value = { + @IntDef(flag = true, value = { DATASPACE_UNKNOWN, DATASPACE_SCRGB_LINEAR, DATASPACE_SRGB, @@ -414,7 +414,7 @@ public final class DataSpace { * expected, except for a possible display gamma transform when drawn to a * screen.</p> */ - public static final long DATASPACE_UNKNOWN = 0; + public static final int DATASPACE_UNKNOWN = 0; /** * scRGB linear encoding. * @@ -429,7 +429,7 @@ public final class DataSpace { * Values beyond the range [0.0 - 1.0] would correspond to other colors * spaces and/or HDR content. */ - public static final long DATASPACE_SCRGB_LINEAR = 406913024; + public static final int DATASPACE_SCRGB_LINEAR = 406913024; /** * sRGB gamma encoding. * @@ -444,7 +444,7 @@ public final class DataSpace { * The alpha component, if present, is always stored in linear space and * is left unmodified when read or written. */ - public static final long DATASPACE_SRGB = 142671872; + public static final int DATASPACE_SRGB = 142671872; /** * scRGB gamma encoding. * @@ -460,7 +460,7 @@ public final class DataSpace { * Values beyond the range [0.0 - 1.0] would correspond to other colors * spaces and/or HDR content. */ - public static final long DATASPACE_SCRGB = 411107328; + public static final int DATASPACE_SCRGB = 411107328; /** * Display P3 encoding. * @@ -470,7 +470,7 @@ public final class DataSpace { * Transfer: TRANSFER_SRGB * Range: RANGE_FULL</pre> */ - public static final long DATASPACE_DISPLAY_P3 = 143261696; + public static final int DATASPACE_DISPLAY_P3 = 143261696; /** * ITU-R Recommendation 2020 (BT.2020) * @@ -482,7 +482,7 @@ public final class DataSpace { * Transfer: TRANSFER_ST2084 * Range: RANGE_FULL</pre> */ - public static final long DATASPACE_BT2020_PQ = 163971072; + public static final int DATASPACE_BT2020_PQ = 163971072; /** * Adobe RGB encoding. * @@ -494,7 +494,7 @@ public final class DataSpace { * * Note: Application is responsible for gamma encoding the data. */ - public static final long DATASPACE_ADOBE_RGB = 151715840; + public static final int DATASPACE_ADOBE_RGB = 151715840; /** * JPEG File Interchange Format (JFIF). * @@ -506,7 +506,7 @@ public final class DataSpace { * * Same model as BT.601-625, but all values (Y, Cb, Cr) range from {@code 0} to {@code 255} */ - public static final long DATASPACE_JFIF = 146931712; + public static final int DATASPACE_JFIF = 146931712; /** * ITU-R Recommendation 601 (BT.601) - 525-line * @@ -518,7 +518,7 @@ public final class DataSpace { * Transfer: TRANSFER_SMPTE_170M * Range: RANGE_LIMITED</pre> */ - public static final long DATASPACE_BT601_625 = 281149440; + public static final int DATASPACE_BT601_625 = 281149440; /** * ITU-R Recommendation 709 (BT.709) * @@ -530,7 +530,7 @@ public final class DataSpace { * Transfer: TRANSFER_SMPTE_170M * Range: RANGE_LIMITED</pre> */ - public static final long DATASPACE_BT601_525 = 281280512; + public static final int DATASPACE_BT601_525 = 281280512; /** * ITU-R Recommendation 2020 (BT.2020) * @@ -542,7 +542,7 @@ public final class DataSpace { * Transfer: TRANSFER_SMPTE_170M * Range: RANGE_FULL</pre> */ - public static final long DATASPACE_BT2020 = 147193856; + public static final int DATASPACE_BT2020 = 147193856; /** * ITU-R Recommendation 709 (BT.709) * @@ -554,7 +554,7 @@ public final class DataSpace { * Transfer: TRANSFER_SMPTE_170M * Range: RANGE_LIMITED</pre> */ - public static final long DATASPACE_BT709 = 281083904; + public static final int DATASPACE_BT709 = 281083904; /** * SMPTE EG 432-1 and SMPTE RP 431-2 * @@ -569,7 +569,7 @@ public final class DataSpace { * Note: Application is responsible for gamma encoding the data as * a 2.6 gamma encoding is not supported in HW. */ - public static final long DATASPACE_DCI_P3 = 155844608; + public static final int DATASPACE_DCI_P3 = 155844608; /** * sRGB linear encoding. * @@ -582,7 +582,7 @@ public final class DataSpace { * The values are encoded using the full range ([0,255] for 8-bit) for all * components. */ - public static final long DATASPACE_SRGB_LINEAR = 138477568; + public static final int DATASPACE_SRGB_LINEAR = 138477568; private DataSpace() {} @@ -594,11 +594,11 @@ public final class DataSpace { * @param transfer Opto-electronic transfer characteristic at the source * @param range The range of values * - * @return The long dataspace packed by standard, transfer and range value + * @return The int dataspace packed by standard, transfer and range value */ - public static @NamedDataSpace long pack(@DataSpaceStandard long standard, - @DataSpaceTransfer long transfer, - @DataSpaceRange long range) { + public static @NamedDataSpace int pack(@DataSpaceStandard int standard, + @DataSpaceTransfer int transfer, + @DataSpaceRange int range) { if ((standard & STANDARD_MASK) != standard) { throw new IllegalArgumentException("Invalid standard " + standard); } @@ -618,8 +618,8 @@ public final class DataSpace { * * @return The standard aspect */ - public static @DataSpaceStandard long getStandard(@NamedDataSpace long dataSpace) { - @DataSpaceStandard long standard = dataSpace & STANDARD_MASK; + public static @DataSpaceStandard int getStandard(@NamedDataSpace int dataSpace) { + @DataSpaceStandard int standard = dataSpace & STANDARD_MASK; return standard; } @@ -630,8 +630,8 @@ public final class DataSpace { * * @return The transfer aspect */ - public static @DataSpaceTransfer long getTransfer(@NamedDataSpace long dataSpace) { - @DataSpaceTransfer long transfer = dataSpace & TRANSFER_MASK; + public static @DataSpaceTransfer int getTransfer(@NamedDataSpace int dataSpace) { + @DataSpaceTransfer int transfer = dataSpace & TRANSFER_MASK; return transfer; } @@ -642,8 +642,8 @@ public final class DataSpace { * * @return The range aspect */ - public static @DataSpaceRange long getRange(@NamedDataSpace long dataSpace) { - @DataSpaceRange long range = dataSpace & RANGE_MASK; + public static @DataSpaceRange int getRange(@NamedDataSpace int dataSpace) { + @DataSpaceRange int range = dataSpace & RANGE_MASK; return range; } } diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java index d8295c962154..f67a5b44a8e9 100644 --- a/core/java/android/hardware/camera2/params/OutputConfiguration.java +++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java @@ -37,7 +37,6 @@ import android.hardware.camera2.utils.SurfaceUtils; import android.media.ImageReader; import android.os.Parcel; import android.os.Parcelable; -import android.util.ArraySet; import android.util.Log; import android.util.Size; import android.view.Surface; @@ -152,6 +151,100 @@ public final class OutputConfiguration implements Parcelable { */ public static final int SURFACE_GROUP_ID_NONE = -1; + /** + * Default timestamp base. + * + * <p>The camera device decides the timestamp based on the properties of the + * output surface.</p> + * + * <li> For a SurfaceView output surface, the timestamp base is {@link + * #TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED}. The timestamp is overridden with choreographer + * pulses from the display subsystem for smoother display of camera frames. The timestamp + * is roughly in the same time base as {@link android.os.SystemClock#uptimeMillis}.</li> + * <li> For an output surface of MediaRecorder, MediaCodec, or ImageReader with {@link + * android.hardware.HardwareBuffer#USAGE_VIDEO_ENCODE} usge flag, the timestamp base is + * {@link #TIMESTAMP_BASE_MONOTONIC}, which is roughly the same time base as + * {@link android.os.SystemClock#uptimeMillis}.</li> + * <li> For all other cases, the timestamp base is {@link #TIMESTAMP_BASE_SENSOR}, the same + * as what's specified by {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE}.</li> + * + * @see #TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED + * @see #TIMESTAMP_BASE_MONOTONIC + * @see #TIMESTAMP_BASE_SENSOR + */ + public static final int TIMESTAMP_BASE_DEFAULT = 0; + + /** + * Timestamp base of {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE}. + * + * <p>The timestamps of the output images are in the time base as specified by {@link + * CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE}. The application can look up the + * corresponding result metadata for a particular output image using this timestamp.</p> + */ + public static final int TIMESTAMP_BASE_SENSOR = 1; + + /** + * Timestamp base roughly the same as {@link android.os.SystemClock#uptimeMillis}. + * + * <p>The timestamps of the output images are monotonically increasing, and are roughly in the + * same time base as {@link android.os.SystemClock#uptimeMillis}. The timestamps with this + * time base can be directly used for audio-video sync in video recording.</p> + * + * <p>If the camera device's {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE} is + * REALTIME, timestamps with this time base cannot directly match the timestamps in + * {@link CameraCaptureSession.CaptureCallback#onCaptureStarted} or the sensor timestamps in + * {@link android.hardware.camera2.CaptureResult}.</p> + */ + public static final int TIMESTAMP_BASE_MONOTONIC = 2; + + /** + * Timestamp base roughly the same as {@link android.os.SystemClock#elapsedRealtime}. + * + * <p>The timestamps of the output images are roughly in the + * same time base as {@link android.os.SystemClock#elapsedRealtime}. The timestamps with this + * time base cannot be directly used for audio-video sync in video recording.</p> + * + * <p>If the camera device's {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE} is + * UNKNOWN, timestamps with this time base cannot directly match the timestamps in + * {@link CameraCaptureSession.CaptureCallback#onCaptureStarted} or the sensor timestamps in + * {@link android.hardware.camera2.CaptureResult}.</p> + * + * <p>If using a REALTIME timestamp base on a device that supports only + * TIMESTAMP_SOURCE_UNKNOWN, the accuracy of timestamps is only what is guaranteed in the + * documentation for UNKNOWN. In particular, they have no guarantees about being accurate + * enough to use in fusing image data with the output of inertial sensors, for features such as + * image stabilization or augmented reality.</p> + */ + public static final int TIMESTAMP_BASE_REALTIME = 3; + + /** + * Timestamp is synchronized to choreographer. + * + * <p>The timestamp of the output images are overridden with choreographer pulses from the + * display subsystem for smoother display of camera frames. An output target of SurfaceView + * uses this time base by default.</p> + * + * <p>The choreographer synchronized timestamps are also reasonable to use when drawing to a + * TextureView. So this timestamp base can be used for a SurfaceTexture as part of a + * TextureView, in addition to SurfaceView.</p> + * + * <p>Timestamps with this time base cannot directly match the timestamps in + * {@link CameraCaptureSession.CaptureCallback#onCaptureStarted} or the sensor timestamps in + * {@link android.hardware.camera2.CaptureResult}. This timestamp base shouldn't be used if the + * timestamp needs to be used for audio-video synchronization.</p> + */ + public static final int TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED = 4; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"TIMESTAMP_BASE_"}, value = + {TIMESTAMP_BASE_DEFAULT, + TIMESTAMP_BASE_SENSOR, + TIMESTAMP_BASE_MONOTONIC, + TIMESTAMP_BASE_REALTIME, + TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED}) + public @interface TimestampBase {}; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"SENSOR_PIXEL_MODE_"}, value = @@ -367,6 +460,7 @@ public final class OutputConfiguration implements Parcelable { mSensorPixelModesUsed = new ArrayList<Integer>(); mDynamicRangeProfile = DynamicRangeProfiles.STANDARD; mStreamUseCase = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT; + mTimestampBase = TIMESTAMP_BASE_DEFAULT; } /** @@ -810,6 +904,47 @@ public final class OutputConfiguration implements Parcelable { } /** + * Set timestamp base for this output target + * + * <p>Timestamp base describes the time domain of images from this + * camera output and its relationship with {@link + * CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE}.</p> + * + * <p>If this function is not called, the timestamp base for this output + * is {@link #TIMESTAMP_BASE_DEFAULT}, with which the camera device adjusts + * timestamps based on the output target.</p> + * + * <p>See {@link #TIMESTAMP_BASE_DEFAULT}, {@link #TIMESTAMP_BASE_SENSOR}, + * and {@link #TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED} for details of each timestamp base.</p> + * + * @param timestampBase The timestamp base to be set. + * + * @throws IllegalArgumentException If the timestamp base isn't within the range of valid + * values. + */ + public void setTimestampBase(@TimestampBase int timestampBase) { + // Verify that the value is in range + if (timestampBase < TIMESTAMP_BASE_DEFAULT || + timestampBase > TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED) { + throw new IllegalArgumentException("Not a valid timestamp base value " + + timestampBase); + } + mTimestampBase = timestampBase; + } + + /** + * Get the current timestamp base + * + * <p>If no {@link #setTimestampBase} is called first, this function returns + * {@link #TIMESTAMP_BASE_DEFAULT}.</p> + * + * @return The currently set timestamp base + */ + public @TimestampBase int getTimestampBase() { + return mTimestampBase; + } + + /** * Create a new {@link OutputConfiguration} instance with another {@link OutputConfiguration} * instance. * @@ -837,6 +972,7 @@ public final class OutputConfiguration implements Parcelable { this.mSensorPixelModesUsed = other.mSensorPixelModesUsed; this.mDynamicRangeProfile = other.mDynamicRangeProfile; this.mStreamUseCase = other.mStreamUseCase; + this.mTimestampBase = other.mTimestampBase; } /** @@ -861,6 +997,7 @@ public final class OutputConfiguration implements Parcelable { int dynamicRangeProfile = source.readInt(); DynamicRangeProfiles.checkProfileValue(dynamicRangeProfile); + int timestampBase = source.readInt(); mSurfaceGroupId = surfaceSetId; mRotation = rotation; mSurfaces = surfaces; @@ -885,6 +1022,7 @@ public final class OutputConfiguration implements Parcelable { mSensorPixelModesUsed = convertIntArrayToIntegerList(sensorPixelModesUsed); mDynamicRangeProfile = dynamicRangeProfile; mStreamUseCase = streamUseCase; + mTimestampBase = timestampBase; } /** @@ -1002,6 +1140,7 @@ public final class OutputConfiguration implements Parcelable { dest.writeIntArray(convertIntegerToIntList(mSensorPixelModesUsed)); dest.writeInt(mDynamicRangeProfile); dest.writeInt(mStreamUseCase); + dest.writeInt(mTimestampBase); } /** @@ -1033,7 +1172,8 @@ public final class OutputConfiguration implements Parcelable { mConfiguredGenerationId != other.mConfiguredGenerationId || !Objects.equals(mPhysicalCameraId, other.mPhysicalCameraId) || mIsMultiResolution != other.mIsMultiResolution || - mStreamUseCase != other.mStreamUseCase) + mStreamUseCase != other.mStreamUseCase || + mTimestampBase != other.mTimestampBase) return false; if (mSensorPixelModesUsed.size() != other.mSensorPixelModesUsed.size()) { return false; @@ -1071,7 +1211,7 @@ public final class OutputConfiguration implements Parcelable { mSurfaceGroupId, mSurfaceType, mIsShared ? 1 : 0, mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(), mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode(), - mDynamicRangeProfile, mStreamUseCase); + mDynamicRangeProfile, mStreamUseCase, mTimestampBase); } return HashCodeHelpers.hashCode( @@ -1080,7 +1220,7 @@ public final class OutputConfiguration implements Parcelable { mConfiguredDataspace, mSurfaceGroupId, mIsShared ? 1 : 0, mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(), mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode(), - mDynamicRangeProfile, mStreamUseCase); + mDynamicRangeProfile, mStreamUseCase, mTimestampBase); } private static final String TAG = "OutputConfiguration"; @@ -1116,4 +1256,6 @@ public final class OutputConfiguration implements Parcelable { private int mDynamicRangeProfile; // Stream use case private int mStreamUseCase; + // Timestamp base + private int mTimestampBase; } diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 8f8c5a9fce06..7f115fad5735 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -44,6 +44,7 @@ import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; import android.gui.DropInputMode; +import android.hardware.DataSpace; import android.hardware.HardwareBuffer; import android.hardware.display.DeviceProductInfo; import android.hardware.display.DisplayedContentSample; @@ -210,8 +211,8 @@ public final class SurfaceControl implements Parcelable { HardwareBuffer buffer); private static native void nativeSetBufferTransform(long transactionObj, long nativeObject, int transform); - private static native void nativeSetColorSpace(long transactionObj, long nativeObject, - int colorSpace); + private static native void nativeSetDataSpace(long transactionObj, long nativeObject, + @DataSpace.NamedDataSpace int dataSpace); private static native void nativeSetDamageRegion(long transactionObj, long nativeObject, Region region); @@ -3719,10 +3720,31 @@ public final class SurfaceControl implements Parcelable { * SurfaceControls that were created as type {@link #FX_SURFACE_BLAST} * * @hide + * @deprecated use {@link #setDataSpace(SurfaceControl, long)} instead */ + @Deprecated public Transaction setColorSpace(SurfaceControl sc, ColorSpace colorSpace) { checkPreconditions(sc); - nativeSetColorSpace(mNativeObject, sc.mNativeObject, colorSpace.getId()); + if (colorSpace.getId() == ColorSpace.Named.DCI_P3.ordinal()) { + setDataSpace(sc, DataSpace.DATASPACE_DCI_P3); + } else { + setDataSpace(sc, DataSpace.DATASPACE_SRGB); + } + return this; + } + + /** + * Set the dataspace for the SurfaceControl. This will control how the buffer + * set with {@link #setBuffer(SurfaceControl, HardwareBuffer)} is displayed. + * + * @param sc The SurfaceControl to update + * @param dataspace The dataspace to set it to + * @return this + */ + public @NonNull Transaction setDataSpace(@NonNull SurfaceControl sc, + @DataSpace.NamedDataSpace int dataspace) { + checkPreconditions(sc); + nativeSetDataSpace(mNativeObject, sc.mNativeObject, dataspace); return this; } diff --git a/core/jni/android_graphics_SurfaceTexture.cpp b/core/jni/android_graphics_SurfaceTexture.cpp index 0f647ea2eaea..21487abadbae 100644 --- a/core/jni/android_graphics_SurfaceTexture.cpp +++ b/core/jni/android_graphics_SurfaceTexture.cpp @@ -346,7 +346,7 @@ static jlong SurfaceTexture_getTimestamp(JNIEnv* env, jobject thiz) return surfaceTexture->getTimestamp(); } -static jlong SurfaceTexture_getDataSpace(JNIEnv* env, jobject thiz) { +static jint SurfaceTexture_getDataSpace(JNIEnv* env, jobject thiz) { sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); return surfaceTexture->getCurrentDataSpace(); } @@ -375,7 +375,7 @@ static const JNINativeMethod gSurfaceTextureMethods[] = { {"nativeAttachToGLContext", "(I)I", (void*)SurfaceTexture_attachToGLContext}, {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix}, {"nativeGetTimestamp", "()J", (void*)SurfaceTexture_getTimestamp}, - {"nativeGetDataSpace", "()J", (void*)SurfaceTexture_getDataSpace}, + {"nativeGetDataSpace", "()I", (void*)SurfaceTexture_getDataSpace}, {"nativeRelease", "()V", (void*)SurfaceTexture_release}, {"nativeIsReleased", "()Z", (void*)SurfaceTexture_isReleased}, }; diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 1033efa5094f..2488b57c7f2a 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -263,15 +263,6 @@ constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace } } -constexpr ui::Dataspace fromNamedColorSpaceValueToDataspace(const jint colorSpace) { - switch (colorSpace) { - case JNamedColorSpace::DISPLAY_P3: - return ui::Dataspace::DISPLAY_P3; - default: - return ui::Dataspace::V0_SRGB; - } -} - constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) { switch (colorMode) { case ui::ColorMode::DISPLAY_P3: @@ -645,11 +636,11 @@ static void nativeSetBufferTransform(JNIEnv* env, jclass clazz, jlong transactio transaction->setTransformToDisplayInverse(ctrl, transformToInverseDisplay); } -static void nativeSetColorSpace(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject, - jint colorSpace) { +static void nativeSetDataSpace(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject, + jint dataSpace) { auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject); - ui::Dataspace dataspace = fromNamedColorSpaceValueToDataspace(colorSpace); + ui::Dataspace dataspace = static_cast<ui::Dataspace>(dataSpace); transaction->setDataspace(ctrl, dataspace); } @@ -2122,8 +2113,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { {"nativeSetBuffer", "(JJLandroid/hardware/HardwareBuffer;)V", (void*)nativeSetBuffer }, {"nativeSetBufferTransform", "(JJI)V", (void*) nativeSetBufferTransform}, - {"nativeSetColorSpace", "(JJI)V", - (void*)nativeSetColorSpace }, + {"nativeSetDataSpace", "(JJI)V", + (void*)nativeSetDataSpace }, {"nativeSyncInputWindows", "(J)V", (void*)nativeSyncInputWindows }, {"nativeGetDisplayBrightnessSupport", "(Landroid/os/IBinder;)Z", diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index afd320d48c51..451b99ea7550 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -1612,7 +1612,7 @@ public class Paint { * Return the paint's Align value for drawing text. This controls how the * text is positioned relative to its origin. LEFT align means that all of * the text will be drawn to the right of its origin (i.e. the origin - * specifieds the LEFT edge of the text) and so on. + * specifies the LEFT edge of the text) and so on. * * @return the paint's Align value for drawing text. */ @@ -1624,7 +1624,7 @@ public class Paint { * Set the paint's text alignment. This controls how the * text is positioned relative to its origin. LEFT align means that all of * the text will be drawn to the right of its origin (i.e. the origin - * specifieds the LEFT edge of the text) and so on. + * specifies the LEFT edge of the text) and so on. * * @param align set the paint's Align value for drawing text. */ diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index d84a24db5c58..ee41148a7686 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -353,7 +353,7 @@ public class SurfaceTexture { * Retrieve the dataspace associated with the texture image. */ @SuppressLint("MethodNameUnits") - public @NamedDataSpace long getDataSpace() { + public @NamedDataSpace int getDataSpace() { return nativeGetDataSpace(); } @@ -426,7 +426,7 @@ public class SurfaceTexture { private native void nativeFinalize(); private native void nativeGetTransformMatrix(float[] mtx); private native long nativeGetTimestamp(); - private native long nativeGetDataSpace(); + private native int nativeGetDataSpace(); private native void nativeSetDefaultBufferSize(int width, int height); private native void nativeUpdateTexImage(); private native void nativeReleaseTexImage(); diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_overlay_layout.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_dialog_background.xml index f4c6d65bad05..3e1a2bce2393 100644 --- a/libs/WindowManager/Shell/res/layout/letterbox_education_overlay_layout.xml +++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_dialog_background.xml @@ -14,11 +14,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -<FrameLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:alpha="0" - android:background="@android:color/system_neutral1_900" - android:clickable="true"> -</FrameLayout> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="@color/compat_controls_background"/> + <corners android:radius="@dimen/letterbox_education_dialog_corner_radius"/> +</shape>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_background.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background.xml index 723963ff8c9a..0d8811357c05 100644 --- a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_background.xml +++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background.xml @@ -16,6 +16,6 @@ --> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> - <solid android:color="@android:color/system_accent1_100"/> + <solid android:color="@color/letterbox_education_accent_primary"/> <corners android:radius="12dp"/> </shape>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_background_ripple.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml index 0a3a81302a49..0d8a8faa9798 100644 --- a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_background_ripple.xml +++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml @@ -14,8 +14,7 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -<!-- DO NOT SUBMIT - find right color!! --> <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@android:color/system_accent1_10"> - <item android:drawable="@drawable/letterbox_education_dismiss_background"/> + <item android:drawable="@drawable/letterbox_education_dismiss_button_background"/> </ripple>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_letterboxed_app.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_letterboxed_app.xml new file mode 100644 index 000000000000..6fcd1de892a3 --- /dev/null +++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_letterboxed_app.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 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. + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="@dimen/letterbox_education_dialog_icon_size" + android:height="@dimen/letterbox_education_dialog_icon_size" + android:viewportWidth="48" + android:viewportHeight="48"> + <path + android:fillColor="@color/letterbox_education_accent_primary" + android:fillType="evenOdd" + android:pathData="M2 8C0.895431 8 0 8.89543 0 10V38C0 39.1046 0.895431 40 2 40H46C47.1046 40 48 39.1046 48 38V10C48 8.89543 47.1046 8 46 8H2ZM44 12H4V36H44V12Z" /> + <path + android:fillColor="@color/letterbox_education_accent_primary" + android:pathData="M 17 14 L 31 14 Q 32 14 32 15 L 32 33 Q 32 34 31 34 L 17 34 Q 16 34 16 33 L 16 15 Q 16 14 17 14 Z" /> +</vector>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml index edf737fcc86a..fc6ea9a57e10 100644 --- a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml +++ b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml @@ -13,30 +13,31 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -<com.android.wm.shell.compatui.LetterboxEduDialogLayout +<com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="@color/compat_controls_background" - android:gravity="center" - android:paddingTop="24dp" - android:paddingBottom="32dp" - android:paddingHorizontal="32dp"> + android:background="@android:color/system_neutral1_900"> + + <!-- The background of the top-level layout acts as the background dim. --> - <!-- Adding an extra layer to animate the alpha of the background and content separately. --> <LinearLayout - android:id="@+id/letterbox_education_content" + android:id="@+id/letterbox_education_dialog_container" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_gravity="center" android:gravity="center_horizontal" - android:orientation="vertical"> + android:orientation="vertical" + android:background="@drawable/letterbox_education_dialog_background" + android:padding="24dp"> <ImageView android:id="@+id/letterbox_education_icon" android:layout_width="@dimen/letterbox_education_dialog_icon_size" android:layout_height="@dimen/letterbox_education_dialog_icon_size" - android:layout_marginBottom="20dp" /> + android:layout_marginBottom="12dp" + android:src="@drawable/letterbox_education_ic_letterboxed_app"/> <TextView android:id="@+id/letterbox_education_dialog_title" @@ -44,36 +45,38 @@ android:layout_height="wrap_content" android:maxWidth="@dimen/letterbox_education_dialog_title_max_width" android:lineSpacingExtra="4sp" + android:text="@string/letterbox_education_dialog_title" android:textAlignment="center" android:textColor="@color/compat_controls_text" android:textSize="24sp"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:maxWidth="@dimen/letterbox_education_dialog_title_max_width" + android:lineSpacingExtra="4sp" + android:text="@string/letterbox_education_dialog_subtext" + android:textAlignment="center" + android:textColor="@color/letterbox_education_text_secondary" + android:textSize="14sp"/> + <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="top" android:orientation="horizontal" - android:paddingTop="43dp"> - - <com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogActionLayout - android:id="@+id/letterbox_education_dialog_screen_rotation_action" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:icon="@drawable/letterbox_education_ic_screen_rotation"/> + android:paddingTop="48dp"> <com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogActionLayout - android:id="@+id/letterbox_education_dialog_split_screen_action" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/letterbox_education_dialog_space_between_actions" - app:icon="@drawable/letterbox_education_ic_split_screen" - app:text="@string/letterbox_education_split_screen_text"/> + app:icon="@drawable/letterbox_education_ic_screen_rotation" + app:text="@string/letterbox_education_screen_rotation_text"/> <com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogActionLayout - android:id="@+id/letterbox_education_dialog_reposition_action" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:visibility="gone" android:layout_marginStart="@dimen/letterbox_education_dialog_space_between_actions" app:icon="@drawable/letterbox_education_ic_reposition" app:text="@string/letterbox_education_reposition_text"/> @@ -81,13 +84,11 @@ </LinearLayout> <Button - android:id="@+id/letterbox_education_dialog_dismiss" + android:id="@+id/letterbox_education_dialog_dismiss_button" android:layout_width="match_parent" android:layout_height="56dp" - android:layout_marginTop="43dp" - android:layout_marginHorizontal="24dp" - android:background="@drawable/letterbox_education_dismiss_background_ripple" - android:gravity="center" + android:layout_marginTop="48dp" + android:background="@drawable/letterbox_education_dismiss_button_background_ripple" android:text="@string/letterbox_education_got_it" android:textColor="@android:color/system_neutral1_900" android:textAlignment="center" @@ -95,4 +96,4 @@ </LinearLayout> -</com.android.wm.shell.compatui.LetterboxEduDialogLayout> +</com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogLayout> diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml index 84aec640434b..4606d24d1716 100644 --- a/libs/WindowManager/Shell/res/values/colors.xml +++ b/libs/WindowManager/Shell/res/values/colors.xml @@ -35,6 +35,7 @@ <color name="compat_controls_text">@android:color/system_neutral1_50</color> <!-- Letterbox Education --> + <color name="letterbox_education_accent_primary">@android:color/system_accent1_100</color> <color name="letterbox_education_text_secondary">@android:color/system_neutral2_200</color> <!-- GM2 colors --> diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index 40c7647ecedf..7a398c504546 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -226,18 +226,14 @@ <dimen name="letterbox_education_dialog_icon_size">48dp</dimen> <!-- The width of each action container in the letterbox education dialog --> - <dimen name="letterbox_education_dialog_action_width">136dp</dimen> + <dimen name="letterbox_education_dialog_action_width">140dp</dimen> <!-- The space between two actions in the letterbox education dialog --> - <dimen name="letterbox_education_dialog_space_between_actions">18dp</dimen> + <dimen name="letterbox_education_dialog_space_between_actions">24dp</dimen> <!-- The maximum width of the title and subtitle in the letterbox education dialog. --> <dimen name="letterbox_education_dialog_title_max_width">444dp</dimen> - <!-- The distance that the letterbox education dialog will move up during appear/dismiss - animation. --> - <dimen name="letterbox_education_dialog_animation_elevation">20dp</dimen> - <!-- The width of the brand image on staring surface. --> <dimen name="starting_surface_brand_image_width">200dp</dimen> diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml index 16a4b524803a..a24311fb1f21 100644 --- a/libs/WindowManager/Shell/res/values/strings.xml +++ b/libs/WindowManager/Shell/res/values/strings.xml @@ -172,19 +172,16 @@ <string name="camera_compat_dismiss_button_description">No camera issues? Tap to dismiss.</string> <!-- The title of the letterbox education dialog. [CHAR LIMIT=NONE] --> - <string name="letterbox_education_dialog_title">Get the most out of <xliff:g id="app_name" example="YouTube">%s</xliff:g></string> + <string name="letterbox_education_dialog_title">Some apps work best in portrait</string> - <!-- Description of the rotate screen into portrait action. [CHAR LIMIT=NONE] --> - <string name="letterbox_education_screen_rotation_portrait_text">Rotate your screen to portrait</string> + <!-- The subtext of the letterbox education dialog. [CHAR LIMIT=NONE] --> + <string name="letterbox_education_dialog_subtext">Try one of these options to make the most of your space</string> - <!-- Description of the rotate screen into landscape action. [CHAR LIMIT=NONE] --> - <string name="letterbox_education_screen_rotation_landscape_text">Rotate your screen to landscape</string> - - <!-- Description of the put app in split-screen action. [CHAR LIMIT=NONE] --> - <string name="letterbox_education_split_screen_text">Drag in another app to use split screen</string> + <!-- Description of the rotate screen action. [CHAR LIMIT=NONE] --> + <string name="letterbox_education_screen_rotation_text">Rotate your device to go full screen</string> <!-- Description of the reposition app action. [CHAR LIMIT=NONE] --> - <string name="letterbox_education_reposition_text">Double tap to reposition</string> + <string name="letterbox_education_reposition_text">Double-tap next to an app to reposition it</string> <!-- Button text for dismissing the letterbox education dialog. [CHAR LIMIT=20] --> <string name="letterbox_education_got_it">Got it</string> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUILayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUILayout.java index 29b2baa221e7..d44b4d8f63b6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUILayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUILayout.java @@ -31,7 +31,7 @@ import com.android.wm.shell.R; /** * Container for compat UI controls. */ -public class CompatUILayout extends LinearLayout { +class CompatUILayout extends LinearLayout { private CompatUIWindowManager mWindowManager; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogActionLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogActionLayout.java index 762a037d19df..fc6fd3f2c959 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogActionLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogActionLayout.java @@ -16,7 +16,6 @@ package com.android.wm.shell.compatui.letterboxedu; -import android.annotation.StringRes; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; @@ -32,8 +31,6 @@ import com.android.wm.shell.R; */ // TODO(b/215316431): Add tests class LetterboxEduDialogActionLayout extends FrameLayout { - private final ImageView mIcon; - private final TextView mText; LetterboxEduDialogActionLayout(Context context, AttributeSet attrs) { super(context, attrs); @@ -46,26 +43,15 @@ class LetterboxEduDialogActionLayout extends FrameLayout { /* defStyleRes= */ 0); int iconId = styledAttributes.getResourceId( R.styleable.LetterboxEduDialogActionLayout_icon, 0); - String optionalText = styledAttributes.getString( + String text = styledAttributes.getString( R.styleable.LetterboxEduDialogActionLayout_text); styledAttributes.recycle(); View rootView = inflate(getContext(), R.layout.letterbox_education_dialog_action_layout, this); - - mIcon = rootView.findViewById(R.id.letterbox_education_dialog_action_icon); - mIcon.setImageResource(iconId); - mText = rootView.findViewById(R.id.letterbox_education_dialog_action_text); - if (optionalText != null) { - mText.setText(optionalText); - } - } - - void setText(@StringRes int id) { - mText.setText(getResources().getString(id)); - } - - void setIconRotation(float rotation) { - mIcon.setRotation(rotation); + ((ImageView) rootView.findViewById( + R.id.letterbox_education_dialog_action_icon)).setImageResource(iconId); + ((TextView) rootView.findViewById(R.id.letterbox_education_dialog_action_text)).setText( + text); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java index 662862afd461..fa75d14b4aec 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java @@ -17,22 +17,23 @@ package com.android.wm.shell.compatui.letterboxedu; import android.content.Context; -import android.content.res.Configuration; -import android.content.res.Configuration.Orientation; -import android.graphics.drawable.Drawable; import android.util.AttributeSet; -import android.view.View; import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.TextView; import com.android.wm.shell.R; /** - * Container for Letterbox Education Dialog. + * Container for Letterbox Education Dialog and background dim. + * + * <p>This layout should fill the entire task and the background around the dialog acts as the + * background dim which dismisses the dialog when clicked. */ // TODO(b/215316431): Add tests -public class LetterboxEduDialogLayout extends FrameLayout { +class LetterboxEduDialogLayout extends FrameLayout { + + // The alpha of a background is a number between 0 (fully transparent) to 255 (fully opaque). + // 204 is simply 255 * 0.8. + private static final int BACKGROUND_DIM_ALPHA = 204; public LetterboxEduDialogLayout(Context context) { this(context, null); @@ -52,43 +53,23 @@ public class LetterboxEduDialogLayout extends FrameLayout { } /** - * Register a callback for the dismiss button. + * Register a callback for the dismiss button and background dim. + * * @param callback The callback to register */ void setDismissOnClickListener(Runnable callback) { - findViewById(R.id.letterbox_education_dialog_dismiss).setOnClickListener( + findViewById(R.id.letterbox_education_dialog_dismiss_button).setOnClickListener( view -> callback.run()); + // Clicks on the background dim should also dismiss the dialog. + setOnClickListener(view -> callback.run()); + // We add a no-op on-click listener to the dialog container so that clicks on it won't + // propagate to the listener of the layout (which represents the background dim). + findViewById(R.id.letterbox_education_dialog_container).setOnClickListener(view -> {}); } - /** - * Updates the layout with the given app info. - * @param appIcon The name of the app - * @param appIcon The icon of the app - */ - void updateAppInfo(String appName, Drawable appIcon) { - ((ImageView) findViewById(R.id.letterbox_education_icon)).setImageDrawable(appIcon); - ((TextView) findViewById(R.id.letterbox_education_dialog_title)).setText( - getResources().getString(R.string.letterbox_education_dialog_title, appName)); - } - - /** - * Updates the layout according to the given orientation. - * @param orientation The orientation of the display - */ - void updateDisplayOrientation(@Orientation int orientation) { - boolean isOrientationPortrait = orientation == Configuration.ORIENTATION_PORTRAIT; - ((LetterboxEduDialogActionLayout) findViewById( - R.id.letterbox_education_dialog_screen_rotation_action)).setText( - isOrientationPortrait - ? R.string.letterbox_education_screen_rotation_landscape_text - : R.string.letterbox_education_screen_rotation_portrait_text); - - if (isOrientationPortrait) { - ((LetterboxEduDialogActionLayout) findViewById( - R.id.letterbox_education_dialog_split_screen_action)).setIconRotation(90f); - } - - findViewById(R.id.letterbox_education_dialog_reposition_action).setVisibility( - isOrientationPortrait ? View.GONE : View.VISIBLE); + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + getBackground().mutate().setAlpha(BACKGROUND_DIM_ALPHA); } } diff --git a/libs/WindowManager/Shell/tests/OWNERS b/libs/WindowManager/Shell/tests/OWNERS index f49e80ae16b1..a244d14b0e14 100644 --- a/libs/WindowManager/Shell/tests/OWNERS +++ b/libs/WindowManager/Shell/tests/OWNERS @@ -2,3 +2,7 @@ # includes OWNERS from parent directories natanieljr@google.com pablogamito@google.com + +lbill@google.com +madym@google.com +hwwang@google.com diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java index cf1aac0e4d4c..8a03afb77942 100644 --- a/media/java/android/media/Image.java +++ b/media/java/android/media/Image.java @@ -302,13 +302,13 @@ public abstract class Image implements AutoCloseable { return; } - private @NamedDataSpace long mDataSpace = DataSpace.DATASPACE_UNKNOWN; + private @NamedDataSpace int mDataSpace = DataSpace.DATASPACE_UNKNOWN; /** * Get the dataspace associated with this frame. */ @SuppressLint("MethodNameUnits") - public @NamedDataSpace long getDataSpace() { + public @NamedDataSpace int getDataSpace() { throwISEIfImageIsInvalid(); return mDataSpace; } @@ -322,7 +322,7 @@ public abstract class Image implements AutoCloseable { * * @param dataSpace The Dataspace to be set for this image */ - public void setDataSpace(@NamedDataSpace long dataSpace) { + public void setDataSpace(@NamedDataSpace int dataSpace) { throwISEIfImageIsInvalid(); mDataSpace = dataSpace; } diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java index c9bda48ec27c..70d6810d01ec 100644 --- a/media/java/android/media/ImageReader.java +++ b/media/java/android/media/ImageReader.java @@ -277,7 +277,7 @@ public class ImageReader implements AutoCloseable { } private void initializeImageReader(int width, int height, int imageFormat, int maxImages, - long usage, int hardwareBufferFormat, long dataSpace, boolean useLegacyImageFormat) { + long usage, int hardwareBufferFormat, int dataSpace, boolean useLegacyImageFormat) { if (width < 1 || height < 1) { throw new IllegalArgumentException( "The image dimensions must be positive"); @@ -330,7 +330,7 @@ public class ImageReader implements AutoCloseable { } private ImageReader(int width, int height, int maxImages, long usage, - MultiResolutionImageReader parent, int hardwareBufferFormat, long dataSpace) { + MultiResolutionImageReader parent, int hardwareBufferFormat, int dataSpace) { mWidth = width; mHeight = height; mFormat = ImageFormat.UNKNOWN; // set default image format value as UNKNOWN @@ -417,7 +417,7 @@ public class ImageReader implements AutoCloseable { * @return the expected dataspace of an Image. */ @SuppressLint("MethodNameUnits") - public @NamedDataSpace long getDataSpace() { + public @NamedDataSpace int getDataSpace() { return mDataSpace; } @@ -925,7 +925,7 @@ public class ImageReader implements AutoCloseable { private int mMaxImages = 1; private int mImageFormat = ImageFormat.UNKNOWN; private int mHardwareBufferFormat = HardwareBuffer.RGBA_8888; - private long mDataSpace = DataSpace.DATASPACE_UNKNOWN; + private int mDataSpace = DataSpace.DATASPACE_UNKNOWN; private long mUsage = HardwareBuffer.USAGE_CPU_READ_OFTEN; private boolean mUseLegacyImageFormat = false; @@ -1042,7 +1042,7 @@ public class ImageReader implements AutoCloseable { * @see #setDefaultHardwareBufferFormat */ @SuppressLint("MissingGetterMatchingBuilder") - public @NonNull Builder setDefaultDataSpace(@NamedDataSpace long dataSpace) { + public @NonNull Builder setDefaultDataSpace(@NamedDataSpace int dataSpace) { mDataSpace = dataSpace; mUseLegacyImageFormat = false; mImageFormat = ImageFormat.UNKNOWN; @@ -1089,7 +1089,7 @@ public class ImageReader implements AutoCloseable { private final int mHardwareBufferFormat; - private final long mDataSpace; + private final @NamedDataSpace int mDataSpace; private final boolean mUseLegacyImageFormat; @@ -1131,7 +1131,7 @@ public class ImageReader implements AutoCloseable { mDataSpace = ImageReader.this.mDataSpace; } - SurfaceImage(int hardwareBufferFormat, long dataSpace) { + SurfaceImage(int hardwareBufferFormat, int dataSpace) { mHardwareBufferFormat = hardwareBufferFormat; mDataSpace = dataSpace; mFormat = PublicFormatUtils.getPublicFormat(mHardwareBufferFormat, mDataSpace); @@ -1240,7 +1240,7 @@ public class ImageReader implements AutoCloseable { } @Override - public long getDataSpace() { + public @NamedDataSpace int getDataSpace() { throwISEIfImageIsInvalid(); return mDataSpace; } @@ -1383,7 +1383,7 @@ public class ImageReader implements AutoCloseable { private SurfacePlane[] mPlanes; private int mFormat = ImageFormat.UNKNOWN; private int mHardwareBufferFormat = HardwareBuffer.RGBA_8888; - private long mDataSpace = DataSpace.DATASPACE_UNKNOWN; + private int mDataSpace = DataSpace.DATASPACE_UNKNOWN; // If this image is detached from the ImageReader. private AtomicBoolean mIsDetached = new AtomicBoolean(false); @@ -1397,7 +1397,7 @@ public class ImageReader implements AutoCloseable { } private synchronized native void nativeInit(Object weakSelf, int w, int h, int maxImgs, - long consumerUsage, int hardwareBufferFormat, long dataSpace); + long consumerUsage, int hardwareBufferFormat, int dataSpace); private synchronized native void nativeClose(); private synchronized native void nativeReleaseImage(Image i); private synchronized native Surface nativeGetSurface(); diff --git a/media/java/android/media/ImageWriter.java b/media/java/android/media/ImageWriter.java index 5c3f918dd98d..e0f04a119234 100644 --- a/media/java/android/media/ImageWriter.java +++ b/media/java/android/media/ImageWriter.java @@ -107,7 +107,7 @@ public class ImageWriter implements AutoCloseable { private final int mMaxImages; private long mUsage = HardwareBuffer.USAGE_CPU_WRITE_OFTEN; private @HardwareBuffer.Format int mHardwareBufferFormat; - private @NamedDataSpace long mDataSpace; + private @NamedDataSpace int mDataSpace; private boolean mUseLegacyImageFormat; // Field below is used by native code, do not access or modify. @@ -251,7 +251,7 @@ public class ImageWriter implements AutoCloseable { private void initializeImageWriter(Surface surface, int maxImages, boolean useSurfaceImageFormatInfo, boolean useLegacyImageFormat, int imageFormat, - int hardwareBufferFormat, long dataSpace, int width, int height, long usage) { + int hardwareBufferFormat, int dataSpace, int width, int height, long usage) { if (surface == null || maxImages < 1) { throw new IllegalArgumentException("Illegal input argument: surface " + surface + ", maxImages: " + maxImages); @@ -331,7 +331,7 @@ public class ImageWriter implements AutoCloseable { } private ImageWriter(Surface surface, int maxImages, boolean useSurfaceImageFormatInfo, - int hardwareBufferFormat, long dataSpace, int width, int height, long usage) { + int hardwareBufferFormat, int dataSpace, int width, int height, long usage) { mMaxImages = maxImages; mUsage = usage; mHardwareBufferFormat = hardwareBufferFormat; @@ -601,7 +601,7 @@ public class ImageWriter implements AutoCloseable { * @return The ImageWriter dataspace. */ @SuppressLint("MethodNameUnits") - public @NamedDataSpace long getDataSpace() { + public @NamedDataSpace int getDataSpace() { return mDataSpace; } @@ -882,7 +882,7 @@ public class ImageWriter implements AutoCloseable { private int mImageFormat = ImageFormat.UNKNOWN; private long mUsage = -1; private @HardwareBuffer.Format int mHardwareBufferFormat = HardwareBuffer.RGBA_8888; - private @NamedDataSpace long mDataSpace = DataSpace.DATASPACE_UNKNOWN; + private @NamedDataSpace int mDataSpace = DataSpace.DATASPACE_UNKNOWN; private boolean mUseSurfaceImageFormatInfo = true; // set this as true temporarily now as a workaround to get correct format // when using surface format by default without overriding the image format @@ -993,7 +993,7 @@ public class ImageWriter implements AutoCloseable { * * @see #setHardwareBufferFormat */ - public @NonNull Builder setDataSpace(@NamedDataSpace long dataSpace) { + public @NonNull Builder setDataSpace(@NamedDataSpace int dataSpace) { mDataSpace = dataSpace; mImageFormat = ImageFormat.UNKNOWN; mUseLegacyImageFormat = false; @@ -1044,7 +1044,7 @@ public class ImageWriter implements AutoCloseable { private int mHeight = -1; private int mWidth = -1; private int mFormat = -1; - private @NamedDataSpace long mDataSpace = DataSpace.DATASPACE_UNKNOWN; + private @NamedDataSpace int mDataSpace = DataSpace.DATASPACE_UNKNOWN; // When this default timestamp is used, timestamp for the input Image // will be generated automatically when queueInputBuffer is called. private final long DEFAULT_TIMESTAMP = Long.MIN_VALUE; @@ -1066,14 +1066,14 @@ public class ImageWriter implements AutoCloseable { } @Override - public @NamedDataSpace long getDataSpace() { + public @NamedDataSpace int getDataSpace() { throwISEIfImageIsInvalid(); return mDataSpace; } @Override - public void setDataSpace(@NamedDataSpace long dataSpace) { + public void setDataSpace(@NamedDataSpace int dataSpace) { throwISEIfImageIsInvalid(); mDataSpace = dataSpace; @@ -1279,13 +1279,13 @@ public class ImageWriter implements AutoCloseable { // Create the SurfacePlane object and fill the information private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes, int writerFmt, - long dataSpace); + int dataSpace); private synchronized native int nativeGetWidth(); private synchronized native int nativeGetHeight(); - private synchronized native int nativeGetFormat(long dataSpace); + private synchronized native int nativeGetFormat(int dataSpace); private synchronized native HardwareBuffer nativeGetHardwareBuffer(); @@ -1295,21 +1295,21 @@ public class ImageWriter implements AutoCloseable { // Native implemented ImageWriter methods. private synchronized native long nativeInit(Object weakSelf, Surface surface, int maxImages, int width, int height, boolean useSurfaceImageFormatInfo, int hardwareBufferFormat, - long dataSpace, long usage); + int dataSpace, long usage); private synchronized native void nativeClose(long nativeCtx); private synchronized native void nativeDequeueInputImage(long nativeCtx, Image wi); private synchronized native void nativeQueueInputImage(long nativeCtx, Image image, - long timestampNs, long dataSpace, int left, int top, int right, int bottom, + long timestampNs, int dataSpace, int left, int top, int right, int bottom, int transform, int scalingMode); private synchronized native int nativeAttachAndQueueImage(long nativeCtx, - long imageNativeBuffer, int imageFormat, long timestampNs, long dataSpace, + long imageNativeBuffer, int imageFormat, long timestampNs, int dataSpace, int left, int top, int right, int bottom, int transform, int scalingMode); private synchronized native int nativeAttachAndQueueGraphicBuffer(long nativeCtx, - GraphicBuffer graphicBuffer, int imageFormat, long timestampNs, long dataSpace, + GraphicBuffer graphicBuffer, int imageFormat, long timestampNs, int dataSpace, int left, int top, int right, int bottom, int transform, int scalingMode); private synchronized native void cancelImage(long nativeCtx, Image image); diff --git a/media/java/android/media/PublicFormatUtils.java b/media/java/android/media/PublicFormatUtils.java index 6268804128c6..209e1c892045 100644 --- a/media/java/android/media/PublicFormatUtils.java +++ b/media/java/android/media/PublicFormatUtils.java @@ -15,6 +15,8 @@ */ package android.media; +import android.hardware.DataSpace; + /** * Package private utility class for PublicFormat related methods. */ @@ -22,13 +24,13 @@ class PublicFormatUtils { public static int getHalFormat(int imageFormat) { return nativeGetHalFormat(imageFormat); } - public static long getHalDataspace(int imageFormat) { + public static int getHalDataspace(int imageFormat) { return nativeGetHalDataspace(imageFormat); } - public static int getPublicFormat(int imageFormat, long dataspace) { + public static int getPublicFormat(int imageFormat, @DataSpace.NamedDataSpace int dataspace) { return nativeGetPublicFormat(imageFormat, dataspace); } private static native int nativeGetHalFormat(int imageFormat); - private static native long nativeGetHalDataspace(int imageFormat); - private static native int nativeGetPublicFormat(int imageFormat, long dataspace); + private static native int nativeGetHalDataspace(int imageFormat); + private static native int nativeGetPublicFormat(int imageFormat, int dataspace); } diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp index 6002e2884db8..4d6739e8fa52 100644 --- a/media/jni/android_media_ImageReader.cpp +++ b/media/jni/android_media_ImageReader.cpp @@ -322,7 +322,7 @@ static void ImageReader_classInit(JNIEnv* env, jclass clazz) ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID); gSurfaceImageClassInfo.mDataSpace = env->GetFieldID( - imageClazz, ANDROID_MEDIA_SURFACEIMAGE_DS_JNI_ID, "J"); + imageClazz, ANDROID_MEDIA_SURFACEIMAGE_DS_JNI_ID, "I"); LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mDataSpace == NULL, "can't find android/graphics/ImageReader.%s", ANDROID_MEDIA_SURFACEIMAGE_DS_JNI_ID); @@ -375,7 +375,7 @@ static void ImageReader_classInit(JNIEnv* env, jclass clazz) } static void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, jint width, jint height, - jint maxImages, jlong ndkUsage, jint nativeFormat, jlong dataSpace) { + jint maxImages, jlong ndkUsage, jint nativeFormat, jint dataSpace) { status_t res; ALOGV("%s: width:%d, height: %d, nativeFormat: %d, maxImages:%d", @@ -624,7 +624,7 @@ static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, jobject image, env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp, static_cast<jlong>(buffer->mTimestamp)); env->SetLongField(image, gSurfaceImageClassInfo.mDataSpace, - static_cast<jlong>(buffer->mDataSpace)); + static_cast<jint>(buffer->mDataSpace)); auto transform = buffer->mTransform; if (buffer->mTransformToDisplayInverse) { transform |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; @@ -954,7 +954,7 @@ static jobject Image_getHardwareBuffer(JNIEnv* env, jobject thiz) { static const JNINativeMethod gImageReaderMethods[] = { {"nativeClassInit", "()V", (void*)ImageReader_classInit }, - {"nativeInit", "(Ljava/lang/Object;IIIJIJ)V", (void*)ImageReader_init }, + {"nativeInit", "(Ljava/lang/Object;IIIJII)V", (void*)ImageReader_init }, {"nativeClose", "()V", (void*)ImageReader_close }, {"nativeReleaseImage", "(Landroid/media/Image;)V", (void*)ImageReader_imageRelease }, {"nativeImageSetup", "(Landroid/media/Image;Z)I", (void*)ImageReader_imageSetup }, diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp index 8f5c9da4fbe1..0f88afbf9a85 100644 --- a/media/jni/android_media_ImageWriter.cpp +++ b/media/jni/android_media_ImageWriter.cpp @@ -320,7 +320,7 @@ extern "C" { // -------------------------------Private method declarations-------------- static void Image_setNativeContext(JNIEnv* env, jobject thiz, - sp<GraphicBuffer> buffer, int fenceFd, long dataSpace); + sp<GraphicBuffer> buffer, int fenceFd, int dataSpace); static void Image_getNativeContext(JNIEnv* env, jobject thiz, GraphicBuffer** buffer, int* fenceFd); static void Image_unlockIfLocked(JNIEnv* env, jobject thiz); @@ -334,7 +334,7 @@ static void ImageWriter_classInit(JNIEnv* env, jclass clazz) { "can't find android/media/ImageWriter$WriterSurfaceImage"); gSurfaceImageClassInfo.mDataSpace = env->GetFieldID( - imageClazz, "mDataSpace", "J"); + imageClazz, "mDataSpace", "I"); LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mDataSpace == NULL, "can't find android/media/ImageWriter$WriterSurfaceImage.mDataSpace"); @@ -375,7 +375,7 @@ static void ImageWriter_classInit(JNIEnv* env, jclass clazz) { static jlong ImageWriter_init(JNIEnv* env, jobject thiz, jobject weakThiz, jobject jsurface, jint maxImages, jint userWidth, jint userHeight, jboolean useSurfaceImageFormatInfo, - jint hardwareBufferFormat, jlong dataSpace, jlong ndkUsage) { + jint hardwareBufferFormat, jint dataSpace, jlong ndkUsage) { status_t res; ALOGV("%s: maxImages:%d", __FUNCTION__, maxImages); @@ -626,7 +626,7 @@ static void ImageWriter_cancelImage(JNIEnv* env, jobject thiz, jlong nativeCtx, } static void ImageWriter_queueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, jobject image, - jlong timestampNs, jlong dataSpace, jint left, jint top, jint right, + jlong timestampNs, jint dataSpace, jint left, jint top, jint right, jint bottom, jint transform, jint scalingMode) { ALOGV("%s", __FUNCTION__); JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx); @@ -660,7 +660,7 @@ static void ImageWriter_queueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, j } // Set dataSpace - ALOGV("dataSpace to be queued: %" PRId64, dataSpace); + ALOGV("dataSpace to be queued: %d", dataSpace); res = native_window_set_buffers_data_space( anw.get(), static_cast<android_dataspace>(dataSpace)); if (res != OK) { @@ -719,7 +719,7 @@ static void ImageWriter_queueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, j } static status_t attachAndQeueuGraphicBuffer(JNIEnv* env, JNIImageWriterContext *ctx, - sp<Surface> surface, sp<GraphicBuffer> gb, jlong timestampNs, jlong dataSpace, + sp<Surface> surface, sp<GraphicBuffer> gb, jlong timestampNs, jint dataSpace, jint left, jint top, jint right, jint bottom, jint transform, jint scalingMode) { status_t res = OK; // Step 1. Attach Image @@ -748,7 +748,7 @@ static status_t attachAndQeueuGraphicBuffer(JNIEnv* env, JNIImageWriterContext * return res; } - ALOGV("dataSpace to be queued: %" PRId64, dataSpace); + ALOGV("dataSpace to be queued: %" PRId32, dataSpace); res = native_window_set_buffers_data_space( anw.get(), static_cast<android_dataspace>(dataSpace)); if (res != OK) { @@ -809,7 +809,7 @@ static status_t attachAndQeueuGraphicBuffer(JNIEnv* env, JNIImageWriterContext * } static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, - jlong nativeBuffer, jint imageFormat, jlong timestampNs, jlong dataSpace, + jlong nativeBuffer, jint imageFormat, jlong timestampNs, jint dataSpace, jint left, jint top, jint right, jint bottom, jint transform, jint scalingMode) { ALOGV("%s", __FUNCTION__); JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx); @@ -840,7 +840,7 @@ static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nat } static jint ImageWriter_attachAndQueueGraphicBuffer(JNIEnv* env, jobject thiz, jlong nativeCtx, - jobject buffer, jint format, jlong timestampNs, jlong dataSpace, jint left, jint top, + jobject buffer, jint format, jlong timestampNs, jint dataSpace, jint left, jint top, jint right, jint bottom, jint transform, jint scalingMode) { ALOGV("%s", __FUNCTION__); JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx); @@ -886,7 +886,7 @@ static void Image_getNativeContext(JNIEnv* env, jobject thiz, } static void Image_setNativeContext(JNIEnv* env, jobject thiz, - sp<GraphicBuffer> buffer, int fenceFd, long dataSpace) { + sp<GraphicBuffer> buffer, int fenceFd, int dataSpace) { ALOGV("%s:", __FUNCTION__); GraphicBuffer* p = NULL; Image_getNativeContext(env, thiz, &p, /*fenceFd*/NULL); @@ -958,7 +958,7 @@ static jint Image_getHeight(JNIEnv* env, jobject thiz) { return buffer->getHeight(); } -static jint Image_getFormat(JNIEnv* env, jobject thiz, jlong dataSpace) { +static jint Image_getFormat(JNIEnv* env, jobject thiz, jint dataSpace) { ALOGV("%s", __FUNCTION__); GraphicBuffer* buffer; Image_getNativeContext(env, thiz, &buffer, NULL); @@ -1042,7 +1042,7 @@ static bool Image_getLockedImageInfo(JNIEnv* env, LockedImage* buffer, int idx, } static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz, - int numPlanes, int writerFormat, long dataSpace) { + int numPlanes, int writerFormat, int dataSpace) { ALOGV("%s: create SurfacePlane array with size %d", __FUNCTION__, numPlanes); int rowStride, pixelStride; uint8_t *pData; @@ -1103,27 +1103,27 @@ static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz, static JNINativeMethod gImageWriterMethods[] = { {"nativeClassInit", "()V", (void*)ImageWriter_classInit }, - {"nativeInit", "(Ljava/lang/Object;Landroid/view/Surface;IIIZIJJ)J", + {"nativeInit", "(Ljava/lang/Object;Landroid/view/Surface;IIIZIIJ)J", (void*)ImageWriter_init }, {"nativeClose", "(J)V", (void*)ImageWriter_close }, {"nativeAttachAndQueueImage", - "(JJIJJIIIIII)I", + "(JJIJIIIIIII)I", (void*)ImageWriter_attachAndQueueImage }, {"nativeAttachAndQueueGraphicBuffer", - "(JLandroid/graphics/GraphicBuffer;IJJIIIIII)I", + "(JLandroid/graphics/GraphicBuffer;IJIIIIIII)I", (void*)ImageWriter_attachAndQueueGraphicBuffer }, {"nativeDequeueInputImage", "(JLandroid/media/Image;)V", (void*)ImageWriter_dequeueImage }, - {"nativeQueueInputImage", "(JLandroid/media/Image;JJIIIIII)V", + {"nativeQueueInputImage", "(JLandroid/media/Image;JIIIIIII)V", (void*)ImageWriter_queueImage }, {"cancelImage", "(JLandroid/media/Image;)V", (void*)ImageWriter_cancelImage }, }; static JNINativeMethod gImageMethods[] = { - {"nativeCreatePlanes", "(IIJ)[Landroid/media/ImageWriter$WriterSurfaceImage$SurfacePlane;", + {"nativeCreatePlanes", "(III)[Landroid/media/ImageWriter$WriterSurfaceImage$SurfacePlane;", (void*)Image_createSurfacePlanes }, {"nativeGetWidth", "()I", (void*)Image_getWidth }, {"nativeGetHeight", "()I", (void*)Image_getHeight }, - {"nativeGetFormat", "(J)I", (void*)Image_getFormat }, + {"nativeGetFormat", "(I)I", (void*)Image_getFormat }, {"nativeSetFenceFd", "(I)V", (void*)Image_setFenceFd }, {"nativeGetHardwareBuffer", "()Landroid/hardware/HardwareBuffer;", (void*)Image_getHardwareBuffer }, diff --git a/media/jni/android_media_PublicFormatUtils.cpp b/media/jni/android_media_PublicFormatUtils.cpp index 09ebdeeff06f..04494ad00a65 100644 --- a/media/jni/android_media_PublicFormatUtils.cpp +++ b/media/jni/android_media_PublicFormatUtils.cpp @@ -30,17 +30,17 @@ static jint android_media_PublicFormatUtils_getHalFormat(JNIEnv* /*env*/, jobjec return static_cast<jint>(nativeFormat); } -static jlong android_media_PublicFormatUtils_getHalDataspace(JNIEnv* /*env*/, jobject /*thiz*/, +static jint android_media_PublicFormatUtils_getHalDataspace(JNIEnv* /*env*/, jobject /*thiz*/, jint imageFormat) { PublicFormat publicFormat = static_cast<PublicFormat>(imageFormat); android_dataspace nativeDataspace = mapPublicFormatToHalDataspace(publicFormat); - return static_cast<jlong>(nativeDataspace); + return static_cast<jint>(nativeDataspace); } static jint android_media_PublicFormatUtils_getPublicFormat(JNIEnv* /*env*/, jobject /*thiz*/, jint hardwareBufferFormat, - jlong dataspace) { + jint dataspace) { PublicFormat nativeFormat = mapHalFormatDataspaceToPublicFormat( hardwareBufferFormat, static_cast<android_dataspace>(dataspace)); return static_cast<jint>(nativeFormat); @@ -48,8 +48,8 @@ static jint android_media_PublicFormatUtils_getPublicFormat(JNIEnv* /*env*/, job static const JNINativeMethod gMethods[] = { {"nativeGetHalFormat", "(I)I", (void*)android_media_PublicFormatUtils_getHalFormat}, - {"nativeGetHalDataspace", "(I)J", (void*)android_media_PublicFormatUtils_getHalDataspace}, - {"nativeGetPublicFormat", "(IJ)I",(void*)android_media_PublicFormatUtils_getPublicFormat} + {"nativeGetHalDataspace", "(I)I", (void*)android_media_PublicFormatUtils_getHalDataspace}, + {"nativeGetPublicFormat", "(II)I",(void*)android_media_PublicFormatUtils_getPublicFormat} }; int register_android_media_PublicFormatUtils(JNIEnv *env) { diff --git a/media/jni/audioeffect/Visualizer.cpp b/media/jni/audioeffect/Visualizer.cpp index 84a8d5122470..193a5d4f3dc0 100644 --- a/media/jni/audioeffect/Visualizer.cpp +++ b/media/jni/audioeffect/Visualizer.cpp @@ -49,7 +49,7 @@ Visualizer::~Visualizer() } status_t Visualizer::set(int32_t priority, - effect_callback_t cbf, + legacy_callback_t cbf, void* user, audio_session_t sessionId, audio_io_handle_t io, diff --git a/media/jni/audioeffect/Visualizer.h b/media/jni/audioeffect/Visualizer.h index aa07ce8055ae..c402c10ccae1 100644 --- a/media/jni/audioeffect/Visualizer.h +++ b/media/jni/audioeffect/Visualizer.h @@ -75,8 +75,8 @@ public: * See AudioEffect 'set' function for details on parameters. */ status_t set(int32_t priority = 0, - effect_callback_t cbf = NULL, - void* user = NULL, + legacy_callback_t cbf = nullptr, + void* user = nullptr, audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX, audio_io_handle_t io = AUDIO_IO_HANDLE_NONE, const AudioDeviceTypeAddr& device = {}, diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java index 6c52b5e8de1c..a17873869691 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java @@ -49,6 +49,7 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.notification.NotificationEntryManager; +import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.phone.DozeServiceHost; import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; @@ -174,6 +175,7 @@ public abstract class SystemUIDefaultModule { StatusBarStateController statusBarStateController, KeyguardBypassController bypassController, GroupMembershipManager groupManager, + VisualStabilityProvider visualStabilityProvider, ConfigurationController configurationController) { return new HeadsUpManagerPhone( context, @@ -181,6 +183,7 @@ public abstract class SystemUIDefaultModule { statusBarStateController, bypassController, groupManager, + visualStabilityProvider, configurationController ); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index a3f0a6dbf1da..eccf27ee8841 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -143,6 +143,7 @@ public class KeyguardIndicationController { private String mRestingIndication; private String mAlignmentIndication; + private CharSequence mTrustGrantedIndication; private CharSequence mTransientIndication; private CharSequence mBiometricMessage; protected ColorStateList mInitialTextColorState; @@ -609,7 +610,9 @@ public class KeyguardIndicationController { */ @VisibleForTesting String getTrustGrantedIndication() { - return mContext.getString(R.string.keyguard_indication_trust_unlocked); + return TextUtils.isEmpty(mTrustGrantedIndication) + ? mContext.getString(R.string.keyguard_indication_trust_unlocked) + : mTrustGrantedIndication.toString(); } /** @@ -909,6 +912,7 @@ public class KeyguardIndicationController { pw.println(" mTextView.getText(): " + ( mTopIndicationView == null ? null : mTopIndicationView.getText())); pw.println(" computePowerIndication(): " + computePowerIndication()); + pw.println(" trustGrantedIndication: " + getTrustGrantedIndication()); mRotateTextViewController.dump(fd, pw, args); } @@ -1054,6 +1058,22 @@ public class KeyguardIndicationController { || msgId == FaceManager.FACE_ERROR_CANCELED); } + + @Override + public void onTrustChanged(int userId) { + if (KeyguardUpdateMonitor.getCurrentUser() != userId) { + return; + } + updateTrust(userId, getTrustGrantedIndication(), getTrustManagedIndication()); + } + + @Override + public void showTrustGrantedMessage(CharSequence message) { + mTrustGrantedIndication = message; + updateTrust(KeyguardUpdateMonitor.getCurrentUser(), getTrustGrantedIndication(), + getTrustManagedIndication()); + } + @Override public void onTrustAgentErrorMessage(CharSequence message) { showBiometricMessage(message); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt index 3f866fe63f1d..5adf31b75fa7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt @@ -1,25 +1,57 @@ package com.android.systemui.statusbar.notification.collection.provider +import android.util.ArraySet import com.android.systemui.dagger.SysUISingleton import com.android.systemui.util.ListenerSet import javax.inject.Inject @SysUISingleton class VisualStabilityProvider @Inject constructor() { - private val listeners = ListenerSet<OnReorderingAllowedListener>() + /** All persistent and temporary listeners, in the order they were added */ + private val allListeners = ListenerSet<OnReorderingAllowedListener>() + + /** The subset of active listeners which are temporary (will be removed after called) */ + private val temporaryListeners = ArraySet<OnReorderingAllowedListener>() var isReorderingAllowed = true set(value) { if (field != value) { field = value if (value) { - listeners.forEach(OnReorderingAllowedListener::onReorderingAllowed) + notifyReorderingAllowed() } } } - fun addPersistentReorderingAllowedListener(listener: OnReorderingAllowedListener) = - listeners.addIfAbsent(listener) + private fun notifyReorderingAllowed() { + allListeners.forEach { listener -> + if (temporaryListeners.remove(listener)) { + allListeners.remove(listener) + } + listener.onReorderingAllowed() + } + } + + /** Add a listener which will be called until it is explicitly removed. */ + fun addPersistentReorderingAllowedListener(listener: OnReorderingAllowedListener) { + temporaryListeners.remove(listener) + allListeners.addIfAbsent(listener) + } + + /** Add a listener which will be removed when it is called. */ + fun addTemporaryReorderingAllowedListener(listener: OnReorderingAllowedListener) { + // Only add to the temporary set if it was added to the global set + // to keep permanent listeners permanent + if (allListeners.addIfAbsent(listener)) { + temporaryListeners.add(listener) + } + } + + /** Remove a listener from receiving any callbacks, whether it is persistent or temporary. */ + fun removeReorderingAllowedListener(listener: OnReorderingAllowedListener) { + temporaryListeners.remove(listener) + allListeners.remove(listener) + } } fun interface OnReorderingAllowedListener { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java index 77cff344558f..2a76418b1f03 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java @@ -33,7 +33,8 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; +import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener; +import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -52,7 +53,7 @@ import java.util.Stack; * A implementation of HeadsUpManager for phone and car. */ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, - VisualStabilityManager.Callback, OnHeadsUpChangedListener { + OnHeadsUpChangedListener { private static final String TAG = "HeadsUpManagerPhone"; @VisibleForTesting @@ -60,8 +61,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, private final KeyguardBypassController mBypassController; private final GroupMembershipManager mGroupMembershipManager; private final List<OnHeadsUpPhoneListenerChange> mHeadsUpPhoneListeners = new ArrayList<>(); - // TODO (b/162832756): remove visual stability manager when migrating to new pipeline - private VisualStabilityManager mVisualStabilityManager; + private final VisualStabilityProvider mVisualStabilityProvider; private boolean mReleaseOnExpandFinish; private boolean mTrackingHeadsUp; @@ -104,6 +104,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, StatusBarStateController statusBarStateController, KeyguardBypassController bypassController, GroupMembershipManager groupMembershipManager, + VisualStabilityProvider visualStabilityProvider, ConfigurationController configurationController) { super(context, logger); Resources resources = mContext.getResources(); @@ -111,6 +112,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, statusBarStateController.addCallback(mStatusBarStateListener); mBypassController = bypassController; mGroupMembershipManager = groupMembershipManager; + mVisualStabilityProvider = visualStabilityProvider; updateResources(); configurationController.addCallback(new ConfigurationController.ConfigurationListener() { @@ -126,10 +128,6 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, }); } - void setup(VisualStabilityManager visualStabilityManager) { - mVisualStabilityManager = visualStabilityManager; - } - public void setAnimationStateHandler(AnimationStateHandler handler) { mAnimationStateHandler = handler; } @@ -333,14 +331,13 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, // We should not defer the removal if reordering isn't allowed since otherwise // these won't disappear until reordering is allowed again, which happens only once // the notification panel is collapsed again. - return mVisualStabilityManager.isReorderingAllowed() && super.shouldExtendLifetime(entry); + return mVisualStabilityProvider.isReorderingAllowed() && super.shouldExtendLifetime(entry); } /////////////////////////////////////////////////////////////////////////////////////////////// - // VisualStabilityManager.Callback overrides: + // OnReorderingAllowedListener: - @Override - public void onChangeAllowed() { + private final OnReorderingAllowedListener mOnReorderingAllowedListener = () -> { mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(false); for (NotificationEntry entry : mEntriesToRemoveWhenReorderingAllowed) { if (isAlerting(entry.getKey())) { @@ -350,7 +347,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, } mEntriesToRemoveWhenReorderingAllowed.clear(); mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(true); - } + }; /////////////////////////////////////////////////////////////////////////////////////////////// // HeadsUpManager utility (protected) methods overrides: @@ -431,13 +428,13 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, public void setEntry(@NonNull final NotificationEntry entry) { Runnable removeHeadsUpRunnable = () -> { - if (!mVisualStabilityManager.isReorderingAllowed() + if (!mVisualStabilityProvider.isReorderingAllowed() // We don't want to allow reordering while pulsing, but headsup need to // time out anyway && !entry.showingPulsing()) { mEntriesToRemoveWhenReorderingAllowed.add(entry); - mVisualStabilityManager.addReorderingAllowedCallback(HeadsUpManagerPhone.this, - false /* persistent */); + mVisualStabilityProvider.addTemporaryReorderingAllowedListener( + mOnReorderingAllowedListener); } else if (mTrackingHeadsUp) { mEntriesToRemoveAfterExpand.add(entry); } else { 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 c8cc807475f3..4748d9c4fa71 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -1185,10 +1185,11 @@ public class StatusBar extends CoreStartable implements }); initializer.initializeStatusBar(mStatusBarComponent); - mHeadsUpManager.setup(mVisualStabilityManager); mStatusBarTouchableRegionManager.setup(this, mNotificationShadeWindowView); mHeadsUpManager.addListener(mNotificationPanelViewController.getOnHeadsUpChangedListener()); - mHeadsUpManager.addListener(mVisualStabilityManager); + if (!mNotifPipelineFlags.isNewPipelineEnabled()) { + mHeadsUpManager.addListener(mVisualStabilityManager); + } mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager); createNavigationBar(result); diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java index 66fc9ac15857..b7f90a479518 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java @@ -50,6 +50,7 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.notification.NotificationEntryManager; +import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.phone.DozeServiceHost; import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; @@ -167,6 +168,7 @@ public abstract class TvSystemUIModule { StatusBarStateController statusBarStateController, KeyguardBypassController bypassController, GroupMembershipManager groupManager, + VisualStabilityProvider visualStabilityProvider, ConfigurationController configurationController) { return new HeadsUpManagerPhone( context, @@ -174,6 +176,7 @@ public abstract class TvSystemUIModule { statusBarStateController, bypassController, groupManager, + visualStabilityProvider, configurationController ); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java index 529f6b47cf9e..98e285743706 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java @@ -774,6 +774,43 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { verify(mRotateTextViewController).hideIndication(INDICATION_TYPE_LOGOUT); } + @Test + public void onTrustGrantedMessageDoesNotShowUntilTrustGranted() { + createController(); + + // GIVEN a trust granted message but trust isn't granted + final String trustGrantedMsg = "testing trust granted message"; + mController.getKeyguardCallback().showTrustGrantedMessage(trustGrantedMsg); + + verifyHideIndication(INDICATION_TYPE_TRUST); + + // WHEN trust is granted + when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true); + mController.setVisible(true); + + // THEN verify the trust granted message shows + verifyIndicationMessage( + INDICATION_TYPE_TRUST, + trustGrantedMsg); + } + + @Test + public void onTrustGrantedMessageDoesShowsOnTrustGranted() { + createController(); + + // GIVEN trust is granted + when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true); + + // WHEN the showTrustGranted message is called + final String trustGrantedMsg = "testing trust granted message"; + mController.getKeyguardCallback().showTrustGrantedMessage(trustGrantedMsg); + + // THEN verify the trust granted message shows + verifyIndicationMessage( + INDICATION_TYPE_TRUST, + trustGrantedMsg); + } + private void sendUpdateDisclosureBroadcast() { mBroadcastReceiver.onReceive(mContext, new Intent()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt new file mode 100644 index 000000000000..b56f8e9364c4 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2022 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.systemui.statusbar.notification.collection.provider + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.util.mockito.mock +import org.junit.After +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.never +import org.mockito.Mockito.spy +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.Mockito.verifyNoMoreInteractions + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class VisualStabilityProviderTest : SysuiTestCase() { + private val visualStabilityProvider = VisualStabilityProvider() + private val listener: OnReorderingAllowedListener = mock() + + @After + fun tearDown() { + // Verify that every interaction is verified in every test + verifyNoMoreInteractions(listener) + } + + @Test + fun testPersistentListenerIgnoredIfStateNotChanged() { + visualStabilityProvider.addPersistentReorderingAllowedListener(listener) + visualStabilityProvider.isReorderingAllowed = true + verify(listener, never()).onReorderingAllowed() + } + + @Test + fun testPersistentListenerCalledTwice() { + visualStabilityProvider.addPersistentReorderingAllowedListener(listener) + visualStabilityProvider.isReorderingAllowed = false + visualStabilityProvider.isReorderingAllowed = true + verify(listener, times(1)).onReorderingAllowed() + + visualStabilityProvider.isReorderingAllowed = false + visualStabilityProvider.isReorderingAllowed = true + verify(listener, times(2)).onReorderingAllowed() + } + + @Test + fun testTemporaryListenerCalledOnce() { + visualStabilityProvider.addTemporaryReorderingAllowedListener(listener) + visualStabilityProvider.isReorderingAllowed = false + visualStabilityProvider.isReorderingAllowed = true + verify(listener, times(1)).onReorderingAllowed() + + visualStabilityProvider.isReorderingAllowed = false + visualStabilityProvider.isReorderingAllowed = true + verify(listener, times(1)).onReorderingAllowed() + } + + @Test + fun testPersistentListenerCanBeRemoved() { + visualStabilityProvider.addPersistentReorderingAllowedListener(listener) + visualStabilityProvider.removeReorderingAllowedListener(listener) + visualStabilityProvider.isReorderingAllowed = false + visualStabilityProvider.isReorderingAllowed = true + verify(listener, never()).onReorderingAllowed() + } + + @Test + fun testTemporaryListenerCanBeRemoved() { + visualStabilityProvider.addTemporaryReorderingAllowedListener(listener) + visualStabilityProvider.removeReorderingAllowedListener(listener) + visualStabilityProvider.isReorderingAllowed = false + visualStabilityProvider.isReorderingAllowed = true + verify(listener, never()).onReorderingAllowed() + } + + @Test + fun testPersistentListenerStaysPersistent() { + visualStabilityProvider.addPersistentReorderingAllowedListener(listener) + visualStabilityProvider.addTemporaryReorderingAllowedListener(listener) + visualStabilityProvider.isReorderingAllowed = false + visualStabilityProvider.isReorderingAllowed = true + verify(listener, times(1)).onReorderingAllowed() + + visualStabilityProvider.isReorderingAllowed = false + visualStabilityProvider.isReorderingAllowed = true + verify(listener, times(2)).onReorderingAllowed() + } + + @Test + fun testTemporaryListenerBecomesPersistent() { + visualStabilityProvider.addTemporaryReorderingAllowedListener(listener) + visualStabilityProvider.addPersistentReorderingAllowedListener(listener) + visualStabilityProvider.isReorderingAllowed = false + visualStabilityProvider.isReorderingAllowed = true + verify(listener, times(1)).onReorderingAllowed() + + visualStabilityProvider.isReorderingAllowed = false + visualStabilityProvider.isReorderingAllowed = true + verify(listener, times(2)).onReorderingAllowed() + } + + @Test + fun testPersistentListenerCanRemoveSelf() { + val selfRemovingListener = spy(object : OnReorderingAllowedListener { + override fun onReorderingAllowed() { + visualStabilityProvider.removeReorderingAllowedListener(this) + } + }) + visualStabilityProvider.addPersistentReorderingAllowedListener(selfRemovingListener) + visualStabilityProvider.isReorderingAllowed = false + visualStabilityProvider.isReorderingAllowed = true + verify(selfRemovingListener, times(1)).onReorderingAllowed() + + visualStabilityProvider.isReorderingAllowed = false + visualStabilityProvider.isReorderingAllowed = true + verify(selfRemovingListener, times(1)).onReorderingAllowed() + } + + @Test + fun testTemporaryListenerCanReAddSelf() { + val selfAddingListener = spy(object : OnReorderingAllowedListener { + override fun onReorderingAllowed() { + visualStabilityProvider.addTemporaryReorderingAllowedListener(this) + } + }) + visualStabilityProvider.addTemporaryReorderingAllowedListener(selfAddingListener) + visualStabilityProvider.isReorderingAllowed = false + visualStabilityProvider.isReorderingAllowed = true + verify(selfAddingListener, times(1)).onReorderingAllowed() + + visualStabilityProvider.isReorderingAllowed = false + visualStabilityProvider.isReorderingAllowed = true + verify(selfAddingListener, times(2)).onReorderingAllowed() + } +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java index 4457ae046260..72f8f70058fc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java @@ -60,6 +60,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; +import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; import com.android.systemui.statusbar.notification.icon.IconBuilder; import com.android.systemui.statusbar.notification.icon.IconManager; import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier; @@ -139,6 +140,7 @@ public class NotificationTestHelper { mStatusBarStateController, mock(KeyguardBypassController.class), mock(NotificationGroupManagerLegacy.class), + mock(VisualStabilityProvider.class), mock(ConfigurationControllerImpl.class) ); mHeadsUpManager.mHandler.removeCallbacksAndMessages(null); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java index e8b9c7b4d289..421d8f6a1889 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java @@ -36,7 +36,7 @@ import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; -import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; +import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.HeadsUpManagerLogger; @@ -62,7 +62,7 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest { @Mock private HeadsUpManagerLogger mHeadsUpManagerLogger; @Mock private NotificationGroupManagerLegacy mGroupManager; @Mock private View mNotificationShadeWindowView; - @Mock private VisualStabilityManager mVSManager; + @Mock private VisualStabilityProvider mVSProvider; @Mock private StatusBar mBar; @Mock private StatusBarStateController mStatusBarStateController; @Mock private KeyguardBypassController mBypassController; @@ -74,7 +74,7 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest { Context context, HeadsUpManagerLogger headsUpManagerLogger, NotificationGroupManagerLegacy groupManager, - VisualStabilityManager vsManager, + VisualStabilityProvider visualStabilityProvider, StatusBarStateController statusBarStateController, KeyguardBypassController keyguardBypassController, ConfigurationController configurationController @@ -85,9 +85,9 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest { statusBarStateController, keyguardBypassController, groupManager, + visualStabilityProvider, configurationController ); - setup(vsManager); mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME; mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME; } @@ -103,14 +103,14 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest { mDependency.injectMockDependency(AccessibilityManagerWrapper.class); when(accessibilityMgr.getRecommendedTimeoutMillis(anyInt(), anyInt())) .thenReturn(TEST_AUTO_DISMISS_TIME); - when(mVSManager.isReorderingAllowed()).thenReturn(true); + when(mVSProvider.isReorderingAllowed()).thenReturn(true); mDependency.injectMockDependency(NotificationShadeWindowController.class); mDependency.injectMockDependency(ConfigurationController.class); mHeadsUpManager = new TestableHeadsUpManagerPhone( mContext, mHeadsUpManagerLogger, mGroupManager, - mVSManager, + mVSProvider, mStatusBarStateController, mBypassController, mConfigurationController diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 4977278979d3..5cc163ddfe9d 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -257,7 +257,6 @@ import android.os.BinderProxy; import android.os.BugreportParams; import android.os.Build; import android.os.Bundle; -import android.os.ConditionVariable; import android.os.Debug; import android.os.DropBoxManager; import android.os.FactoryTest; @@ -15551,32 +15550,45 @@ public class ActivityManagerService extends IActivityManager.Stub * @throws RemoteException */ public void dumpAllResources(ParcelFileDescriptor fd, PrintWriter pw) throws RemoteException { - synchronized (mProcLock) { - mProcessList.forEachLruProcessesLOSP(true, app -> { - ConditionVariable lock = new ConditionVariable(); - RemoteCallback - finishCallback = new RemoteCallback(result -> lock.open(), null); - - pw.println(String.format("------ DUMP RESOURCES %s (%s) ------", - app.processName, - app.info.packageName)); - pw.flush(); + final ArrayList<ProcessRecord> processes = new ArrayList<>(); + synchronized (mPidsSelfLocked) { + processes.addAll(mProcessList.getLruProcessesLOSP()); + } + for (int i = 0, size = processes.size(); i < size; i++) { + ProcessRecord app = processes.get(i); + pw.println(String.format("------ DUMP RESOURCES %s (%s) ------", + app.processName, + app.info.packageName)); + pw.flush(); + try { + TransferPipe tp = new TransferPipe(); try { - app.getThread().dumpResources(fd.dup(), finishCallback); - lock.block(2000); - } catch (Exception e) { - pw.println(String.format( - "------ EXCEPTION DUMPING RESOURCES for %s (%s): %s ------", - app.processName, - app.info.packageName, - e.getMessage())); - pw.flush(); + IApplicationThread thread = app.getThread(); + if (thread != null) { + app.getThread().dumpResources(tp.getWriteFd(), null); + tp.go(fd.getFileDescriptor(), 2000); + pw.println(String.format("------ END DUMP RESOURCES %s (%s) ------", + app.processName, + app.info.packageName)); + pw.flush(); + } else { + pw.println(String.format( + "------ DUMP RESOURCES %s (%s) failed, no thread ------", + app.processName, + app.info.packageName)); + } + } finally { + tp.kill(); } - pw.println(String.format("------ END DUMP RESOURCES %s (%s) ------", + } catch (IOException e) { + pw.println(String.format( + "------ EXCEPTION DUMPING RESOURCES for %s (%s): %s ------", app.processName, - app.info.packageName)); + app.info.packageName, + e.getMessage())); pw.flush(); - }); + } + } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index dddec42e9b29..aafcc5831718 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -124,6 +124,7 @@ import static com.android.server.utils.PriorityDump.PRIORITY_ARG_NORMAL; import android.Manifest; import android.Manifest.permission; +import android.annotation.ElapsedRealtimeLong; import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.Nullable; @@ -851,7 +852,8 @@ public class NotificationManagerService extends SystemService { } if (summary.getSbn().getNotification().flags != oldFlags) { - mHandler.post(new EnqueueNotificationRunnable(userId, summary, isAppForeground)); + mHandler.post(new EnqueueNotificationRunnable(userId, summary, isAppForeground, + SystemClock.elapsedRealtime())); } } @@ -1373,7 +1375,7 @@ public class NotificationManagerService extends SystemService { // Force isAppForeground true here, because for sysui's purposes we // want to adjust the flag behaviour. mHandler.post(new EnqueueNotificationRunnable(r.getUser().getIdentifier(), - r, true /* isAppForeground*/)); + r, true /* isAppForeground*/, SystemClock.elapsedRealtime())); } } } @@ -1404,7 +1406,7 @@ public class NotificationManagerService extends SystemService { r.getNotification().flags |= FLAG_ONLY_ALERT_ONCE; mHandler.post( new EnqueueNotificationRunnable(r.getUser().getIdentifier(), r, - true /* isAppForeground */)); + true /* isAppForeground */, SystemClock.elapsedRealtime())); } } } @@ -2554,7 +2556,8 @@ public class NotificationManagerService extends SystemService { if (r != null) { final boolean isAppForeground = mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND; - mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground)); + mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground, + SystemClock.elapsedRealtime())); } } @@ -5750,7 +5753,8 @@ public class NotificationManagerService extends SystemService { final NotificationRecord removed = findNotificationByKeyLocked(summaries.remove(pkg)); if (removed != null) { boolean wasPosted = removeFromNotificationListsLocked(removed); - cancelNotificationLocked(removed, false, REASON_UNAUTOBUNDLED, wasPosted, null); + cancelNotificationLocked(removed, false, REASON_UNAUTOBUNDLED, wasPosted, null, + SystemClock.elapsedRealtime()); } } } @@ -6481,7 +6485,8 @@ public class NotificationManagerService extends SystemService { } finally { Binder.restoreCallingIdentity(token); } - mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground)); + mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground, + SystemClock.elapsedRealtime())); } private void onConversationRemovedInternal(String pkg, int uid, Set<String> shortcuts) { @@ -6625,7 +6630,8 @@ public class NotificationManagerService extends SystemService { r.getNotification().flags |= FLAG_ONLY_ALERT_ONCE; mHandler.post( new NotificationManagerService.EnqueueNotificationRunnable( - r.getUser().getIdentifier(), r, isAppForeground)); + r.getUser().getIdentifier(), r, isAppForeground, + SystemClock.elapsedRealtime())); } } } @@ -6929,7 +6935,8 @@ public class NotificationManagerService extends SystemService { NotificationRecordLogger.NotificationEvent.NOTIFICATION_SNOOZED, r); reportUserInteraction(r); boolean wasPosted = removeFromNotificationListsLocked(r); - cancelNotificationLocked(r, false, REASON_SNOOZED, wasPosted, null); + cancelNotificationLocked(r, false, REASON_SNOOZED, wasPosted, null, + SystemClock.elapsedRealtime()); updateLightsLocked(); if (mSnoozeCriterionId != null) { mAssistants.notifyAssistantSnoozedLocked(r, mSnoozeCriterionId); @@ -6956,12 +6963,14 @@ public class NotificationManagerService extends SystemService { private final int mRank; private final int mCount; private final ManagedServiceInfo mListener; + private final long mCancellationElapsedTimeMs; CancelNotificationRunnable(final int callingUid, final int callingPid, final String pkg, final String tag, final int id, final int mustHaveFlags, final int mustNotHaveFlags, final boolean sendDelete, final int userId, final int reason, int rank, int count, - final ManagedServiceInfo listener) { + final ManagedServiceInfo listener, + @ElapsedRealtimeLong long cancellationElapsedTimeMs) { this.mCallingUid = callingUid; this.mCallingPid = callingPid; this.mPkg = pkg; @@ -6975,6 +6984,7 @@ public class NotificationManagerService extends SystemService { this.mRank = rank; this.mCount = count; this.mListener = listener; + this.mCancellationElapsedTimeMs = cancellationElapsedTimeMs; } @Override @@ -7037,9 +7047,11 @@ public class NotificationManagerService extends SystemService { // Cancel the notification. boolean wasPosted = removeFromNotificationListsLocked(r); cancelNotificationLocked( - r, mSendDelete, mReason, mRank, mCount, wasPosted, listenerName); + r, mSendDelete, mReason, mRank, mCount, wasPosted, listenerName, + mCancellationElapsedTimeMs); cancelGroupChildrenLocked(r, mCallingUid, mCallingPid, listenerName, - mSendDelete, childrenFlagChecker, mReason); + mSendDelete, childrenFlagChecker, mReason, + mCancellationElapsedTimeMs); updateLightsLocked(); if (mShortcutHelper != null) { mShortcutHelper.maybeListenForShortcutChangesForBubbles(r, @@ -7101,11 +7113,14 @@ public class NotificationManagerService extends SystemService { private final NotificationRecord r; private final int userId; private final boolean isAppForeground; + private final long enqueueElapsedTimeMs; - EnqueueNotificationRunnable(int userId, NotificationRecord r, boolean foreground) { + EnqueueNotificationRunnable(int userId, NotificationRecord r, boolean foreground, + @ElapsedRealtimeLong long enqueueElapsedTimeMs) { this.userId = userId; this.r = r; this.isAppForeground = foreground; + this.enqueueElapsedTimeMs = enqueueElapsedTimeMs; } @Override @@ -7178,10 +7193,11 @@ public class NotificationManagerService extends SystemService { // tell the assistant service about the notification if (mAssistants.isEnabled()) { mAssistants.onNotificationEnqueuedLocked(r); - mHandler.postDelayed(new PostNotificationRunnable(r.getKey()), + mHandler.postDelayed( + new PostNotificationRunnable(r.getKey(), enqueueElapsedTimeMs), DELAY_FOR_ASSISTANT_TIME); } else { - mHandler.post(new PostNotificationRunnable(r.getKey())); + mHandler.post(new PostNotificationRunnable(r.getKey(), enqueueElapsedTimeMs)); } } } @@ -7204,9 +7220,11 @@ public class NotificationManagerService extends SystemService { protected class PostNotificationRunnable implements Runnable { private final String key; + private final long postElapsedTimeMs; - PostNotificationRunnable(String key) { + PostNotificationRunnable(String key, @ElapsedRealtimeLong long postElapsedTimeMs) { this.key = key; + this.postElapsedTimeMs = postElapsedTimeMs; } @Override @@ -7262,7 +7280,7 @@ public class NotificationManagerService extends SystemService { mNotificationList.add(r); mUsageStats.registerPostedByApp(r); mUsageStatsManagerInternal.reportNotificationPosted(r.getSbn().getOpPkg(), - r.getSbn().getUser(), SystemClock.elapsedRealtime()); + r.getSbn().getUser(), postElapsedTimeMs); final boolean isInterruptive = isVisuallyInterruptive(null, r); r.setInterruptive(isInterruptive); r.setTextChanged(isInterruptive); @@ -7271,7 +7289,7 @@ public class NotificationManagerService extends SystemService { mNotificationList.set(index, r); mUsageStats.registerUpdatedByApp(r, old); mUsageStatsManagerInternal.reportNotificationUpdated(r.getSbn().getOpPkg(), - r.getSbn().getUser(), SystemClock.elapsedRealtime()); + r.getSbn().getUser(), postElapsedTimeMs); // Make sure we don't lose the foreground service state. notification.flags |= old.getNotification().flags & FLAG_FOREGROUND_SERVICE; @@ -7576,7 +7594,7 @@ public class NotificationManagerService extends SystemService { // notification was a summary and its group key changed. if (oldIsSummary && (!isSummary || !oldGroup.equals(group))) { cancelGroupChildrenLocked(old, callingUid, callingPid, null, false /* sendDelete */, - childrenFlagChecker, REASON_APP_CANCEL); + childrenFlagChecker, REASON_APP_CANCEL, SystemClock.elapsedRealtime()); } } @@ -8662,14 +8680,17 @@ public class NotificationManagerService extends SystemService { @GuardedBy("mNotificationLock") private void cancelNotificationLocked(NotificationRecord r, boolean sendDelete, @NotificationListenerService.NotificationCancelReason int reason, - boolean wasPosted, String listenerName) { - cancelNotificationLocked(r, sendDelete, reason, -1, -1, wasPosted, listenerName); + boolean wasPosted, String listenerName, + @ElapsedRealtimeLong long cancellationElapsedTimeMs) { + cancelNotificationLocked(r, sendDelete, reason, -1, -1, wasPosted, listenerName, + cancellationElapsedTimeMs); } @GuardedBy("mNotificationLock") private void cancelNotificationLocked(NotificationRecord r, boolean sendDelete, @NotificationListenerService.NotificationCancelReason int reason, - int rank, int count, boolean wasPosted, String listenerName) { + int rank, int count, boolean wasPosted, String listenerName, + @ElapsedRealtimeLong long cancellationElapsedTimeMs) { final String canceledKey = r.getKey(); // Get pending intent used to create alarm, use FLAG_NO_CREATE if PendingIntent @@ -8755,7 +8776,7 @@ public class NotificationManagerService extends SystemService { case REASON_APP_CANCEL_ALL: mUsageStats.registerRemovedByApp(r); mUsageStatsManagerInternal.reportNotificationRemoved(r.getSbn().getOpPkg(), - r.getUser(), SystemClock.elapsedRealtime()); + r.getUser(), cancellationElapsedTimeMs); break; } @@ -8932,7 +8953,7 @@ public class NotificationManagerService extends SystemService { * and none of the {@code mustNotHaveFlags}. */ void cancelNotification(final int callingUid, final int callingPid, - final String pkg, final String tag, final int id, + final String pkg, final String tag, int id, final int mustHaveFlags, final int mustNotHaveFlags, final boolean sendDelete, final int userId, final int reason, final ManagedServiceInfo listener) { cancelNotification(callingUid, callingPid, pkg, tag, id, mustHaveFlags, mustNotHaveFlags, @@ -8954,7 +8975,7 @@ public class NotificationManagerService extends SystemService { // remove notification call ends up in not removing the notification. mHandler.scheduleCancelNotification(new CancelNotificationRunnable(callingUid, callingPid, pkg, tag, id, mustHaveFlags, mustNotHaveFlags, sendDelete, userId, reason, rank, - count, listener)); + count, listener, SystemClock.elapsedRealtime())); } /** @@ -8988,6 +9009,7 @@ public class NotificationManagerService extends SystemService { void cancelAllNotificationsInt(int callingUid, int callingPid, String pkg, String channelId, int mustHaveFlags, int mustNotHaveFlags, boolean doit, int userId, int reason, ManagedServiceInfo listener) { + final long cancellationElapsedTimeMs = SystemClock.elapsedRealtime(); mHandler.post(new Runnable() { @Override public void run() { @@ -9015,11 +9037,12 @@ public class NotificationManagerService extends SystemService { cancelAllNotificationsByListLocked(mNotificationList, callingUid, callingPid, pkg, true /*nullPkgIndicatesUserSwitch*/, channelId, flagChecker, false /*includeCurrentProfiles*/, userId, false /*sendDelete*/, reason, - listenerName, true /* wasPosted */); + listenerName, true /* wasPosted */, cancellationElapsedTimeMs); cancelAllNotificationsByListLocked(mEnqueuedNotifications, callingUid, callingPid, pkg, true /*nullPkgIndicatesUserSwitch*/, channelId, flagChecker, false /*includeCurrentProfiles*/, userId, - false /*sendDelete*/, reason, listenerName, false /* wasPosted */); + false /*sendDelete*/, reason, listenerName, false /* wasPosted */, + cancellationElapsedTimeMs); mSnoozeHelper.cancel(userId, pkg); } } @@ -9035,7 +9058,8 @@ public class NotificationManagerService extends SystemService { private void cancelAllNotificationsByListLocked(ArrayList<NotificationRecord> notificationList, int callingUid, int callingPid, String pkg, boolean nullPkgIndicatesUserSwitch, String channelId, FlagChecker flagChecker, boolean includeCurrentProfiles, int userId, - boolean sendDelete, int reason, String listenerName, boolean wasPosted) { + boolean sendDelete, int reason, String listenerName, boolean wasPosted, + @ElapsedRealtimeLong long cancellationElapsedTimeMs) { Set<String> childNotifications = null; for (int i = notificationList.size() - 1; i >= 0; --i) { NotificationRecord r = notificationList.get(i); @@ -9069,7 +9093,8 @@ public class NotificationManagerService extends SystemService { notificationList.remove(i); mNotificationsByKey.remove(r.getKey()); r.recordDismissalSentiment(NotificationStats.DISMISS_SENTIMENT_NEUTRAL); - cancelNotificationLocked(r, sendDelete, reason, wasPosted, listenerName); + cancelNotificationLocked(r, sendDelete, reason, wasPosted, listenerName, + cancellationElapsedTimeMs); } if (childNotifications != null) { final int M = notificationList.size(); @@ -9081,7 +9106,8 @@ public class NotificationManagerService extends SystemService { notificationList.remove(i); mNotificationsByKey.remove(r.getKey()); r.recordDismissalSentiment(NotificationStats.DISMISS_SENTIMENT_NEUTRAL); - cancelNotificationLocked(r, sendDelete, reason, wasPosted, listenerName); + cancelNotificationLocked(r, sendDelete, reason, wasPosted, listenerName, + cancellationElapsedTimeMs); } } updateLightsLocked(); @@ -9127,6 +9153,7 @@ public class NotificationManagerService extends SystemService { @GuardedBy("mNotificationLock") void cancelAllLocked(int callingUid, int callingPid, int userId, int reason, ManagedServiceInfo listener, boolean includeCurrentProfiles) { + final long cancellationElapsedTimeMs = SystemClock.elapsedRealtime(); mHandler.post(new Runnable() { @Override public void run() { @@ -9151,11 +9178,11 @@ public class NotificationManagerService extends SystemService { cancelAllNotificationsByListLocked(mNotificationList, callingUid, callingPid, null, false /*nullPkgIndicatesUserSwitch*/, null, flagChecker, includeCurrentProfiles, userId, true /*sendDelete*/, reason, - listenerName, true); + listenerName, true, cancellationElapsedTimeMs); cancelAllNotificationsByListLocked(mEnqueuedNotifications, callingUid, callingPid, null, false /*nullPkgIndicatesUserSwitch*/, null, flagChecker, includeCurrentProfiles, userId, true /*sendDelete*/, - reason, listenerName, false); + reason, listenerName, false, cancellationElapsedTimeMs); mSnoozeHelper.cancel(userId, includeCurrentProfiles); } } @@ -9165,7 +9192,8 @@ public class NotificationManagerService extends SystemService { // Warning: The caller is responsible for invoking updateLightsLocked(). @GuardedBy("mNotificationLock") private void cancelGroupChildrenLocked(NotificationRecord r, int callingUid, int callingPid, - String listenerName, boolean sendDelete, FlagChecker flagChecker, int reason) { + String listenerName, boolean sendDelete, FlagChecker flagChecker, int reason, + @ElapsedRealtimeLong long cancellationElapsedTimeMs) { Notification n = r.getNotification(); if (!n.isGroupSummary()) { return; @@ -9179,16 +9207,16 @@ public class NotificationManagerService extends SystemService { } cancelGroupChildrenByListLocked(mNotificationList, r, callingUid, callingPid, listenerName, - sendDelete, true, flagChecker, reason); + sendDelete, true, flagChecker, reason, cancellationElapsedTimeMs); cancelGroupChildrenByListLocked(mEnqueuedNotifications, r, callingUid, callingPid, - listenerName, sendDelete, false, flagChecker, reason); + listenerName, sendDelete, false, flagChecker, reason, cancellationElapsedTimeMs); } @GuardedBy("mNotificationLock") private void cancelGroupChildrenByListLocked(ArrayList<NotificationRecord> notificationList, NotificationRecord parentNotification, int callingUid, int callingPid, String listenerName, boolean sendDelete, boolean wasPosted, FlagChecker flagChecker, - int reason) { + int reason, @ElapsedRealtimeLong long cancellationElapsedTimeMs) { final String pkg = parentNotification.getSbn().getPackageName(); final int userId = parentNotification.getUserId(); final int childReason = REASON_GROUP_SUMMARY_CANCELED; @@ -9204,7 +9232,8 @@ public class NotificationManagerService extends SystemService { childSbn.getTag(), userId, 0, 0, childReason, listenerName); notificationList.remove(i); mNotificationsByKey.remove(childR.getKey()); - cancelNotificationLocked(childR, sendDelete, childReason, wasPosted, listenerName); + cancelNotificationLocked(childR, sendDelete, childReason, wasPosted, listenerName, + cancellationElapsedTimeMs); } } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 9f92294135c0..9ecb14a769a4 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -1335,7 +1335,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey()); + mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -1356,7 +1356,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(IMPORTANCE_NONE); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey()); + mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -3918,7 +3918,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false); mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey()); + mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -3935,7 +3935,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { r = generateNotificationRecord(mTestNotificationChannel, 0, null, false); mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey()); + mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -3951,7 +3951,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey()); + mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -3964,12 +3964,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { r.setCriticality(CriticalNotificationExtractor.CRITICAL_LOW); mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey()); + mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); runnable.run(); r = generateNotificationRecord(mTestNotificationChannel, 1, null, false); r.setCriticality(CriticalNotificationExtractor.CRITICAL); - runnable = mService.new PostNotificationRunnable(r.getKey()); + runnable = mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); mService.addEnqueuedNotification(r); runnable.run(); @@ -4412,7 +4412,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.addEnqueuedNotification(original); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(original.getKey()); + mService.new PostNotificationRunnable(original.getKey(), + SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -4433,7 +4434,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.addEnqueuedNotification(update); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(update.getKey()); + mService.new PostNotificationRunnable(update.getKey(), + SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -6475,7 +6477,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertNull(update.getSbn().getNotification().getSmallIcon()); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(update.getKey()); + mService.new PostNotificationRunnable(update.getKey(), + SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java index da5496da1bfa..fec5405c3390 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java @@ -91,6 +91,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.Process; import android.os.RemoteException; +import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; @@ -656,7 +657,7 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey()); + mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -789,7 +790,7 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey()); + mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -805,7 +806,7 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); mService.addEnqueuedNotification(r); - runnable = mService.new PostNotificationRunnable(r.getKey()); + runnable = mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -821,7 +822,7 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); mService.addEnqueuedNotification(r); - runnable = mService.new PostNotificationRunnable(r.getKey()); + runnable = mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index a7d44f99e2a8..dbdb1985724f 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -359,6 +359,12 @@ public class CarrierConfigManager { KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL = "require_entitlement_checks_bool"; /** + * Flag indicating if the carrier supports tethering of mobile data. + */ + public static final String KEY_CARRIER_SUPPORTS_TETHERING_BOOL = + "carrier_supports_tethering_bool"; + + /** * Flag indicating whether radio is to be restarted on error PDP_FAIL_REGULAR_DEACTIVATION * This is false by default. * @@ -8379,6 +8385,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_VOICE_PRIVACY_DISABLE_UI_BOOL, false); sDefaults.putBoolean(KEY_WORLD_PHONE_BOOL, false); sDefaults.putBoolean(KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true); + sDefaults.putBoolean(KEY_CARRIER_SUPPORTS_TETHERING_BOOL, true); sDefaults.putBoolean(KEY_RESTART_RADIO_ON_PDP_FAIL_REGULAR_DEACTIVATION_BOOL, false); sDefaults.putIntArray(KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY, new int[]{}); sDefaults.putInt(KEY_VOLTE_REPLACEMENT_RAT_INT, 0); diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt index d38a719b2372..065b1c27b837 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt @@ -54,7 +54,7 @@ import org.junit.runners.Parameterized @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group1 -class OpenAppColdTest(testSpec: FlickerTestParameter) : OpenAppTransition(testSpec) { +class OpenAppColdTest(testSpec: FlickerTestParameter) : OpenAppFromLauncherTransition(testSpec) { /** * Defines the transition used to run the test */ @@ -104,11 +104,6 @@ class OpenAppColdTest(testSpec: FlickerTestParameter) : OpenAppTransition(testSp /** {@inheritDoc} */ @Presubmit @Test - override fun launcherWindowBecomesInvisible() = super.launcherWindowBecomesInvisible() - - /** {@inheritDoc} */ - @Presubmit - @Test override fun navBarLayerIsVisible() = super.navBarLayerIsVisible() /** {@inheritDoc} */ diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt new file mode 100644 index 000000000000..c6e92adce8c7 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt @@ -0,0 +1,71 @@ +/* + * 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.server.wm.flicker.launch + +import android.platform.test.annotations.Presubmit +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.LAUNCHER_COMPONENT +import com.android.server.wm.flicker.replacesLayer +import com.android.server.wm.traces.common.FlickerComponentName +import org.junit.Test + +/** + * Base class for app launch tests + */ +abstract class OpenAppFromLauncherTransition(testSpec: FlickerTestParameter) + : OpenAppTransition(testSpec) { + + /** + * Checks that the focus changes from the launcher to [testApp] + */ + @Presubmit + @Test + open fun focusChanges() { + testSpec.assertEventLog { + this.focusChanges("NexusLauncherActivity", testApp.`package`) + } + } + + /** + * Checks that [LAUNCHER_COMPONENT] layer is visible at the start of the transition, and + * is replaced by [testApp], which remains visible until the end + */ + open fun appLayerReplacesLauncher() { + testSpec.replacesLayer(LAUNCHER_COMPONENT, testApp.component, + ignoreEntriesWithRotationLayer = true, ignoreSnapshot = true, + ignoreSplashscreen = true) + } + + /** + * Checks that [LAUNCHER_COMPONENT] window is visible at the start of the transition, and + * is replaced by a snapshot or splash screen (optional), and finally, is replaced by + * [testApp], which remains visible until the end + */ + @Presubmit + @Test + open fun appWindowReplacesLauncherAsTopWindow() { + testSpec.assertWm { + this.isAppWindowOnTop(LAUNCHER_COMPONENT) + .then() + .isAppWindowOnTop(FlickerComponentName.SNAPSHOT, isOptional = true) + .then() + .isAppWindowOnTop(FlickerComponentName.SPLASH_SCREEN, isOptional = true) + .then() + .isAppWindowOnTop(testApp.component) + } + } +}
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt new file mode 100644 index 000000000000..f47e2726e6ad --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.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.server.wm.flicker.launch + +import android.platform.test.annotations.Presubmit +import androidx.test.filters.FlakyTest +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.traces.common.FlickerComponentName +import org.junit.Test + +/** + * Base class for app launch tests from lock screen + */ +abstract class OpenAppFromLockTransition(testSpec: FlickerTestParameter) + : OpenAppTransition(testSpec) { + + /** + * Defines the transition used to run the test + */ + override val transition: FlickerBuilder.() -> Unit + get() = { + super.transition(this) + setup { + eachRun { + device.sleep() + wmHelper.waitFor("noAppWindowsOnTop") { + it.wmState.topVisibleAppWindow.isEmpty() + } + } + } + teardown { + eachRun { + testApp.exit(wmHelper) + } + } + transitions { + testApp.launchViaIntent(wmHelper) + wmHelper.waitForFullScreenApp(testApp.component) + } + } + + /** + * Check that we go from no focus to focus on the [testApp] + */ + @Presubmit + @Test + open fun focusChanges() { + testSpec.assertEventLog { + this.focusChanges("", testApp.`package`) + } + } + + /** + * Checks that we start of with no top windows and then [testApp] becomes the first and only top + * window of the transition, with snapshot or splash screen windows optionally showing first. + */ + @FlakyTest(bugId = 203538234) + @Test + open fun appWindowBecomesFirstAndOnlyTopWindow() { + testSpec.assertWm { + this.hasNoVisibleAppWindow() + .then() + .isAppWindowOnTop(FlickerComponentName.SNAPSHOT, isOptional = true) + .then() + .isAppWindowOnTop(FlickerComponentName.SPLASH_SCREEN, isOptional = true) + .then() + .isAppWindowOnTop(testApp.component) + } + } + + /** + * Checks that the screen is locked at the start of the transition ([colorFadComponent]) + * layer is visible + */ + @Presubmit + @Test + fun screenLockedStart() { + testSpec.assertLayersStart { + isEmpty() + } + } + + /** {@inheritDoc} */ + @FlakyTest(bugId = 203538234) + @Test + override fun appWindowBecomesVisible() = super.appWindowBecomesVisible() +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt index 61df403dd9ba..3a2eba1d851b 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt @@ -62,7 +62,8 @@ import org.junit.runners.Parameterized @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group1 -class OpenAppFromOverviewTest(testSpec: FlickerTestParameter) : OpenAppTransition(testSpec) { +class OpenAppFromOverviewTest(testSpec: FlickerTestParameter) + : OpenAppFromLauncherTransition(testSpec) { /** * Defines the transition used to run the test */ @@ -116,17 +117,22 @@ class OpenAppFromOverviewTest(testSpec: FlickerTestParameter) : OpenAppTransitio /** {@inheritDoc} */ @Presubmit @Test - override fun launcherWindowBecomesInvisible() = super.launcherWindowBecomesInvisible() + override fun navBarLayerIsVisible() = super.navBarLayerIsVisible() /** {@inheritDoc} */ @Presubmit @Test - override fun navBarLayerIsVisible() = super.navBarLayerIsVisible() + override fun navBarWindowIsVisible() = super.navBarWindowIsVisible() /** {@inheritDoc} */ @Presubmit @Test - override fun navBarWindowIsVisible() = super.navBarWindowIsVisible() + override fun appLayerBecomesVisible() = super.appLayerBecomesVisible_warmStart() + + /** {@inheritDoc} */ + @Presubmit + @Test + override fun appWindowBecomesVisible() = super.appWindowBecomesVisible_warmStart() /** {@inheritDoc} */ @Presubmit diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt index 12177ed653c8..6365e7b9e967 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt @@ -27,10 +27,8 @@ import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group1 import com.android.server.wm.flicker.helpers.NonResizeableAppHelper -import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.traces.common.FlickerComponentName -import com.google.common.truth.Truth import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -59,36 +57,12 @@ import org.junit.runners.Parameterized @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group1 -class OpenAppNonResizeableTest(testSpec: FlickerTestParameter) : OpenAppTransition(testSpec) { +class OpenAppNonResizeableTest(testSpec: FlickerTestParameter) + : OpenAppFromLockTransition(testSpec) { override val testApp = NonResizeableAppHelper(instrumentation) private val colorFadComponent = FlickerComponentName("", "ColorFade BLAST#") /** - * Defines the transition used to run the test - */ - override val transition: FlickerBuilder.() -> Unit - get() = { - super.transition(this) - setup { - eachRun { - device.sleep() - wmHelper.waitFor("noAppWindowsOnTop") { - it.wmState.topVisibleAppWindow.isEmpty() - } - } - } - teardown { - eachRun { - testApp.exit(wmHelper) - } - } - transitions { - testApp.launchViaIntent(wmHelper) - wmHelper.waitForFullScreenApp(testApp.component) - } - } - - /** * Checks that the nav bar layer starts invisible, becomes visible during unlocking animation * and remains visible at the end */ @@ -103,41 +77,6 @@ class OpenAppNonResizeableTest(testSpec: FlickerTestParameter) : OpenAppTransiti } /** - * Checks that the app layer doesn't exist at the start of the transition, that it is - * created (invisible) and becomes visible during the transition - */ - @Postsubmit - @Test - fun appLayerBecomesVisible() { - testSpec.assertLayers { - this.notContains(testApp.component) - .then() - .isInvisible(testApp.component) - .then() - .isVisible(testApp.component) - } - } - - /** - * Checks that the app window doesn't exist at the start of the transition, that it is - * created (invisible - optional) and becomes visible during the transition - * - * The `isAppWindowInvisible` step is optional because we log once per frame, upon logging, - * the window may be visible or not depending on what was processed until that moment. - */ - @FlakyTest(bugId = 203538234) - @Test - fun appWindowBecomesVisible() { - testSpec.assertWm { - this.notContains(testApp.component) - .then() - .isAppWindowInvisible(testApp.component, isOptional = true) - .then() - .isAppWindowVisible(testApp.component) - } - } - - /** * Checks if [testApp] is visible at the end of the transition */ @Presubmit @@ -193,6 +132,7 @@ class OpenAppNonResizeableTest(testSpec: FlickerTestParameter) : OpenAppTransiti } } + /** {@inheritDoc} */ @FlakyTest @Test override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales() @@ -208,44 +148,6 @@ class OpenAppNonResizeableTest(testSpec: FlickerTestParameter) : OpenAppTransiti @Test override fun entireScreenCovered() = super.entireScreenCovered() - /** - * Checks that the focus changes from the launcher to [testApp] - */ - @FlakyTest - @Test - override fun focusChanges() = super.focusChanges() - - /** - * Checks that the screen is locked at the start of the transition ([colorFadComponent]) - * layer is visible - */ - @Presubmit - @Test - fun screenLockedStart() { - testSpec.assertLayersStart { - isEmpty() - } - } - - /** - * This test checks if the launcher is visible at the start and the app at the end, - * it cannot use the regular assertion (check over time), because on lock screen neither - * the app not the launcher are visible, and there is no top visible window. - */ - @FlakyTest(bugId = 203538234) - @Test - override fun appWindowReplacesLauncherAsTopWindow() { - testSpec.assertWm { - this.invoke("noAppWindowsOnTop") { - Truth.assertWithMessage("Should not have any app window on top " + - "when the screen is locked") - .that(it.wmState.topVisibleAppWindow) - .isEmpty() - }.then() - .isAppWindowOnTop(testApp.component) - } - } - companion object { /** * Creates the test configurations. @@ -265,4 +167,4 @@ class OpenAppNonResizeableTest(testSpec: FlickerTestParameter) : OpenAppTransiti ) } } -}
\ No newline at end of file +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt index b5c81bb39ed4..d2f6c7f144dd 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt @@ -17,21 +17,20 @@ package com.android.server.wm.flicker.launch import android.app.Instrumentation +import android.platform.test.annotations.FlakyTest import android.platform.test.annotations.Presubmit import androidx.test.platform.app.InstrumentationRegistry import com.android.server.wm.flicker.FlickerBuilderProvider import com.android.server.wm.flicker.FlickerTestParameter -import com.android.server.wm.flicker.LAUNCHER_COMPONENT import com.android.server.wm.flicker.dsl.FlickerBuilder -import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.helpers.SimpleAppHelper import com.android.server.wm.flicker.helpers.StandardAppHelper import com.android.server.wm.flicker.helpers.setRotation import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen +import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.navBarLayerIsVisible import com.android.server.wm.flicker.navBarLayerRotatesAndScales import com.android.server.wm.flicker.navBarWindowIsVisible -import com.android.server.wm.flicker.replacesLayer import com.android.server.wm.flicker.statusBarLayerIsVisible import com.android.server.wm.flicker.statusBarLayerRotatesScales import com.android.server.wm.flicker.statusBarWindowIsVisible @@ -151,53 +150,83 @@ abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) { open fun entireScreenCovered() = testSpec.entireScreenCovered() /** - * Checks that the focus changes from the launcher to [testApp] + * Checks that the app layer doesn't exist or is invisible at the start of the transition, but + * is created and/or becomes visible during the transition. */ @Presubmit @Test - open fun focusChanges() { - testSpec.assertEventLog { - this.focusChanges("NexusLauncherActivity", testApp.`package`) + open fun appLayerBecomesVisible() = appLayerBecomesVisible_coldStart() + + protected fun appLayerBecomesVisible_coldStart() { + testSpec.assertLayers { + this.notContains(testApp.component) + .then() + .isInvisible(testApp.component, isOptional = true) + .then() + .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true) + .then() + .isVisible(FlickerComponentName.SPLASH_SCREEN, isOptional = true) + .then() + .isVisible(testApp.component) } } - /** - * Checks that [LAUNCHER_COMPONENT] layer is visible at the start of the transition, and - * is replaced by [testApp], which remains visible until the end - */ - open fun appLayerReplacesLauncher() { - testSpec.replacesLayer(LAUNCHER_COMPONENT, testApp.component, - ignoreEntriesWithRotationLayer = true, ignoreSnapshot = true) + protected fun appLayerBecomesVisible_warmStart() { + testSpec.assertLayers { + this.isInvisible(testApp.component) + .then() + .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true) + .then() + .isVisible(FlickerComponentName.SPLASH_SCREEN, isOptional = true) + .then() + .isVisible(testApp.component) + } } /** - * Checks that [LAUNCHER_COMPONENT] window is visible at the start of the transition, and - * is replaced by a snapshot or splash screen (optional), and finally, is replaced by - * [testApp], which remains visible until the end + * Checks that the app window doesn't exist at the start of the transition, that it is + * created (invisible - optional) and becomes visible during the transition + * + * The `isAppWindowInvisible` step is optional because we log once per frame, upon logging, + * the window may be visible or not depending on what was processed until that moment. */ @Presubmit @Test - open fun appWindowReplacesLauncherAsTopWindow() { + open fun appWindowBecomesVisible() = appWindowBecomesVisible_coldStart() + + protected fun appWindowBecomesVisible_coldStart() { testSpec.assertWm { - this.isAppWindowOnTop(LAUNCHER_COMPONENT) + this.notContains(testApp.component) .then() - .isAppWindowOnTop(FlickerComponentName.SNAPSHOT, isOptional = true) + .isAppWindowInvisible(testApp.component, isOptional = true) .then() - .isAppWindowOnTop(FlickerComponentName.SPLASH_SCREEN, isOptional = true) + .isAppWindowVisible(testApp.component) + } + } + + protected fun appWindowBecomesVisible_warmStart() { + testSpec.assertWm { + this.isAppWindowInvisible(testApp.component) .then() - .isAppWindowOnTop(testApp.component) + .isAppWindowVisible(testApp.component) } } /** - * Checks that [LAUNCHER_COMPONENT] window is visible at the start, and - * becomes invisible during the transition + * Checks that [testApp] window is not on top at the start of the transition, and then becomes + * the top visible window until the end of the transition. */ - open fun launcherWindowBecomesInvisible() { + @FlakyTest(bugId = 203538234) + @Test + open fun appWindowBecomesTopWindow() { testSpec.assertWm { - this.isAppWindowOnTop(LAUNCHER_COMPONENT) + this.isAppWindowNotOnTop(testApp.component) + .then() + .isAppWindowOnTop(FlickerComponentName.SNAPSHOT, isOptional = true) .then() - .isAppWindowNotOnTop(LAUNCHER_COMPONENT) + .isAppWindowOnTop(FlickerComponentName.SPLASH_SCREEN, isOptional = true) + .then() + .isAppWindowOnTop(testApp.component) } } -}
\ No newline at end of file +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt index 304e5165c3a8..3159bf187275 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt @@ -54,7 +54,8 @@ import org.junit.runners.Parameterized @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group1 -class OpenAppWarmTest(testSpec: FlickerTestParameter) : OpenAppTransition(testSpec) { +class OpenAppWarmTest(testSpec: FlickerTestParameter) + : OpenAppFromLauncherTransition(testSpec) { /** * Defines the transition used to run the test */ @@ -112,17 +113,22 @@ class OpenAppWarmTest(testSpec: FlickerTestParameter) : OpenAppTransition(testSp /** {@inheritDoc} */ @Presubmit @Test - override fun launcherWindowBecomesInvisible() = super.launcherWindowBecomesInvisible() + override fun navBarLayerIsVisible() = super.navBarLayerIsVisible() /** {@inheritDoc} */ @Presubmit @Test - override fun navBarLayerIsVisible() = super.navBarLayerIsVisible() + override fun navBarWindowIsVisible() = super.navBarWindowIsVisible() /** {@inheritDoc} */ @Presubmit @Test - override fun navBarWindowIsVisible() = super.navBarWindowIsVisible() + override fun appLayerBecomesVisible() = super.appLayerBecomesVisible_warmStart() + + /** {@inheritDoc} */ + @Presubmit + @Test + override fun appWindowBecomesVisible() = super.appWindowBecomesVisible_warmStart() companion object { /** |