diff options
40 files changed, 407 insertions, 287 deletions
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java index 99b297abe92a..0e45787c1340 100644 --- a/core/java/android/hardware/camera2/CameraDevice.java +++ b/core/java/android/hardware/camera2/CameraDevice.java @@ -283,7 +283,8 @@ public abstract class CameraDevice implements AutoCloseable { * @see StreamConfigurationMap#getInputFormats * @see StreamConfigurationMap#getInputSizes * @see StreamConfigurationMap#getValidOutputFormatsForInput - * @see StreamConfigurationMap#getOutputSizes + * @see StreamConfigurationMap#getOutputSizes(int) + * @see StreamConfigurationMap#getOutputSizes(Class) * @see android.media.ImageWriter * @see android.media.ImageReader * @deprecated Please use {@link diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index 85f8ca66715b..a64d66fade25 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -129,14 +129,17 @@ public final class CameraManager { /** * Enable physical camera availability callbacks when the logical camera is unavailable * - * <p>Previously once a logical camera becomes unavailable, no {@link - * #onPhysicalCameraAvailable} or {@link #onPhysicalCameraUnavailable} will be called until - * the logical camera becomes available again. The results in the app opening the logical - * camera not able to receive physical camera availability change.</p> - * - * <p>With this change, the {@link #onPhysicalCameraAvailable} and {@link - * #onPhysicalCameraUnavailable} can still be called while the logical camera is unavailable. - * </p> + * <p>Previously once a logical camera becomes unavailable, no + * {@link AvailabilityCallback#onPhysicalCameraAvailable} or + * {@link AvailabilityCallback#onPhysicalCameraUnavailable} will + * be called until the logical camera becomes available again. The + * results in the app opening the logical camera not able to + * receive physical camera availability change.</p> + * + * <p>With this change, the {@link + * AvailabilityCallback#onPhysicalCameraAvailable} and {@link + * AvailabilityCallback#onPhysicalCameraUnavailable} can still be + * called while the logical camera is unavailable. </p> */ @ChangeId @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) diff --git a/core/java/android/hardware/camera2/package.html b/core/java/android/hardware/camera2/package.html index 719c2f620234..3fd5d7c60832 100644 --- a/core/java/android/hardware/camera2/package.html +++ b/core/java/android/hardware/camera2/package.html @@ -62,12 +62,28 @@ RAW buffers for {@link android.hardware.camera2.DngCreator} can be done with {@link android.media.ImageReader} with the {@link android.graphics.ImageFormat#JPEG} and {@link android.graphics.ImageFormat#RAW_SENSOR} formats. Application-driven -processing of camera data in RenderScript, OpenGL ES, or directly in -managed or native code is best done through {@link -android.renderscript.Allocation} with a YUV {@link -android.renderscript.Type}, {@link android.graphics.SurfaceTexture}, -and {@link android.media.ImageReader} with a {@link -android.graphics.ImageFormat#YUV_420_888} format, respectively.</p> +processing of camera data in OpenGL ES, or directly in managed or +native code is best done through {@link +android.graphics.SurfaceTexture}, or {@link android.media.ImageReader} +with a {@link android.graphics.ImageFormat#YUV_420_888} format, +respectively. </p> + +<p>By default, YUV-format buffers provided by the camera are using the +JFIF YUV<->RGB transform matrix (equivalent to Rec.601 full-range +encoding), and after conversion to RGB with this matrix, the resulting +RGB data is in the sRGB colorspace. Captured JPEG images may contain +an ICC profile to specify their color space information; if not, they +should be assumed to be in the sRGB space as well. On some devices, +the output colorspace can be changed via {@link +android.hardware.camera2.params.SessionConfiguration#setColorSpace}. +</p> +<p> +Note that although the YUV->RGB transform is the JFIF matrix (Rec.601 +full-range), due to legacy and compatibility reasons, the output is in +the sRGB colorspace, which uses the Rec.709 color primaries. Image +processing code can safely treat the output RGB as being in the sRGB +colorspace. +</p> <p>The application then needs to construct a {@link android.hardware.camera2.CaptureRequest}, which defines all the diff --git a/core/java/android/hardware/camera2/params/ColorSpaceProfiles.java b/core/java/android/hardware/camera2/params/ColorSpaceProfiles.java index 2e3af80f9cc0..bb154a96cbe9 100644 --- a/core/java/android/hardware/camera2/params/ColorSpaceProfiles.java +++ b/core/java/android/hardware/camera2/params/ColorSpaceProfiles.java @@ -192,7 +192,7 @@ public final class ColorSpaceProfiles { * @see OutputConfiguration#setDynamicRangeProfile * @see SessionConfiguration#setColorSpace * @see ColorSpace.Named - * @see DynamicRangeProfiles.Profile + * @see DynamicRangeProfiles */ public @NonNull Set<Long> getSupportedDynamicRangeProfiles(@NonNull ColorSpace.Named colorSpace, @ImageFormat.Format int imageFormat) { @@ -230,7 +230,7 @@ public final class ColorSpaceProfiles { * @see SessionConfiguration#setColorSpace * @see OutputConfiguration#setDynamicRangeProfile * @see ColorSpace.Named - * @see DynamicRangeProfiles.Profile + * @see DynamicRangeProfiles */ public @NonNull Set<ColorSpace.Named> getSupportedColorSpacesForDynamicRange( @ImageFormat.Format int imageFormat, diff --git a/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java b/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java index 80db38fc9d8f..d4ce0ebbc528 100644 --- a/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java +++ b/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java @@ -45,7 +45,7 @@ import java.util.Set; * Immutable class to store the recommended stream configurations to set up * {@link android.view.Surface Surfaces} for creating a * {@link android.hardware.camera2.CameraCaptureSession capture session} with - * {@link android.hardware.camera2.CameraDevice#createCaptureSession}. + * {@link android.hardware.camera2.CameraDevice#createCaptureSession(SessionConfiguration)}. * * <p>The recommended list does not replace or deprecate the exhaustive complete list found in * {@link StreamConfigurationMap}. It is a suggestion about available power and performance @@ -70,7 +70,7 @@ import java.util.Set; * }</code></pre> * * @see CameraCharacteristics#getRecommendedStreamConfigurationMap - * @see CameraDevice#createCaptureSession + * @see CameraDevice#createCaptureSession(SessionConfiguration) */ public final class RecommendedStreamConfigurationMap { @@ -282,7 +282,7 @@ public final class RecommendedStreamConfigurationMap { /** * Determine whether or not output surfaces with a particular user-defined format can be passed - * {@link CameraDevice#createCaptureSession createCaptureSession}. + * {@link CameraDevice#createCaptureSession(SessionConfiguration) createCaptureSession}. * * <p> * For further information refer to {@link StreamConfigurationMap#isOutputSupportedFor}. @@ -292,7 +292,7 @@ public final class RecommendedStreamConfigurationMap { * @param format an image format from either {@link ImageFormat} or {@link PixelFormat} * @return * {@code true} if using a {@code surface} with this {@code format} will be - * supported with {@link CameraDevice#createCaptureSession} + * supported with {@link CameraDevice#createCaptureSession(SessionConfiguration)} * * @throws IllegalArgumentException * if the image format was not a defined named constant @@ -508,8 +508,10 @@ public final class RecommendedStreamConfigurationMap { } /** - * Determine whether or not the {@code surface} in its current state is suitable to be included - * in a {@link CameraDevice#createCaptureSession capture session} as an output. + * Determine whether or not the {@code surface} in its current + * state is suitable to be included in a {@link + * CameraDevice#createCaptureSession(SessionConfiguration) capture + * session} as an output. * * <p>For more information refer to {@link StreamConfigurationMap#isOutputSupportedFor}. * </p> diff --git a/core/java/android/hardware/camera2/params/SessionConfiguration.java b/core/java/android/hardware/camera2/params/SessionConfiguration.java index 385f10719509..8f611a831204 100644 --- a/core/java/android/hardware/camera2/params/SessionConfiguration.java +++ b/core/java/android/hardware/camera2/params/SessionConfiguration.java @@ -55,7 +55,7 @@ public final class SessionConfiguration implements Parcelable { * at regular non high speed FPS ranges and optionally {@link InputConfiguration} for * reprocessable sessions. * - * @see CameraDevice#createCaptureSession + * @see CameraDevice#createCaptureSession(SessionConfiguration) * @see CameraDevice#createReprocessableCaptureSession */ public static final int SESSION_REGULAR = CameraDevice.SESSION_OPERATION_MODE_NORMAL; @@ -110,10 +110,7 @@ public final class SessionConfiguration implements Parcelable { * * @see #SESSION_REGULAR * @see #SESSION_HIGH_SPEED - * @see CameraDevice#createCaptureSession(List, CameraCaptureSession.StateCallback, Handler) - * @see CameraDevice#createCaptureSessionByOutputConfigurations - * @see CameraDevice#createReprocessableCaptureSession - * @see CameraDevice#createConstrainedHighSpeedCaptureSession + * @see CameraDevice#createCaptureSession(SessionConfiguration) */ public SessionConfiguration(@SessionMode int sessionType, @NonNull List<OutputConfiguration> outputs, diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java index aabe149d16f5..ef0db7f8a41c 100644 --- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java +++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java @@ -41,7 +41,7 @@ import java.util.Set; * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP configurations} to set up * {@link android.view.Surface Surfaces} for creating a * {@link android.hardware.camera2.CameraCaptureSession capture session} with - * {@link android.hardware.camera2.CameraDevice#createCaptureSession}. + * {@link android.hardware.camera2.CameraDevice#createCaptureSession(SessionConfiguration)}. * <!-- TODO: link to input stream configuration --> * * <p>This is the authoritative list for all <!-- input/ -->output formats (and sizes respectively @@ -62,7 +62,7 @@ import java.util.Set; * }</code></pre> * * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP - * @see CameraDevice#createCaptureSession + * @see CameraDevice#createCaptureSession(SessionConfiguration) */ public final class StreamConfigurationMap { @@ -456,7 +456,7 @@ public final class StreamConfigurationMap { /** * Determine whether or not output surfaces with a particular user-defined format can be passed - * {@link CameraDevice#createCaptureSession createCaptureSession}. + * {@link CameraDevice#createCaptureSession(SessionConfiguration) createCaptureSession}. * * <p>This method determines that the output {@code format} is supported by the camera device; * each output {@code surface} target may or may not itself support that {@code format}. @@ -468,7 +468,7 @@ public final class StreamConfigurationMap { * @param format an image format from either {@link ImageFormat} or {@link PixelFormat} * @return * {@code true} iff using a {@code surface} with this {@code format} will be - * supported with {@link CameraDevice#createCaptureSession} + * supported with {@link CameraDevice#createCaptureSession(SessionConfiguration)} * * @throws IllegalArgumentException * if the image format was not a defined named constant @@ -476,7 +476,7 @@ public final class StreamConfigurationMap { * * @see ImageFormat * @see PixelFormat - * @see CameraDevice#createCaptureSession + * @see CameraDevice#createCaptureSession(SessionConfiguration) */ public boolean isOutputSupportedFor(int format) { checkArgumentFormat(format); @@ -521,7 +521,7 @@ public final class StreamConfigurationMap { * * <p>Generally speaking this means that creating a {@link Surface} from that class <i>may</i> * provide a producer endpoint that is suitable to be used with - * {@link CameraDevice#createCaptureSession}.</p> + * {@link CameraDevice#createCaptureSession(SessionConfiguration)}.</p> * * <p>Since not all of the above classes support output of all format and size combinations, * the particular combination should be queried with {@link #isOutputSupportedFor(Surface)}.</p> @@ -531,7 +531,7 @@ public final class StreamConfigurationMap { * * @throws NullPointerException if {@code klass} was {@code null} * - * @see CameraDevice#createCaptureSession + * @see CameraDevice#createCaptureSession(SessionConfiguration) * @see #isOutputSupportedFor(Surface) */ public static <T> boolean isOutputSupportedFor(Class<T> klass) { @@ -555,8 +555,10 @@ public final class StreamConfigurationMap { } /** - * Determine whether or not the {@code surface} in its current state is suitable to be included - * in a {@link CameraDevice#createCaptureSession capture session} as an output. + * Determine whether or not the {@code surface} in its current + * state is suitable to be included in a {@link + * CameraDevice#createCaptureSession(SessionConfiguration) capture + * session} as an output. * * <p>Not all surfaces are usable with the {@link CameraDevice}, and not all configurations * of that {@code surface} are compatible. Some classes that provide the {@code surface} are @@ -588,7 +590,7 @@ public final class StreamConfigurationMap { * @throws NullPointerException if {@code surface} was {@code null} * @throws IllegalArgumentException if the Surface endpoint is no longer valid * - * @see CameraDevice#createCaptureSession + * @see CameraDevice#createCaptureSession(SessionConfiguration) * @see #isOutputSupportedFor(Class) */ public boolean isOutputSupportedFor(Surface surface) { @@ -623,14 +625,16 @@ public final class StreamConfigurationMap { } /** - * Determine whether or not the particular stream configuration is suitable to be included - * in a {@link CameraDevice#createCaptureSession capture session} as an output. + * Determine whether or not the particular stream configuration is + * suitable to be included in a {@link + * CameraDevice#createCaptureSession(SessionConfiguration) capture + * session} as an output. * * @param size stream configuration size * @param format stream configuration format * @return {@code true} if this is supported, {@code false} otherwise * - * @see CameraDevice#createCaptureSession + * @see CameraDevice#createCaptureSession(SessionConfiguration) * @see #isOutputSupportedFor(Class) * @hide */ diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java index 3da696ad0bc7..7fbaf1027af6 100644 --- a/core/java/android/net/Uri.java +++ b/core/java/android/net/Uri.java @@ -882,10 +882,11 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { } static Uri readFrom(Parcel parcel) { + final StringUri stringUri = new StringUri(parcel.readString8()); return new OpaqueUri( - parcel.readString8(), - Part.readFrom(parcel), - Part.readFrom(parcel) + stringUri.parseScheme(), + stringUri.getSsp(), + stringUri.getFragmentPart() ); } @@ -895,9 +896,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(TYPE_ID); - parcel.writeString8(scheme); - ssp.writeTo(parcel); - fragment.writeTo(parcel); + parcel.writeString8(toString()); } public boolean isHierarchical() { @@ -1196,22 +1195,25 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { Part query, Part fragment) { this.scheme = scheme; this.authority = Part.nonNull(authority); - this.path = path == null ? PathPart.NULL : path; + this.path = generatePath(path); this.query = Part.nonNull(query); this.fragment = Part.nonNull(fragment); } - static Uri readFrom(Parcel parcel) { - final String scheme = parcel.readString8(); - final Part authority = Part.readFrom(parcel); + private PathPart generatePath(PathPart originalPath) { // In RFC3986 the path should be determined based on whether there is a scheme or // authority present (https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3). final boolean hasSchemeOrAuthority = (scheme != null && scheme.length() > 0) || !authority.isEmpty(); - final PathPart path = PathPart.readFrom(hasSchemeOrAuthority, parcel); - final Part query = Part.readFrom(parcel); - final Part fragment = Part.readFrom(parcel); - return new HierarchicalUri(scheme, authority, path, query, fragment); + final PathPart newPath = hasSchemeOrAuthority ? PathPart.makeAbsolute(originalPath) + : originalPath; + return newPath == null ? PathPart.NULL : newPath; + } + + static Uri readFrom(Parcel parcel) { + final StringUri stringUri = new StringUri(parcel.readString8()); + return new HierarchicalUri(stringUri.getScheme(), stringUri.getAuthorityPart(), + stringUri.getPathPart(), stringUri.getQueryPart(), stringUri.getFragmentPart()); } public int describeContents() { @@ -1220,11 +1222,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(TYPE_ID); - parcel.writeString8(scheme); - authority.writeTo(parcel); - path.writeTo(parcel); - query.writeTo(parcel); - fragment.writeTo(parcel); + parcel.writeString8(toString()); } public boolean isHierarchical() { diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index a91781580ac4..157d95dc3c01 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -880,22 +880,23 @@ public interface WindowManager extends ViewManager { int LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP = 600; /** - * Application level {@link android.content.pm.PackageManager.Property PackageManager - * .Property} for an app to inform the system that the app can be opted-in or opted-out - * from the compatibility treatment that avoids {@link - * android.app.Activity#setRequestedOrientation} loops. The loop can be trigerred by - * ignoreRequestedOrientation display setting enabled on the device or by the landscape natural - * orientation of the device. + * Application level {@link android.content.pm.PackageManager.Property PackageManager.Property} + * for an app to inform the system that the app can be opted-in or opted-out from the + * compatibility treatment that avoids {@link android.app.Activity#setRequestedOrientation + * Activity#setRequestedOrientation()} loops. Loops can be triggered by the OEM-configured + * ignore requested orientation display setting (on Android 12 (API level 31) and higher) or by + * the landscape natural orientation of the device. * * <p>The treatment is disabled by default but device manufacturers can enable the treatment * using their discretion to improve display compatibility. * - * <p>With this property set to {@code true}, the system could ignore {@link - * android.app.Activity#setRequestedOrientation} call from an app if one of the following - * conditions are true: + * <p>With this property set to {@code true}, the system could ignore + * {@link android.app.Activity#setRequestedOrientation Activity#setRequestedOrientation()} call + * from an app if one of the following conditions are true: * <ul> - * <li>Activity is relaunching due to the previous {@link - * android.app.Activity#setRequestedOrientation} call. + * <li>Activity is relaunching due to the previous + * {@link android.app.Activity#setRequestedOrientation Activity#setRequestedOrientation()} + * call. * <li>Camera compatibility force rotation treatment is active for the package. * </ul> * @@ -919,14 +920,16 @@ public interface WindowManager extends ViewManager { /** * Application level {@link android.content.pm.PackageManager.Property PackageManager.Property} * for an app to inform the system that the app can be opted-out from the compatibility - * treatment that avoids {@link android.app.Activity#setRequestedOrientation} loops. The loop - * can be trigerred by ignoreRequestedOrientation display setting enabled on the device or - * by the landscape natural orientation of the device. + * treatment that avoids {@link android.app.Activity#setRequestedOrientation + * Activity#setRequestedOrientation()} loops. Loops can be triggered by the OEM-configured + * ignore requested orientation display setting (on Android 12 (API level 31) and higher) or by + * the landscape natural orientation of the device. * - * <p>The system could ignore {@link android.app.Activity#setRequestedOrientation} - * call from an app if both of the following conditions are true: + * <p>The system could ignore {@link android.app.Activity#setRequestedOrientation + * Activity#setRequestedOrientation()} call from an app if both of the following conditions are + * true: * <ul> - * <li>Activity has requested orientation more than 2 times within 1-second timer + * <li>Activity has requested orientation more than two times within one-second timer * <li>Activity is not letterboxed for fixed orientation * </ul> * @@ -953,23 +956,21 @@ public interface WindowManager extends ViewManager { "android.window.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED"; /** - * Application level {@link android.content.pm.PackageManager.Property PackageManager - * .Property} for an app to inform the system that it needs to be opted-out from the - * compatibility treatment that sandboxes {@link android.view.View} API. + * Application level {@link android.content.pm.PackageManager.Property PackageManager.Property} + * for an app to inform the system that it needs to be opted-out from the compatibility + * treatment that sandboxes the {@link android.view.View View} API. * * <p>The treatment can be enabled by device manufacturers for applications which misuse - * {@link android.view.View} APIs by expecting that - * {@link android.view.View#getLocationOnScreen}, - * {@link android.view.View#getBoundsOnScreen}, - * {@link android.view.View#getWindowVisibleDisplayFrame}, - * {@link android.view.View#getWindowDisplayFrame} + * {@link android.view.View View} APIs by expecting that + * {@link android.view.View#getLocationOnScreen View#getLocationOnScreen()} and + * {@link android.view.View#getWindowVisibleDisplayFrame View#getWindowVisibleDisplayFrame()} * return coordinates as if an activity is positioned in the top-left corner of the screen, with - * left coordinate equal to 0. This may not be the case for applications in multi-window and in + * left coordinate equal to 0. This may not be the case for applications in multi-window and * letterbox modes. * * <p>Setting this property to {@code false} informs the system that the application must be - * opted-out from the "Sandbox {@link android.view.View} API to Activity bounds" treatment even - * if the device manufacturer has opted the app into the treatment. + * opted-out from the "Sandbox View API to Activity bounds" treatment even if the device + * manufacturer has opted the app into the treatment. * * <p>Not setting this property at all, or setting this property to {@code true} has no effect. * @@ -987,12 +988,11 @@ public interface WindowManager extends ViewManager { "android.window.PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS"; /** - * Application level {@link android.content.pm.PackageManager.Property PackageManager - * .Property} for an app to inform the system that the application can be opted-in or opted-out - * from the compatibility treatment that enables sending a fake focus event for unfocused - * resumed split screen activities. This is needed because some game engines wait to get - * focus before drawing the content of the app which isn't guaranteed by default in multi-window - * modes. + * Application level {@link android.content.pm.PackageManager.Property PackageManager.Property} + * for an app to inform the system that the application can be opted-in or opted-out from the + * compatibility treatment that enables sending a fake focus event for unfocused resumed + * split-screen activities. This is needed because some game engines wait to get focus before + * drawing the content of the app which isn't guaranteed by default in multi-window mode. * * <p>Device manufacturers can enable this treatment using their discretion on a per-device * basis to improve display compatibility. The treatment also needs to be specifically enabled @@ -1022,9 +1022,9 @@ public interface WindowManager extends ViewManager { String PROPERTY_COMPAT_ENABLE_FAKE_FOCUS = "android.window.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS"; /** - * Application level {@link android.content.pm.PackageManager.Property PackageManager - * .Property} for an app to inform the system that the app should be excluded from the - * camera compatibility force rotation treatment. + * Application level {@link android.content.pm.PackageManager.Property PackageManager.Property} + * for an app to inform the system that the app should be excluded from the camera compatibility + * force rotation treatment. * * <p>The camera compatibility treatment aligns orientations of portrait app window and natural * orientation of the device and set opposite to natural orientation for a landscape app @@ -1034,10 +1034,11 @@ public interface WindowManager extends ViewManager { * rotation can cause letterboxing. The forced rotation is triggered as soon as app opens to * camera and is removed once camera is closed. * - * <p>The camera compatibility can be enabled by device manufacturers on the displays that have - * ignoreOrientationRequest display setting enabled (enables compatibility mode for fixed - * orientation, see <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced letterboxing</a> - * for more details). + * <p>The camera compatibility can be enabled by device manufacturers on displays that have the + * ignore requested orientation display setting enabled (enables compatibility mode for fixed + * orientation on Android 12 (API level 31) or higher; see + * <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced + * letterboxing</a> for more details). * * <p>With this property set to {@code true} or unset, the system may apply the force rotation * treatment to fixed orientation activities. Device manufacturers can exclude packages from the @@ -1060,9 +1061,9 @@ public interface WindowManager extends ViewManager { "android.window.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION"; /** - * Application level {@link android.content.pm.PackageManager.Property PackageManager - * .Property} for an app to inform the system that the app should be excluded - * from the activity "refresh" after the camera compatibility force rotation treatment. + * Application level {@link android.content.pm.PackageManager.Property PackageManager.Property} + * for an app to inform the system that the app should be excluded from the activity "refresh" + * after the camera compatibility force rotation treatment. * * <p>The camera compatibility treatment aligns orientations of portrait app window and natural * orientation of the device and set opposite to natural orientation for a landscape app @@ -1079,10 +1080,11 @@ public interface WindowManager extends ViewManager { * camera preview and can lead to sideways or stretching issues persisting even after force * rotation. * - * <p>The camera compatibility can be enabled by device manufacturers on the displays that have - * ignoreOrientationRequest display setting enabled (enables compatibility mode for fixed - * orientation, see <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced letterboxing</a> - * for more details). + * <p>The camera compatibility can be enabled by device manufacturers on displays that have the + * ignore requested orientation display setting enabled (enables compatibility mode for fixed + * orientation on Android 12 (API level 31) or higher; see + * <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced + * letterboxing</a> for more details). * * <p>With this property set to {@code true} or unset, the system may "refresh" activity after * the force rotation treatment. Device manufacturers can exclude packages from the "refresh" @@ -1105,10 +1107,10 @@ public interface WindowManager extends ViewManager { "android.window.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH"; /** - * Application level {@link android.content.pm.PackageManager.Property PackageManager - * .Property} for an app to inform the system that the activity should be or shouldn't be - * "refreshed" after the camera compatibility force rotation treatment using "paused -> - * resumed" cycle rather than "stopped -> resumed". + * Application level {@link android.content.pm.PackageManager.Property PackageManager.Property} + * for an app to inform the system that the activity should be or shouldn't be "refreshed" after + * the camera compatibility force rotation treatment using "paused -> resumed" cycle rather than + * "stopped -> resumed". * * <p>The camera compatibility treatment aligns orientations of portrait app window and natural * orientation of the device and set opposite to natural orientation for a landscape app @@ -1124,10 +1126,11 @@ public interface WindowManager extends ViewManager { * values in apps (e.g., display or camera rotation) that influence camera preview and can lead * to sideways or stretching issues persisting even after force rotation. * - * <p>The camera compatibility can be enabled by device manufacturers on the displays that have - * ignoreOrientationRequest display setting enabled (enables compatibility mode for fixed - * orientation, see <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced letterboxing</a> - * for more details). + * <p>The camera compatibility can be enabled by device manufacturers on displays that have the + * ignore requested orientation display setting enabled (enables compatibility mode for fixed + * orientation on Android 12 (API level 31) or higher; see + * <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced + * letterboxing</a> for more details). * * <p>Device manufacturers can override packages to "refresh" via "resumed -> paused -> resumed" * cycle using their discretion to improve display compatibility. @@ -1153,22 +1156,23 @@ public interface WindowManager extends ViewManager { "android.window.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE"; /** - * Application level {@link android.content.pm.PackageManager.Property PackageManager - * .Property} for an app to inform the system that the app should be excluded from the - * compatibility override for orientation set by the device manufacturer. When the orientation - * override is applied it can: + * Application level {@link android.content.pm.PackageManager.Property PackageManager.Property} + * for an app to inform the system that the app should be excluded from the compatibility + * override for orientation set by the device manufacturer. When the orientation override is + * applied it can: * <ul> * <li>Replace the specific orientation requested by the app with another selected by the - device manufacturer, e.g. replace undefined requested by the app with portrait. + device manufacturer; for example, replace undefined requested by the app with portrait. * <li>Always use an orientation selected by the device manufacturer. * <li>Do one of the above but only when camera connection is open. * </ul> * - * <p>This property is different from {@link PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION} + * <p>This property is different from {@link #PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION} * (which is used to avoid orientation loops caused by the incorrect use of {@link - * android.app.Activity#setRequestedOrientation}) because this property overrides the app to an - * orientation selected by the device manufacturer rather than ignoring one of orientation - * requests coming from the app while respecting the previous one. + * android.app.Activity#setRequestedOrientation Activity#setRequestedOrientation()}) because + * this property overrides the app to an orientation selected by the device manufacturer rather + * than ignoring one of orientation requests coming from the app while respecting the previous + * one. * * <p>With this property set to {@code true} or unset, device manufacturers can override * orientation for the app using their discretion to improve display compatibility. @@ -1190,10 +1194,10 @@ public interface WindowManager extends ViewManager { "android.window.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE"; /** - * Application level {@link android.content.pm.PackageManager.Property PackageManager - * .Property} for an app to inform the system that the app should be opted-out from the - * compatibility override that fixes display orientation to landscape natural orientation when - * an activity is fullscreen. + * Application level {@link android.content.pm.PackageManager.Property PackageManager.Property} + * for an app to inform the system that the app should be opted-out from the compatibility + * override that fixes display orientation to landscape natural orientation when an activity is + * fullscreen. * * <p>When this compat override is enabled and while display is fixed to the landscape natural * orientation, the orientation requested by the activity will be still respected by bounds @@ -1202,16 +1206,17 @@ public interface WindowManager extends ViewManager { * lanscape natural orientation. * * <p>The treatment is disabled by default but device manufacturers can enable the treatment - * using their discretion to improve display compatibility on the displays that have - * ignoreOrientationRequest display setting enabled (enables compatibility mode for fixed - * orientation, see <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced letterboxing</a> - * for more details). + * using their discretion to improve display compatibility on displays that have the ignore + * orientation request display setting enabled by OEMs on the device (enables compatibility mode + * for fixed orientation on Android 12 (API level 31) or higher; see + * <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced + * letterboxing</a> for more details). * * <p>With this property set to {@code true} or unset, the system wiil use landscape display * orientation when the following conditions are met: * <ul> * <li>Natural orientation of the display is landscape - * <li>ignoreOrientationRequest display setting is enabled + * <li>ignore requested orientation display setting is enabled * <li>Activity is fullscreen. * <li>Device manufacturer enabled the treatment. * </ul> @@ -1233,9 +1238,9 @@ public interface WindowManager extends ViewManager { "android.window.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE"; /** - * Application level {@link android.content.pm.PackageManager.Property PackageManager - * .Property} for an app to inform the system that the app should be opted-out from the - * compatibility override that changes the min aspect ratio. + * Application level {@link android.content.pm.PackageManager.Property PackageManager.Property} + * for an app to inform the system that the app should be opted-out from the compatibility + * override that changes the min aspect ratio. * * <p>When this compat override is enabled the min aspect ratio given in the app's manifest can * be overridden by the device manufacturer using their discretion to improve display @@ -1264,14 +1269,14 @@ public interface WindowManager extends ViewManager { "android.window.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE"; /** - * Application level {@link android.content.pm.PackageManager.Property PackageManager - * .Property} for an app to inform the system that the app should be opted-out from the - * compatibility overrides that change the resizability of the app. + * Application level {@link android.content.pm.PackageManager.Property PackageManager.Property} + * for an app to inform the system that the app should be opted-out from the compatibility + * overrides that change the resizability of the app. * * <p>When these compat overrides are enabled they force the packages they are applied to to be - * resizable / unresizable. If the app is forced to be resizable this won't change whether - * the app can be put into multi-windowing mode, but allow the app to resize without going into - * size-compat mode when the window container resizes, such as display size change or screen + * resizable/unresizable. If the app is forced to be resizable this won't change whether the app + * can be put into multi-windowing mode, but allow the app to resize without going into size + * compatibility mode when the window container resizes, such as display size change or screen * rotation. * * <p>Setting this property to {@code false} informs the system that the app must be @@ -1320,34 +1325,29 @@ public interface WindowManager extends ViewManager { } /** - * Application-level - * {@link android.content.pm.PackageManager.Property PackageManager.Property} - * tag that specifies whether OEMs are permitted to provide activity - * embedding split-rule configurations on behalf of the app. + * Application-level {@link android.content.pm.PackageManager.Property PackageManager.Property} + * tag that specifies whether OEMs are permitted to provide activity embedding split-rule + * configurations on behalf of the app. * - * <p>If {@code true}, the system is permitted to override the app's - * windowing behavior and implement activity embedding split rules, such as - * displaying activities side by side. A system override informs the app - * that the activity embedding APIs are disabled so the app will not provide - * its own activity embedding rules, which would conflict with the system's + * <p>If {@code true}, the system is permitted to override the app's windowing behavior and + * implement activity embedding split rules, such as displaying activities side by side. A + * system override informs the app that the activity embedding APIs are disabled so the app + * doesn't provide its own activity embedding rules, which would conflict with the system's * rules. * - * <p>If {@code false}, the system is not permitted to override the - * windowing behavior of the app. Set the property to {@code false} if the - * app provides its own activity embedding split rules, or if you want to - * prevent the system override for any other reason. + * <p>If {@code false}, the system is not permitted to override the windowing behavior of the + * app. Set the property to {@code false} if the app provides its own activity embedding split + * rules, or if you want to prevent the system override for any other reason. * * <p>The default value is {@code false}. * - * <p class="note"><b>Note:</b> Refusal to permit the system override is not - * enforceable. OEMs can override the app's activity embedding - * implementation whether or not this property is specified and set to - * <code>false</code>. The property is, in effect, a hint to OEMs. + * <p class="note"><b>Note:</b> Refusal to permit the system override is not enforceable. OEMs + * can override the app's activity embedding implementation whether or not this property is + * specified and set to {@code false}. The property is, in effect, a hint to OEMs. * - * <p>OEMs can implement activity embedding on any API level. The best - * practice for apps is to always explicitly set this property in the app - * manifest file regardless of targeted API level rather than rely on the - * default value. + * <p>OEMs can implement activity embedding on any API level. The best practice for apps is to + * always explicitly set this property in the app manifest file regardless of targeted API level + * rather than rely on the default value. * * <p><b>Syntax:</b> * <pre> @@ -1362,14 +1362,15 @@ public interface WindowManager extends ViewManager { "android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE"; /** - * Application level {@link android.content.pm.PackageManager.Property PackageManager - * .Property} that an app can specify to inform the system that the app is ActivityEmbedding - * split feature enabled. + * Application level {@link android.content.pm.PackageManager.Property PackageManager.Property} + * that an app can specify to inform the system that the app is activity embedding split feature + * enabled. * * <p>With this property, the system could provide custom behaviors for the apps that are - * ActivityEmbedding split feature enabled. For example, the fixed-portrait orientation + * activity embedding split feature enabled. For example, the fixed-portrait orientation * requests of the activities could be ignored by the system in order to provide seamless - * ActivityEmbedding split experiences while holding the large-screen devices in landscape mode. + * activity embedding split experiences while holding large screen devices in landscape + * orientation. * * <p><b>Syntax:</b> * <pre> diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index b65c1a17e26b..cb5dbe6c5618 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -1550,6 +1550,7 @@ public class ScrollView extends FrameLayout { float deltaDistance = -unconsumed * FLING_DESTRETCH_FACTOR / size; int consumed = Math.round(-size / FLING_DESTRETCH_FACTOR * mEdgeGlowTop.onPullDistance(deltaDistance, 0.5f)); + mEdgeGlowTop.onRelease(); if (consumed != unconsumed) { mEdgeGlowTop.finish(); } @@ -1560,6 +1561,7 @@ public class ScrollView extends FrameLayout { float deltaDistance = unconsumed * FLING_DESTRETCH_FACTOR / size; int consumed = Math.round(size / FLING_DESTRETCH_FACTOR * mEdgeGlowBottom.onPullDistance(deltaDistance, 0.5f)); + mEdgeGlowBottom.onRelease(); if (consumed != unconsumed) { mEdgeGlowBottom.finish(); } diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index a165af18472e..be67a1300d48 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -670,7 +670,7 @@ <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Sakatu hau aurpegi-eredua ezabatzeko eta, gero, gehitu aurpegia berriro"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Konfiguratu Aurpegi bidez desblokeatzea"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Telefonoa desblokeatzeko, begira iezaiozu"</string> - <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Aurpegi bidez desblokeatzeko aukera erabiltzeko, aktibatu "<b>"kamera erabiltzeko baimena"</b>" Ezarpenak > Pribatutasuna atalean"</string> + <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Aurpegi bidez desblokeatzeko eginbidea erabiltzeko, aktibatu "<b>"kamera erabiltzeko baimena"</b>" Ezarpenak > Pribatutasuna atalean"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Konfiguratu telefonoa desblokeatzeko modu gehiago"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Sakatu hau hatz-marka bat gehitzeko"</string> <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Hatz-marka bidez desblokeatzea"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index cd1ee9366949..53967e6dc25d 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -256,7 +256,7 @@ <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Usa esta opción na maioría das circunstancias. Permíteche realizar un seguimento do progreso do informe, introducir máis detalles sobre o problema e facer capturas de pantalla. É posible que omita algunhas seccións menos usadas para as que se tarda máis en facer o informe."</string> <string name="bugreport_option_full_title" msgid="7681035745950045690">"Informe completo"</string> <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Usa esta opción para que a interferencia sexa mínima cando o teu dispositivo non responda ou funcione demasiado lento, ou ben cando precises todas as seccións do informe. Non poderás introducir máis detalles nin facer máis capturas de pantalla."</string> - <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Vaise facer unha captura de pantalla para o informe de erro dentro de # segundo.}other{Vaise facer unha captura de pantalla para o informe de erro dentro de # segundos.}}"</string> + <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Vaise facer unha captura de pantalla para o informe de erros dentro de # segundo.}other{Vaise facer unha captura de pantalla para o informe de erros dentro de # segundos.}}"</string> <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Realizouse a captura de pantalla co informe de erros"</string> <string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"Produciuse un erro ao realizar a captura de pantalla co informe de erros"</string> <string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"Modo silencioso"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index e6979ae283f8..6da3465c6a49 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1369,7 +1369,7 @@ <string name="usb_power_notification_message" msgid="7284765627437897702">"연결된 기기를 충전합니다. 옵션을 더 보려면 탭하세요."</string> <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"아날로그 오디오 액세서리가 감지됨"</string> <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"연결된 기기가 이 휴대전화와 호환되지 않습니다. 자세히 알아보려면 탭하세요."</string> - <string name="adb_active_notification_title" msgid="408390247354560331">"USB 디버깅 연결됨"</string> + <string name="adb_active_notification_title" msgid="408390247354560331">"USB 디버깅 연결됨."</string> <string name="adb_active_notification_message" msgid="5617264033476778211">"USB 디버깅을 사용 중지하려면 탭하세요."</string> <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB 디버깅을 사용하지 않으려면 선택합니다."</string> <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"무선 디버깅 연결됨"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 828ab59d7657..958073a4ab99 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -1940,7 +1940,7 @@ <string name="country_selection_title" msgid="5221495687299014379">"地區偏好設定"</string> <string name="search_language_hint" msgid="7004225294308793583">"請輸入語言名稱"</string> <string name="language_picker_section_suggested" msgid="6556199184638990447">"建議語言"</string> - <string name="language_picker_regions_section_suggested" msgid="6080131515268225316">"建議的語言"</string> + <string name="language_picker_regions_section_suggested" msgid="6080131515268225316">"建議地區"</string> <string name="language_picker_section_suggested_bilingual" msgid="5932198319583556613">"建議語言"</string> <string name="region_picker_section_suggested_bilingual" msgid="704607569328224133">"建議地區"</string> <string name="language_picker_section_all" msgid="1985809075777564284">"所有語言"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index ee8c0f83304e..06be5fa5fb18 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -5175,7 +5175,7 @@ </string-array> <!-- The integer index of the selected option in config_udfps_touch_detection_options --> - <integer name="config_selected_udfps_touch_detection">3</integer> + <integer name="config_selected_udfps_touch_detection">0</integer> <!-- An array of arrays of side fingerprint sensor properties relative to each display. Note: this value is temporary and is expected to be queried directly diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java index 89632a46267e..2a4ca79d997e 100644 --- a/core/tests/coretests/src/android/net/UriTest.java +++ b/core/tests/coretests/src/android/net/UriTest.java @@ -25,8 +25,6 @@ import junit.framework.TestCase; import java.io.File; import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.Arrays; import java.util.Iterator; import java.util.List; @@ -869,84 +867,90 @@ public class UriTest extends TestCase { return (Uri) hierarchicalUriConstructor.newInstance("https", authority, path, null, null); } - /** Attempting to unparcel a legacy parcel format of Uri.{,Path}Part should fail. */ - public void testUnparcelLegacyPart_fails() throws Exception { - assertUnparcelLegacyPart_fails(Class.forName("android.net.Uri$Part")); - assertUnparcelLegacyPart_fails(Class.forName("android.net.Uri$PathPart")); - } - - private static void assertUnparcelLegacyPart_fails(Class partClass) throws Exception { - Parcel parcel = Parcel.obtain(); - parcel.writeInt(0 /* BOTH */); - parcel.writeString("encoded"); - parcel.writeString("decoded"); - parcel.setDataPosition(0); - - Method readFromMethod = partClass.getDeclaredMethod("readFrom", Parcel.class); - readFromMethod.setAccessible(true); - try { - readFromMethod.invoke(null, parcel); - fail(); - } catch (InvocationTargetException expected) { - Throwable targetException = expected.getTargetException(); - // Check that the exception was thrown for the correct reason. - assertEquals("Unknown representation: 0", targetException.getMessage()); - } finally { - parcel.recycle(); - } - } - - private Uri buildUriFromRawParcel(boolean argumentsEncoded, + private Uri buildUriFromParts(boolean argumentsEncoded, String scheme, String authority, String path, String query, String fragment) { - // Representation value (from AbstractPart.REPRESENTATION_{ENCODED,DECODED}). - final int representation = argumentsEncoded ? 1 : 2; - Parcel parcel = Parcel.obtain(); - try { - parcel.writeInt(3); // hierarchical - parcel.writeString8(scheme); - parcel.writeInt(representation); - parcel.writeString8(authority); - parcel.writeInt(representation); - parcel.writeString8(path); - parcel.writeInt(representation); - parcel.writeString8(query); - parcel.writeInt(representation); - parcel.writeString8(fragment); - parcel.setDataPosition(0); - return Uri.CREATOR.createFromParcel(parcel); - } finally { - parcel.recycle(); + final Uri.Builder builder = new Uri.Builder(); + builder.scheme(scheme); + if (argumentsEncoded) { + builder.encodedAuthority(authority); + builder.encodedPath(path); + builder.encodedQuery(query); + builder.encodedFragment(fragment); + } else { + builder.authority(authority); + builder.path(path); + builder.query(query); + builder.fragment(fragment); } + return builder.build(); } public void testUnparcelMalformedPath() { // Regression tests for b/171966843. // Test cases with arguments encoded (covering testing `scheme` * `authority` options). - Uri uri0 = buildUriFromRawParcel(true, "https", "google.com", "@evil.com", null, null); + Uri uri0 = buildUriFromParts(true, "https", "google.com", "@evil.com", null, null); assertEquals("https://google.com/@evil.com", uri0.toString()); - Uri uri1 = buildUriFromRawParcel(true, null, "google.com", "@evil.com", "name=spark", "x"); + Uri uri1 = buildUriFromParts(true, null, "google.com", "@evil.com", "name=spark", "x"); assertEquals("//google.com/@evil.com?name=spark#x", uri1.toString()); - Uri uri2 = buildUriFromRawParcel(true, "http:", null, "@evil.com", null, null); + Uri uri2 = buildUriFromParts(true, "http:", null, "@evil.com", null, null); assertEquals("http::/@evil.com", uri2.toString()); - Uri uri3 = buildUriFromRawParcel(true, null, null, "@evil.com", null, null); + Uri uri3 = buildUriFromParts(true, null, null, "@evil.com", null, null); assertEquals("@evil.com", uri3.toString()); // Test cases with arguments not encoded (covering testing `scheme` * `authority` options). - Uri uriA = buildUriFromRawParcel(false, "https", "google.com", "@evil.com", null, null); + Uri uriA = buildUriFromParts(false, "https", "google.com", "@evil.com", null, null); assertEquals("https://google.com/%40evil.com", uriA.toString()); - Uri uriB = buildUriFromRawParcel(false, null, "google.com", "@evil.com", null, null); + Uri uriB = buildUriFromParts(false, null, "google.com", "@evil.com", null, null); assertEquals("//google.com/%40evil.com", uriB.toString()); - Uri uriC = buildUriFromRawParcel(false, "http:", null, "@evil.com", null, null); + Uri uriC = buildUriFromParts(false, "http:", null, "@evil.com", null, null); assertEquals("http::/%40evil.com", uriC.toString()); - Uri uriD = buildUriFromRawParcel(false, null, null, "@evil.com", "name=spark", "y"); + Uri uriD = buildUriFromParts(false, null, null, "@evil.com", "name=spark", "y"); assertEquals("%40evil.com?name%3Dspark#y", uriD.toString()); } + public void testParsedUriFromStringEquality() { + Uri uri = buildUriFromParts( + true, "https", "google.com", "@evil.com", null, null); + assertEquals(uri, Uri.parse(uri.toString())); + Uri uri2 = buildUriFromParts( + true, "content://evil.authority?foo=", "safe.authority", "@evil.com", null, null); + assertEquals(uri2, Uri.parse(uri2.toString())); + Uri uri3 = buildUriFromParts( + false, "content://evil.authority?foo=", "safe.authority", "@evil.com", null, null); + assertEquals(uri3, Uri.parse(uri3.toString())); + } + + public void testParceledUrisAreEqual() { + Uri opaqueUri = Uri.fromParts("fake://uri#", "ssp", "fragment"); + Parcel parcel = Parcel.obtain(); + try { + opaqueUri.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + Uri postParcelUri = Uri.CREATOR.createFromParcel(parcel); + Uri parsedUri = Uri.parse(postParcelUri.toString()); + assertEquals(parsedUri.getScheme(), postParcelUri.getScheme()); + } finally { + parcel.recycle(); + } + + Uri hierarchicalUri = new Uri.Builder().scheme("fake://uri#").authority("auth").build(); + parcel = Parcel.obtain(); + try { + hierarchicalUri.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + Uri postParcelUri = Uri.CREATOR.createFromParcel(parcel); + Uri parsedUri = Uri.parse(postParcelUri.toString()); + assertEquals(parsedUri.getScheme(), postParcelUri.getScheme()); + } finally { + parcel.recycle(); + } + } + public void testToSafeString() { checkToSafeString("tel:xxxxxx", "tel:Google"); checkToSafeString("tel:xxxxxxxxxx", "tel:1234567890"); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index b14c3c10846b..08da4857a0b0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -1927,6 +1927,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, pw.println(innerPrefix + "mLeash=" + mLeash); pw.println(innerPrefix + "mState=" + mPipTransitionState.getTransitionState()); pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams); + mPipTransitionController.dump(pw, innerPrefix); } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java index 73eb62ae47e9..e3d53fc415db 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java @@ -72,6 +72,7 @@ import com.android.wm.shell.transition.CounterRotatorHelper; import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.util.TransitionUtil; +import java.io.PrintWriter; import java.util.Optional; /** @@ -451,6 +452,9 @@ public class PipTransition extends PipTransitionController { @Override public void forceFinishTransition() { + // mFinishCallback might be null with an outdated mCurrentPipTaskToken + // for example, when app crashes while in PiP and exit transition has not started + mCurrentPipTaskToken = null; if (mFinishCallback == null) return; mFinishCallback.onTransitionFinished(null /* wct */, null /* callback */); mFinishCallback = null; @@ -1137,4 +1141,12 @@ public class PipTransition extends PipTransitionController { PipMenuController.ALPHA_NO_CHANGE); mPipMenuController.updateMenuBounds(destinationBounds); } + + @Override + public void dump(PrintWriter pw, String prefix) { + final String innerPrefix = prefix + " "; + pw.println(prefix + TAG); + pw.println(innerPrefix + "mCurrentPipTaskToken=" + mCurrentPipTaskToken); + pw.println(innerPrefix + "mFinishCallback=" + mFinishCallback); + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java index e1bcd70c256b..63627938ec87 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java @@ -42,6 +42,7 @@ import com.android.wm.shell.common.split.SplitScreenUtils; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -283,4 +284,9 @@ public abstract class PipTransitionController implements Transitions.TransitionH */ void onPipTransitionCanceled(int direction); } + + /** + * Dumps internal states. + */ + public void dump(PrintWriter pw, String prefix) {} } diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml index 3b980c5a5770..17d5e1d7fb34 100644 --- a/packages/SettingsLib/res/values-eu/arrays.xml +++ b/packages/SettingsLib/res/values-eu/arrays.xml @@ -208,7 +208,7 @@ <item msgid="2675263395797191850">"Animazioa desaktibatuta"</item> <item msgid="5790132543372767872">"Animazio-eskala: 0,5x"</item> <item msgid="2529692189302148746">"Animazio-eskala: 1×"</item> - <item msgid="8072785072237082286">"Animazio-eskala: 1,5x"</item> + <item msgid="8072785072237082286">"Animazio-eskala: 1,5×"</item> <item msgid="3531560925718232560">"Animazio-eskala 2x"</item> <item msgid="4542853094898215187">"Animazio-eskala: 5x"</item> <item msgid="5643881346223901195">"Animazio-eskala: 10x"</item> @@ -217,7 +217,7 @@ <item msgid="3376676813923486384">"Animazioa desaktibatuta"</item> <item msgid="753422683600269114">"Animazio-eskala: 0,5x"</item> <item msgid="3695427132155563489">"Animazio-eskala: 1×"</item> - <item msgid="9032615844198098981">"Animazio-eskala: 1,5x"</item> + <item msgid="9032615844198098981">"Animazio-eskala: 1,5×"</item> <item msgid="8473868962499332073">"Animazio-eskala: 2x"</item> <item msgid="4403482320438668316">"Animazio-eskala: 5x"</item> <item msgid="169579387974966641">"Animazio-eskala: 10x"</item> @@ -226,7 +226,7 @@ <item msgid="6416998593844817378">"Animazioa desaktibatuta"</item> <item msgid="875345630014338616">"Animazio-eskala: 0,5x"</item> <item msgid="2753729231187104962">"Animazio-eskala: 1×"</item> - <item msgid="1368370459723665338">"Animazio-eskala: 1,5x"</item> + <item msgid="1368370459723665338">"Animazio-eskala: 1,5×"</item> <item msgid="5768005350534383389">"Animazio-eskala: 2x"</item> <item msgid="3728265127284005444">"Animazio-eskala: 5x"</item> <item msgid="2464080977843960236">"Animazio-eskala: 10x"</item> diff --git a/packages/Shell/res/values-gl/strings.xml b/packages/Shell/res/values-gl/strings.xml index 912dc85e15e4..9d4f7de68793 100644 --- a/packages/Shell/res/values-gl/strings.xml +++ b/packages/Shell/res/values-gl/strings.xml @@ -20,7 +20,7 @@ <string name="bugreport_notification_channel" msgid="2574150205913861141">"Informes de erros"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Estase xerando o informe de erros <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Rexistrouse o informe de erros <xliff:g id="ID">#%d</xliff:g>"</string> - <string name="bugreport_updating_title" msgid="4423539949559634214">"Engadindo detalles ao informe de erro"</string> + <string name="bugreport_updating_title" msgid="4423539949559634214">"Engadindo detalles ao informe de erros"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Agarda..."</string> <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"O informe de erros aparecerá no teléfono en breve"</string> <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Selecciona para compartir o teu informe de erros"</string> @@ -32,7 +32,7 @@ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Non mostrar outra vez"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes de erros"</string> <string name="bugreport_unreadable_text" msgid="586517851044535486">"Non se puido ler o ficheiro de informe de erros"</string> - <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Non se puideron engadir os detalles do informe de erro ao ficheiro zip"</string> + <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Non se puideron engadir os detalles do informe de erros ao ficheiro zip"</string> <string name="bugreport_unnamed" msgid="2800582406842092709">"sen nome"</string> <string name="bugreport_info_action" msgid="2158204228510576227">"Detalles"</string> <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Captura de pantalla"</string> diff --git a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml index 87b5a4c2fc5b..32dc4b335f7e 100644 --- a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml +++ b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml @@ -20,7 +20,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" android:shape="rectangle"> - <solid android:color="?androidprv:attr/colorSurface"/> + <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh"/> <size android:width="@dimen/keyguard_affordance_fixed_width" android:height="@dimen/keyguard_affordance_fixed_height"/> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 692363b3bc18..729d63455971 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -1029,7 +1029,7 @@ <string name="status_before_loading" msgid="1500477307859631381">"El contenido se mostrará en breve"</string> <string name="missed_call" msgid="4228016077700161689">"Llamada perdida"</string> <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> - <string name="people_tile_description" msgid="8154966188085545556">"Consulta los mensajes recientes, las llamadas perdidas y los cambios de estado"</string> + <string name="people_tile_description" msgid="8154966188085545556">"Consulta mensajes recientes, llamadas perdidas y cambios de estado"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversación"</string> <string name="paused_by_dnd" msgid="7856941866433556428">"Pausado por No molestar"</string> <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ha enviado un mensaje: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 6010557e9954..6accfd1f6f7d 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -510,14 +510,14 @@ <string name="stream_accessibility" msgid="3873610336741987152">"Accessibilità"</string> <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Attiva suoneria"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Attiva vibrazione"</string> - <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Disattiva suoneria"</string> + <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Silenzia"</string> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tocca per riattivare l\'audio."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tocca per attivare la vibrazione. L\'audio dei servizi di accessibilità può essere disattivato."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tocca per disattivare l\'audio. L\'audio dei servizi di accessibilità può essere disattivato."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tocca per attivare la vibrazione."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tocca per disattivare l\'audio."</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Tocca per cambiare la modalità della suoneria"</string> - <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"disattiva l\'audio"</string> + <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenzia"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"riattiva l\'audio"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrazione"</string> <string name="volume_dialog_title" msgid="6502703403483577940">"Controlli del volume %s"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 823462e49cad..8f60d73c3964 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -301,8 +301,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Күн шыққанға дейін"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Қосылу уақыты: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> дейін"</string> - <string name="quick_settings_dark_mode_secondary_label_on_at_bedtime" msgid="2274300599408864897">"Ұйқы уақытында"</string> - <string name="quick_settings_dark_mode_secondary_label_until_bedtime_ends" msgid="1790772410777123685">"Ұйқы уақыты аяқталғанға дейін"</string> + <string name="quick_settings_dark_mode_secondary_label_on_at_bedtime" msgid="2274300599408864897">"Ұйқы режимінде"</string> + <string name="quick_settings_dark_mode_secondary_label_until_bedtime_ends" msgid="1790772410777123685">"Ұйқы режимі аяқталғанға дейін"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC өшірулі"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC қосулы"</string> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockFrame.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardClockFrame.kt index 635f0fa44234..50e5466d0325 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockFrame.kt +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockFrame.kt @@ -12,6 +12,10 @@ class KeyguardClockFrame( ) : FrameLayout(context, attrs) { private var drawAlpha: Int = 255 + init { + setLayerType(View.LAYER_TYPE_SOFTWARE, null) + } + protected override fun onSetAlpha(alpha: Int): Boolean { drawAlpha = alpha return true diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index 951d077808c9..366056af7ab3 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -683,11 +683,11 @@ object Flags { // TODO(b/283071711): Tracking bug @JvmField val TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK = - releasedFlag(2401, "trim_resources_with_background_trim_on_lock") + unreleasedFlag(2401, "trim_resources_with_background_trim_on_lock") // TODO:(b/283203305): Tracking bug @JvmField - val TRIM_FONT_CACHES_AT_UNLOCK = releasedFlag(2402, "trim_font_caches_on_unlock") + val TRIM_FONT_CACHES_AT_UNLOCK = unreleasedFlag(2402, "trim_font_caches_on_unlock") // 2700 - unfold transitions // TODO(b/265764985): Tracking Bug diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt index a8d662c96284..5ad6e5196f66 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt @@ -377,9 +377,9 @@ object KeyguardBottomAreaViewBinder { Utils.getColorAttrDefaultColor( view.context, if (viewModel.isActivated) { - com.android.internal.R.attr.textColorPrimaryInverse + com.android.internal.R.attr.materialColorOnPrimaryFixed } else { - com.android.internal.R.attr.textColorPrimary + com.android.internal.R.attr.materialColorOnSurface }, ) ) @@ -389,9 +389,9 @@ object KeyguardBottomAreaViewBinder { Utils.getColorAttr( view.context, if (viewModel.isActivated) { - com.android.internal.R.attr.colorAccentPrimary + com.android.internal.R.attr.materialColorPrimaryFixed } else { - com.android.internal.R.attr.colorSurface + com.android.internal.R.attr.materialColorSurfaceContainerHigh } ) } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 1bf63be3c8b0..d97e64ee6672 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -51,6 +51,7 @@ import com.android.keyguard.KeyguardSecurityModel; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.KeyguardViewController; +import com.android.keyguard.TrustGrantFlags; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor; import com.android.systemui.dagger.SysUISingleton; @@ -305,6 +306,16 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb @Nullable private TaskbarDelegate mTaskbarDelegate; private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() { + @Override + public void onTrustGrantedForCurrentUser( + boolean dismissKeyguard, + boolean newlyUnlocked, + @NonNull TrustGrantFlags flags, + @Nullable String message + ) { + updateAlternateBouncerShowing(mAlternateBouncerInteractor.maybeHide()); + } + @Override public void onEmergencyCallAction() { // Since we won't get a setOccluded call we have to reset the view manually such that @@ -430,7 +441,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mDockManager.addListener(mDockEventListener); mIsDocked = mDockManager.isDocked(); } - mKeyguardStateController.addCallback(mKeyguardStateControllerCallback); } /** Register a callback, to be invoked by the Predictive Back system. */ @@ -1564,14 +1574,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb || mode == KeyguardSecurityModel.SecurityMode.SimPuk; } - private KeyguardStateController.Callback mKeyguardStateControllerCallback = - new KeyguardStateController.Callback() { - @Override - public void onUnlockedChanged() { - updateAlternateBouncerShowing(mAlternateBouncerInteractor.maybeHide()); - } - }; - /** * Delegate used to send show and hide events to an alternate authentication method instead of * the regular pin/pattern/password bouncer. diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java index 3eea93c6ec2c..131cc07178f4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java @@ -35,6 +35,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.service.trust.TrustAgentService; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.MotionEvent; @@ -57,6 +58,8 @@ import com.android.keyguard.KeyguardMessageArea; import com.android.keyguard.KeyguardMessageAreaController; import com.android.keyguard.KeyguardSecurityModel; import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.KeyguardUpdateMonitorCallback; +import com.android.keyguard.TrustGrantFlags; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor; @@ -84,7 +87,6 @@ import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.unfold.SysUIUnfoldComponent; import com.google.common.truth.Truth; @@ -153,7 +155,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { @Captor private ArgumentCaptor<OnBackInvokedCallback> mBackCallbackCaptor; @Captor - private ArgumentCaptor<KeyguardStateController.Callback> mKeyguardStateControllerCallback; + private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallback; @Before @@ -925,18 +927,24 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { } @Test - public void onDeviceUnlocked_hideAlternateBouncerAndClearMessageArea() { + public void onTrustChanged_hideAlternateBouncerAndClearMessageArea() { + // GIVEN keyguard update monitor callback is registered + verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallback.capture()); + reset(mKeyguardUpdateMonitor); reset(mKeyguardMessageAreaController); - // GIVEN keyguard state controller callback is registered - verify(mKeyguardStateController).addCallback(mKeyguardStateControllerCallback.capture()); - // GIVEN alternate bouncer state = not visible when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false); - // WHEN the device is unlocked - mKeyguardStateControllerCallback.getValue().onUnlockedChanged(); + // WHEN the device is trusted by active unlock + mKeyguardUpdateMonitorCallback.getValue().onTrustGrantedForCurrentUser( + true, + true, + new TrustGrantFlags(TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD + | TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE), + null + ); // THEN the false visibility state is propagated to the keyguardUpdateMonitor verify(mKeyguardUpdateMonitor).setAlternateBouncerShowing(eq(false)); diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java index 82af38200166..7557071d0d4b 100644 --- a/services/autofill/java/com/android/server/autofill/Helper.java +++ b/services/autofill/java/com/android/server/autofill/Helper.java @@ -20,6 +20,8 @@ import static com.android.server.autofill.Helper.sDebug; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UserIdInt; +import android.app.ActivityManager; import android.app.assist.AssistStructure; import android.app.assist.AssistStructure.ViewNode; import android.app.assist.AssistStructure.WindowNode; @@ -40,6 +42,7 @@ import android.view.View; import android.view.WindowManager; import android.view.autofill.AutofillId; import android.view.autofill.AutofillValue; +import android.widget.RemoteViews; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.ArrayUtils; @@ -50,6 +53,8 @@ import java.lang.ref.WeakReference; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; +import java.util.concurrent.atomic.AtomicBoolean; + public final class Helper { @@ -83,6 +88,44 @@ public final class Helper { throw new UnsupportedOperationException("contains static members only"); } + private static boolean checkRemoteViewUriPermissions( + @UserIdInt int userId, @NonNull RemoteViews rView) { + final AtomicBoolean permissionsOk = new AtomicBoolean(true); + + rView.visitUris(uri -> { + int uriOwnerId = android.content.ContentProvider.getUserIdFromUri(uri); + boolean allowed = uriOwnerId == userId; + permissionsOk.set(allowed && permissionsOk.get()); + }); + + return permissionsOk.get(); + } + + /** + * Checks the URI permissions of the remote view, + * to see if the current userId is able to access it. + * + * Returns the RemoteView that is passed if user is able, null otherwise. + * + * TODO: instead of returning a null remoteview when + * the current userId cannot access an URI, + * return a new RemoteView with the URI removed. + */ + public static @Nullable RemoteViews sanitizeRemoteView(RemoteViews rView) { + if (rView == null) return null; + + int userId = ActivityManager.getCurrentUser(); + + boolean ok = checkRemoteViewUriPermissions(userId, rView); + if (!ok) { + Slog.w(TAG, + "sanitizeRemoteView() user: " + userId + + " tried accessing resource that does not belong to them"); + } + return (ok ? rView : null); + } + + @Nullable static AutofillId[] toArray(@Nullable ArraySet<AutofillId> set) { if (set == null) return null; diff --git a/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java b/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java index dbeb624bd202..fa414e3b172b 100644 --- a/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java @@ -53,6 +53,7 @@ import android.widget.TextView; import com.android.internal.R; import com.android.server.autofill.AutofillManagerService; +import com.android.server.autofill.Helper; import java.io.PrintWriter; import java.util.ArrayList; @@ -208,7 +209,8 @@ final class DialogFillUi { } private void setHeader(View decor, FillResponse response) { - final RemoteViews presentation = response.getDialogHeader(); + final RemoteViews presentation = + Helper.sanitizeRemoteView(response.getDialogHeader()); if (presentation == null) { return; } @@ -243,9 +245,10 @@ final class DialogFillUi { } private void initialAuthenticationLayout(View decor, FillResponse response) { - RemoteViews presentation = response.getDialogPresentation(); + RemoteViews presentation = Helper.sanitizeRemoteView( + response.getDialogPresentation()); if (presentation == null) { - presentation = response.getPresentation(); + presentation = Helper.sanitizeRemoteView(response.getPresentation()); } if (presentation == null) { throw new RuntimeException("No presentation for fill dialog authentication"); @@ -289,7 +292,8 @@ final class DialogFillUi { final Dataset dataset = response.getDatasets().get(i); final int index = dataset.getFieldIds().indexOf(focusedViewId); if (index >= 0) { - RemoteViews presentation = dataset.getFieldDialogPresentation(index); + RemoteViews presentation = Helper.sanitizeRemoteView( + dataset.getFieldDialogPresentation(index)); if (presentation == null) { if (sDebug) { Slog.w(TAG, "not displaying UI on field " + focusedViewId + " because " diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java index 129ce72e037d..cdfe7bb4f4a7 100644 --- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java @@ -148,8 +148,9 @@ final class FillUi { final LayoutInflater inflater = LayoutInflater.from(mContext); - final RemoteViews headerPresentation = response.getHeader(); - final RemoteViews footerPresentation = response.getFooter(); + final RemoteViews headerPresentation = Helper.sanitizeRemoteView(response.getHeader()); + final RemoteViews footerPresentation = Helper.sanitizeRemoteView(response.getFooter()); + final ViewGroup decor; if (mFullScreen) { decor = (ViewGroup) inflater.inflate(R.layout.autofill_dataset_picker_fullscreen, null); @@ -227,6 +228,9 @@ final class FillUi { ViewGroup container = decor.findViewById(R.id.autofill_dataset_picker); final View content; try { + if (Helper.sanitizeRemoteView(response.getPresentation()) == null) { + throw new RuntimeException("Permission error accessing RemoteView"); + } content = response.getPresentation().applyWithTheme( mContext, decor, interceptionHandler, mThemeId); container.addView(content); @@ -306,7 +310,8 @@ final class FillUi { final Dataset dataset = response.getDatasets().get(i); final int index = dataset.getFieldIds().indexOf(focusedViewId); if (index >= 0) { - final RemoteViews presentation = dataset.getFieldPresentation(index); + final RemoteViews presentation = Helper.sanitizeRemoteView( + dataset.getFieldPresentation(index)); if (presentation == null) { Slog.w(TAG, "not displaying UI on field " + focusedViewId + " because " + "service didn't provide a presentation for it on " + dataset); diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java index f035d0764279..70382f1d5274 100644 --- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java @@ -384,8 +384,7 @@ final class SaveUi { return false; } writeLog(MetricsEvent.AUTOFILL_SAVE_CUSTOM_DESCRIPTION); - - final RemoteViews template = customDescription.getPresentation(); + final RemoteViews template = Helper.sanitizeRemoteView(customDescription.getPresentation()); if (template == null) { Slog.w(TAG, "No remote view on custom description"); return false; diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 4bd66f2f0c95..7369e5ed5932 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -7005,7 +7005,7 @@ public class NotificationManagerService extends SystemService { */ private boolean canBeNonDismissible(ApplicationInfo ai, Notification notification) { return notification.isMediaNotification() || isEnterpriseExempted(ai) - || isCallNotification(ai.packageName, ai.uid, notification) + || notification.isStyle(Notification.CallStyle.class) || isDefaultSearchSelectorPackage(ai.packageName); } diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 0171c200b56c..b34ae1930048 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -2186,7 +2186,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { * Processes the activities to be stopped or destroyed. This should be called when the resumed * activities are idle or drawn. */ - private void processStoppingAndFinishingActivities(ActivityRecord launchedActivity, + void processStoppingAndFinishingActivities(ActivityRecord launchedActivity, boolean processPausingActivities, String reason) { // Stop any activities that are scheduled to do so but have been waiting for the transition // animation to finish. @@ -2194,7 +2194,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { ArrayList<ActivityRecord> readyToStopActivities = null; for (int i = 0; i < mStoppingActivities.size(); i++) { final ActivityRecord s = mStoppingActivities.get(i); - final boolean animating = s.isInTransition(); + // Activity in a force hidden task should not be counted as animating, i.e., we want to + // send onStop before any configuration change when removing pip transition is ongoing. + final boolean animating = s.isInTransition() + && s.getTask() != null && !s.getTask().isForceHidden(); displaySwapping |= s.isDisplaySleepingAndSwapping(); ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b " + "finishing=%s", s, s.nowVisible, animating, s.finishing); diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 2c582c18a8ff..65c5c9b35ab7 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -712,6 +712,14 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { mFlags |= WindowManager.TRANSIT_FLAG_INVISIBLE; return; } + // Activity doesn't need to capture snapshot if the starting window has associated to task. + if (wc.asActivityRecord() != null) { + final ActivityRecord activityRecord = wc.asActivityRecord(); + if (activityRecord.mStartingData != null + && activityRecord.mStartingData.mAssociatedTask != null) { + return; + } + } if (mContainerFreezer == null) { mContainerFreezer = new ScreenshotFreezer(); diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index a2f7ba499fdf..027ab97693fd 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -559,6 +559,13 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } if (forceHiddenForPip) { wc.asTask().setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, true /* set */); + // When removing pip, make sure that onStop is sent to the app ahead of + // onPictureInPictureModeChanged. + // See also PinnedStackTests#testStopBeforeMultiWindowCallbacksOnDismiss + wc.asTask().ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); + wc.asTask().mTaskSupervisor.processStoppingAndFinishingActivities( + null /* launchedActivity */, false /* processPausingActivities */, + "force-stop-on-removing-pip"); } int containerEffect = applyWindowContainerChange(wc, entry.getValue(), diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java index a1199d99f1c3..6747cea80115 100644 --- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java +++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java @@ -91,8 +91,6 @@ public final class CredentialManagerService CredentialManagerService, CredentialManagerServiceImpl> { private static final String TAG = "CredManSysService"; - private static final String DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API = - "enable_credential_description_api"; private static final String PERMISSION_DENIED_ERROR = "permission_denied"; private static final String PERMISSION_DENIED_WRITE_SECURE_SETTINGS_ERROR = "Caller is missing WRITE_SECURE_SETTINGS permission"; @@ -311,14 +309,7 @@ public final class CredentialManagerService } public static boolean isCredentialDescriptionApiEnabled() { - final long origId = Binder.clearCallingIdentity(); - try { - return DeviceConfig.getBoolean( - DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API, - false); - } finally { - Binder.restoreCallingIdentity(origId); - } + return true; } @SuppressWarnings("GuardedBy") // ErrorProne requires initiateProviderSessionForRequestLocked 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 06fe9b7a458e..4849665b0c44 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -11210,7 +11210,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // Given: a call notification has the flag FLAG_ONGOING_EVENT set // feature flag: ALLOW_DISMISS_ONGOING is on mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true); - when(mTelecomManager.isInManagedCall()).thenReturn(true); Person person = new Person.Builder() .setName("caller") |