diff options
65 files changed, 1119 insertions, 394 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index b17e3343666e..de6addf5a06c 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -27748,6 +27748,7 @@ package android.media.tv.interactive { method public void onRecordingTuned(@NonNull String, @NonNull android.net.Uri); method public abstract void onRelease(); method public void onResetInteractiveApp(); + method @FlaggedApi("android.media.tv.flags.tiaf_v_apis") public void onSelectedTrackInfo(@NonNull java.util.List<android.media.tv.TvTrackInfo>); method public abstract boolean onSetSurface(@Nullable android.view.Surface); method public void onSetTeletextAppEnabled(boolean); method public void onSignalStrength(int); @@ -27782,6 +27783,7 @@ package android.media.tv.interactive { method @CallSuper public void requestCurrentVideoBounds(); method @CallSuper public void requestScheduleRecording(@NonNull String, @NonNull String, @NonNull android.net.Uri, @NonNull android.net.Uri, @NonNull android.os.Bundle); method @CallSuper public void requestScheduleRecording(@NonNull String, @NonNull String, @NonNull android.net.Uri, long, long, int, @NonNull android.os.Bundle); + method @FlaggedApi("android.media.tv.flags.tiaf_v_apis") @CallSuper public void requestSelectedTrackInfo(); method @CallSuper public void requestSigning(@NonNull String, @NonNull String, @NonNull String, @NonNull byte[]); method @CallSuper public void requestStartRecording(@NonNull String, @Nullable android.net.Uri); method @CallSuper public void requestStopRecording(@NonNull String); @@ -27846,6 +27848,7 @@ package android.media.tv.interactive { method public void sendCurrentChannelUri(@Nullable android.net.Uri); method public void sendCurrentTvInputId(@Nullable String); method public void sendCurrentVideoBounds(@NonNull android.graphics.Rect); + method @FlaggedApi("android.media.tv.flags.tiaf_v_apis") public void sendSelectedTrackInfo(@Nullable java.util.List<android.media.tv.TvTrackInfo>); method public void sendSigningResult(@NonNull String, @NonNull byte[]); method public void sendStreamVolume(float); method public void sendTimeShiftMode(int); @@ -27881,6 +27884,7 @@ package android.media.tv.interactive { method public void onRequestCurrentVideoBounds(@NonNull String); method public void onRequestScheduleRecording(@NonNull String, @NonNull String, @NonNull String, @NonNull android.net.Uri, @NonNull android.net.Uri, @NonNull android.os.Bundle); method public void onRequestScheduleRecording(@NonNull String, @NonNull String, @NonNull String, @NonNull android.net.Uri, long, long, int, @NonNull android.os.Bundle); + method @FlaggedApi("android.media.tv.flags.tiaf_v_apis") public void onRequestSelectedTrackInfo(@NonNull String); method public void onRequestSigning(@NonNull String, @NonNull String, @NonNull String, @NonNull String, @NonNull byte[]); method public void onRequestStartRecording(@NonNull String, @NonNull String, @Nullable android.net.Uri); method public void onRequestStopRecording(@NonNull String, @NonNull String); diff --git a/core/api/system-current.txt b/core/api/system-current.txt index e6040f8cf68b..01f54ade9acc 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -13449,6 +13449,7 @@ package android.telecom { public abstract class Connection extends android.telecom.Conferenceable { method @Deprecated public final android.telecom.AudioState getAudioState(); + method @FlaggedApi("com.android.server.telecom.flags.telecom_resolve_hidden_dependencies") public final int getCallDirection(); method @IntRange(from=0) public final long getConnectTimeMillis(); method public final long getConnectionStartElapsedRealtimeMillis(); method @Nullable public android.telecom.PhoneAccountHandle getPhoneAccountHandle(); diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index 8b8576a0b25e..b5e507458a30 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -721,28 +721,28 @@ public class KeyguardManager { /** * Returns whether the device is currently locked for the user. * <p> - * This returns the device locked state for the {@link Context}'s user. If this user is the - * current user, then the device is considered "locked" when the lock screen is showing (i.e. - * {@link #isKeyguardLocked()} returns {@code true}) and is not trivially dismissible (e.g. with - * swipe), and the user has a PIN, pattern, or password. + * This method returns the device locked state for the {@link Context}'s user. The device is + * considered to be locked for a user when the user's apps are currently inaccessible and some + * form of lock screen authentication is required to regain access to them. The lock screen + * authentication typically uses PIN, pattern, password, or biometric. Some devices may support + * additional methods, such as unlock using a paired smartwatch. "Swipe" does not count as + * authentication; if the lock screen is dismissible with swipe, for example due to the lock + * screen being set to Swipe or due to the device being kept unlocked by being near a trusted + * bluetooth device or in a trusted location, the device is considered unlocked. + * <div class="note"> * <p> - * Note: the above definition implies that a user with no PIN, pattern, or password is never - * considered locked, even if the lock screen is showing and requesting a SIM card PIN. The - * device PIN and SIM PIN are separate. Also, the user is not considered locked if face - * authentication has just completed or a trust agent is keeping the device unlocked, since in - * these cases the lock screen is dismissible with swipe. + * <b>Note:</b> In the case of multiple full users, each user can have their own lock screen + * authentication configured. The device-locked state may differ between different users. For + * example, the device may be unlocked for the current user, but locked for a non-current user + * if lock screen authentication would be required to access that user's apps after switching to + * that user. * <p> - * For a user that is not the current user but can be switched to (usually this means "another - * full user"), and that has a PIN, pattern, or password, the device is always considered - * locked. - * <p> - * For a profile with a unified challenge, the device locked state is the same as that of the - * parent user. - * <p> - * For a profile with a separate challenge, the device becomes unlocked when the profile's PIN, - * pattern, password, or biometric is verified. It becomes locked when the parent user becomes - * locked, the screen turns off, the device reboots, the device policy controller locks the - * profile, or the timeout set by the device policy controller expires. + * In the case of a profile, when the device goes to the main lock screen, up to two layers of + * authentication may be required to regain access to the profile's apps: one to unlock the main + * lock screen, and one to unlock the profile (when a separate profile challenge is required). + * For a profile, the device is considered to be locked as long as any challenge remains, either + * the parent user's challenge (when applicable) or the profile's challenge (when applicable). + * </div> * * @return {@code true} if the device is currently locked for the user * @see #isKeyguardLocked() diff --git a/core/java/android/app/QueuedWork.java b/core/java/android/app/QueuedWork.java index edf0a46b1433..6a114f908a22 100644 --- a/core/java/android/app/QueuedWork.java +++ b/core/java/android/app/QueuedWork.java @@ -114,6 +114,22 @@ public class QueuedWork { } /** + * Remove all Messages from the Handler with the given code. + * + * This method intentionally avoids creating the Handler if it doesn't + * already exist. + */ + private static void handlerRemoveMessages(int what) { + synchronized (sLock) { + if (sHandler == null) { + // Nothing to remove + return; + } + getHandler().removeMessages(what); + } + } + + /** * Add a finisher-runnable to wait for {@link #queue asynchronously processed work}. * * Used by SharedPreferences$Editor#startCommit(). @@ -156,17 +172,13 @@ public class QueuedWork { long startTime = System.currentTimeMillis(); boolean hadMessages = false; - Handler handler = getHandler(); - synchronized (sLock) { - if (handler.hasMessages(QueuedWorkHandler.MSG_RUN)) { - // Delayed work will be processed at processPendingWork() below - handler.removeMessages(QueuedWorkHandler.MSG_RUN); - - if (DEBUG) { - hadMessages = true; - Log.d(LOG_TAG, "waiting"); - } + if (DEBUG) { + hadMessages = getHandler().hasMessages(QueuedWorkHandler.MSG_RUN); + } + handlerRemoveMessages(QueuedWorkHandler.MSG_RUN); + if (DEBUG && hadMessages) { + Log.d(LOG_TAG, "waiting"); } // We should not delay any work as this might delay the finishers @@ -257,7 +269,7 @@ public class QueuedWork { sWork = new LinkedList<>(); // Remove all msg-s as all work will be processed now - getHandler().removeMessages(QueuedWorkHandler.MSG_RUN); + handlerRemoveMessages(QueuedWorkHandler.MSG_RUN); } if (work.size() > 0) { diff --git a/core/java/android/app/contextualsearch/OWNERS b/core/java/android/app/contextualsearch/OWNERS new file mode 100644 index 000000000000..0c2612c9957b --- /dev/null +++ b/core/java/android/app/contextualsearch/OWNERS @@ -0,0 +1 @@ +include /core/java/android/service/contextualsearch/OWNERS diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index e9b94c9f5791..87fb84331af3 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -185,7 +185,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * * @param context A Context object which should be some mock instance (like the * instance of {@link android.test.mock.MockContext}). - * @param readPermission The read permision you want this instance should have in the + * @param readPermission The read permission you want this instance should have in the * test, which is available via {@link #getReadPermission()}. * @param writePermission The write permission you want this instance should have * in the test, which is available via {@link #getWritePermission()}. diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index 9253998b325a..a126363237b8 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -387,7 +387,7 @@ public abstract class ContentResolver implements ContentInterface { * {@link Bundle} under {@link #EXTRA_HONORED_ARGS}. * <li>When querying a provider, where no QUERY_ARG_SQL* otherwise exists in * the arguments {@link Bundle}, the Content framework will attempt to - * synthesize an QUERY_ARG_SQL* argument using the corresponding + * synthesize a QUERY_ARG_SQL* argument using the corresponding * QUERY_ARG_SORT* values. */ public static final String QUERY_ARG_SORT_COLUMNS = "android:query-arg-sort-columns"; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 8744eaee4341..bc29f8b7ed86 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -4479,6 +4479,10 @@ public abstract class PackageManager { * the Android Keystore backed by an isolated execution environment. The version indicates * which features are implemented in the isolated execution environment: * <ul> + * <li>300: Ability to include a second IMEI in the ID attestation record, see + * {@link android.app.admin.DevicePolicyManager#ID_TYPE_IMEI}. + * <li>200: Hardware support for Curve 25519 (including both Ed25519 signature generation and + * X25519 key agreement). * <li>100: Hardware support for ECDH (see {@link javax.crypto.KeyAgreement}) and support * for app-generated attestation keys (see {@link * android.security.keystore.KeyGenParameterSpec.Builder#setAttestKeyAlias(String)}). @@ -4508,6 +4512,11 @@ public abstract class PackageManager { * StrongBox</a>. If this feature has a version, the version number indicates which features are * implemented in StrongBox: * <ul> + * <li>300: Ability to include a second IMEI in the ID attestation record, see + * {@link android.app.admin.DevicePolicyManager#ID_TYPE_IMEI}. + * <li>200: No new features for StrongBox (the Android Keystore environment backed by an + * isolated execution environment has gained support for Curve 25519 in this version, but + * the implementation backed by a dedicated secure processor is not expected to implement it). * <li>100: Hardware support for ECDH (see {@link javax.crypto.KeyAgreement}) and support * for app-generated attestation keys (see {@link * android.security.keystore.KeyGenParameterSpec.Builder#setAttestKeyAlias(String)}). diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java index cb1d3f5252b2..3b7ade25ecb2 100644 --- a/core/java/android/database/Cursor.java +++ b/core/java/android/database/Cursor.java @@ -511,7 +511,7 @@ public interface Cursor extends Closeable { Bundle getExtras(); /** - * This is an out-of-band way for the the user of a cursor to communicate with the cursor. The + * This is an out-of-band way for the user of a cursor to communicate with the cursor. The * structure of each bundle is entirely defined by the cursor. * * <p>One use of this is to tell a cursor that it should retry its network request after it diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 665d8d280bc6..47f5b4c3a5f6 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -5313,7 +5313,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * </code></pre> * <ul> * <li>VIDEO_STABILIZATION_MODES: {OFF, PREVIEW}</li> - * <li>AE_TARGET_FPS_RANGE: {{<em>, 30}, {</em>, 60}}</li> + * <li>AE_TARGET_FPS_RANGE: {{<em>, 30}, {</em>, 60}}</li> * <li>DYNAMIC_RANGE_PROFILE: {STANDARD, HLG10}</li> * </ul> * <p>This key is available on all devices.</p> diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index f3496e7f2592..b1ef05a6f00c 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -71,7 +71,7 @@ import java.util.UUID; */ public class ZygoteProcess { - private static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000; + private static final int ZYGOTE_CONNECT_TIMEOUT_MS = 60000; /** * Use a relatively short delay, because for app zygote, this is in the critical path of diff --git a/core/java/android/service/contextualsearch/OWNERS b/core/java/android/service/contextualsearch/OWNERS new file mode 100644 index 000000000000..463adf48dd3e --- /dev/null +++ b/core/java/android/service/contextualsearch/OWNERS @@ -0,0 +1,3 @@ +srazdan@google.com +volnov@google.com +hackz@google.com diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java index 59ec60545d6d..9db1060abad4 100644 --- a/core/java/android/view/InputWindowHandle.java +++ b/core/java/android/view/InputWindowHandle.java @@ -162,6 +162,12 @@ public final class InputWindowHandle { public float alpha; /** + * Sets a property on this window indicating that its visible region should be considered when + * computing TrustedPresentation Thresholds. + */ + public boolean canOccludePresentation; + + /** * The input token for the window to which focus should be transferred when this input window * can be successfully focused. If null, this input window will not transfer its focus to * any other window. @@ -205,6 +211,7 @@ public final class InputWindowHandle { focusTransferTarget = other.focusTransferTarget; contentSize = new Size(other.contentSize.getWidth(), other.contentSize.getHeight()); alpha = other.alpha; + canOccludePresentation = other.canOccludePresentation; } @Override @@ -219,6 +226,7 @@ public final class InputWindowHandle { .append(", isClone=").append((inputConfig & InputConfig.CLONE) != 0) .append(", contentSize=").append(contentSize) .append(", alpha=").append(alpha) + .append(", canOccludePresentation=").append(canOccludePresentation) .toString(); } diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 3ed03859ffa6..3c0ac06ae13f 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -168,6 +168,8 @@ public final class SurfaceControl implements Parcelable { boolean isTrustedOverlay); private static native void nativeSetDropInputMode( long transactionObj, long nativeObject, int flags); + private static native void nativeSetCanOccludePresentation(long transactionObj, + long nativeObject, boolean canOccludePresentation); private static native void nativeSurfaceFlushJankData(long nativeSurfaceObject); private static native boolean nativeClearContentFrameStats(long nativeObject); private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats); @@ -589,6 +591,28 @@ public final class SurfaceControl implements Parcelable { public static final int DISPLAY_DECORATION = 0x00000200; /** + * Ignore any destination frame set on the layer. This is used when the buffer scaling mode + * is freeze and the destination frame is applied asynchronously with the buffer submission. + * This is needed to maintain compatibility for SurfaceView scaling behavior. + * See SurfaceView scaling behavior for more details. + * @hide + */ + public static final int IGNORE_DESTINATION_FRAME = 0x00000400; + + /** + * Special casing for layer that is a refresh rate indicator + * @hide + */ + public static final int LAYER_IS_REFRESH_RATE_INDICATOR = 0x00000800; + + /** + * Sets a property on this layer indicating that its visible region should be considered when + * computing TrustedPresentation Thresholds + * @hide + */ + public static final int CAN_OCCLUDE_PRESENTATION = 0x00001000; + + /** * Surface creation flag: Creates a surface where color components are interpreted * as "non pre-multiplied" by their alpha channel. Of course this flag is * meaningless for surfaces without an alpha channel. By default @@ -4163,6 +4187,29 @@ public final class SurfaceControl implements Parcelable { } /** + * Sets a property on this SurfaceControl and all its children indicating that the visible + * region of this SurfaceControl should be considered when computing TrustedPresentation + * Thresholds. + * <p> + * API Guidance: + * The goal of this API is to identify windows that can be used to occlude content on + * another window. This includes windows controlled by the user or the system. If the window + * is transient, like Toast or notification shade, the window should not set this flag since + * the user or the app cannot use the window to occlude content in a persistent manner. All + * apps should have this flag set. + * <p> + * The caller must hold the ACCESS_SURFACE_FLINGER permission. + * @hide + */ + public Transaction setCanOccludePresentation(SurfaceControl sc, + boolean canOccludePresentation) { + checkPreconditions(sc); + final int value = (canOccludePresentation) ? CAN_OCCLUDE_PRESENTATION : 0; + nativeSetFlags(mNativeObject, sc.mNativeObject, value, CAN_OCCLUDE_PRESENTATION); + return this; + } + + /** * Sends a flush jank data transaction for the given surface. * @hide */ diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 1fdd1a5a5a5f..f54ef3868f53 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -425,12 +425,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te int mMotionViewNewTop; /** - * The X value associated with the the down motion event + * The X value associated with the down motion event */ int mMotionX; /** - * The Y value associated with the the down motion event + * The Y value associated with the down motion event */ @UnsupportedAppUsage int mMotionY; @@ -7381,7 +7381,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te scrap.dispatchStartTemporaryDetach(); - // The the accessibility state of the view may change while temporary + // the accessibility state of the view may change while temporary // detached and we do not allow detached views to fire accessibility // events. So we are announcing that the subtree changed giving a chance // to clients holding on to a view in this subtree to refresh it. @@ -7750,7 +7750,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } /** - * Abstract positon scroller used to handle smooth scrolling. + * Abstract position scroller used to handle smooth scrolling. */ static abstract class AbsPositionScroller { public abstract void start(int position); diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java index 76e97ad7a0f6..3b7e1e91f839 100644 --- a/core/java/android/widget/AbsSpinner.java +++ b/core/java/android/widget/AbsSpinner.java @@ -170,7 +170,7 @@ public abstract class AbsSpinner extends AdapterView<SpinnerAdapter> { * @see android.view.View#measure(int, int) * * Figure out the dimensions of this Spinner. The width comes from - * the widthMeasureSpec as Spinnners can't have their width set to + * the widthMeasureSpec as Spinners can't have their width set to * UNSPECIFIED. The height is based on the height of the selected item * plus padding. */ diff --git a/core/java/android/widget/OWNERS b/core/java/android/widget/OWNERS index e20357fa2dd9..1dc90edbd1e5 100644 --- a/core/java/android/widget/OWNERS +++ b/core/java/android/widget/OWNERS @@ -15,3 +15,5 @@ per-file SpellChecker.java = file:../view/inputmethod/OWNERS per-file Remote* = file:../appwidget/OWNERS per-file Toast.java = juliacr@google.com, jeffdq@google.com + +per-file flags/notification_widget_flags.aconfig = juliacr@google.com, jeffdq@google.com diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig index 4a6e8d761061..2e20cceb64de 100644 --- a/core/java/android/window/flags/windowing_sdk.aconfig +++ b/core/java/android/window/flags/windowing_sdk.aconfig @@ -16,7 +16,7 @@ flag { namespace: "windowing_sdk" name: "activity_embedding_overlay_presentation_flag" description: "Whether the overlay presentation feature is enabled" - bug: "243518738" + bug: "293370683" } flag { @@ -30,7 +30,7 @@ flag { namespace: "windowing_sdk" name: "fullscreen_dim_flag" description: "Whether to allow showing fullscreen dim on ActivityEmbedding split" - bug: "253533308" + bug: "293797706" } flag { @@ -44,7 +44,7 @@ flag { namespace: "windowing_sdk" name: "untrusted_embedding_any_app_permission" description: "Feature flag to enable the permission to embed any app in untrusted mode." - bug: "289199433" + bug: "293647332" is_fixed_read_only: true } @@ -60,5 +60,5 @@ flag { namespace: "windowing_sdk" name: "embedded_activity_back_nav_flag" description: "Refines embedded activity back navigation behavior" - bug: "240575809" + bug: "293642394" }
\ No newline at end of file diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp index ae23942f2500..bed776836043 100644 --- a/core/jni/android_hardware_input_InputWindowHandle.cpp +++ b/core/jni/android_hardware_input_InputWindowHandle.cpp @@ -75,6 +75,7 @@ static struct { jfieldID windowToken; jfieldID focusTransferTarget; jfieldID alpha; + jfieldID canOccludePresentation; } gInputWindowHandleClassInfo; static struct { @@ -327,6 +328,8 @@ jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env, gui::WindowIn javaObjectForIBinder(env, windowInfo.windowToken)); env->SetFloatField(inputWindowHandle, gInputWindowHandleClassInfo.alpha, windowInfo.alpha); + env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.canOccludePresentation, + windowInfo.canOccludePresentation); return inputWindowHandle; } @@ -451,6 +454,9 @@ int register_android_view_InputWindowHandle(JNIEnv* env) { GET_FIELD_ID(gInputWindowHandleClassInfo.alpha, clazz, "alpha", "F"); + GET_FIELD_ID(gInputWindowHandleClassInfo.canOccludePresentation, clazz, + "canOccludePresentation", "Z"); + jclass surfaceControlClazz; FIND_CLASS(surfaceControlClazz, "android/view/SurfaceControl"); GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegionSurfaceControl.mNativeObject, diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp index 2f29cae42d07..917d28348d04 100644 --- a/core/jni/android_opengl_EGL14.cpp +++ b/core/jni/android_opengl_EGL14.cpp @@ -17,6 +17,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" diff --git a/core/jni/android_opengl_EGL15.cpp b/core/jni/android_opengl_EGL15.cpp index b9c36b9ed9aa..447b8ec58ca7 100644 --- a/core/jni/android_opengl_EGL15.cpp +++ b/core/jni/android_opengl_EGL15.cpp @@ -17,6 +17,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" diff --git a/core/jni/android_opengl_EGLExt.cpp b/core/jni/android_opengl_EGLExt.cpp index cdc985273472..ffd75ea053d5 100644 --- a/core/jni/android_opengl_EGLExt.cpp +++ b/core/jni/android_opengl_EGLExt.cpp @@ -17,6 +17,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" @@ -54,11 +55,11 @@ nativeClassInit(JNIEnv *_env, jclass glImplClass) jclass eglsurfaceClassLocal = _env->FindClass("android/opengl/EGLSurface"); eglsurfaceClass = (jclass) _env->NewGlobalRef(eglsurfaceClassLocal); jclass eglsyncClassLocal = _env->FindClass("android/opengl/EGLSync"); - eglsyncClass = (jclass)_env->NewGlobalRef(eglsyncClassLocal); + eglsyncClass = (jclass) _env->NewGlobalRef(eglsyncClassLocal); egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getNativeHandle", "()J"); eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getNativeHandle", "()J"); - eglsyncGetHandleID = _env->GetMethodID(eglsyncClassLocal, "getNativeHandle", "()J"); + eglsyncGetHandleID = _env->GetMethodID(eglsyncClass, "getNativeHandle", "()J"); } static void * @@ -72,6 +73,14 @@ fromEGLHandle(JNIEnv *_env, jmethodID mid, jobject obj) { return reinterpret_cast<void*>(_env->CallLongMethod(obj, mid)); } +// TODO: this should be generated from the .spec file, but needs to be renamed and made private +static jint android_eglDupNativeFenceFDANDROID(JNIEnv *env, jobject, jobject dpy, jobject sync) { + EGLDisplay dpy_native = (EGLDisplay)fromEGLHandle(env, egldisplayGetHandleID, dpy); + EGLSync sync_native = (EGLSync)fromEGLHandle(env, eglsyncGetHandleID, sync); + + return eglDupNativeFenceFDANDROID(dpy_native, sync_native); +} + // -------------------------------------------------------------------------- /* EGLBoolean eglPresentationTimeANDROID ( EGLDisplay dpy, EGLSurface sur, EGLnsecsANDROID time ) */ static jboolean @@ -89,21 +98,12 @@ android_eglPresentationTimeANDROID return (jboolean)_returnValue; } -static jint android_eglDupNativeFenceFDANDROID(JNIEnv *env, jobject, jobject dpy, jobject sync) { - EGLDisplay dpy_native = (EGLDisplay)fromEGLHandle(env, egldisplayGetHandleID, dpy); - EGLSync sync_native = (EGLSync)fromEGLHandle(env, eglsyncGetHandleID, sync); - - return eglDupNativeFenceFDANDROID(dpy_native, sync_native); -} - static const char *classPathName = "android/opengl/EGLExt"; static const JNINativeMethod methods[] = { - {"_nativeClassInit", "()V", (void *)nativeClassInit}, - {"eglPresentationTimeANDROID", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;J)Z", - (void *)android_eglPresentationTimeANDROID}, - {"eglDupNativeFenceFDANDROIDImpl", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSync;)I", - (void *)android_eglDupNativeFenceFDANDROID}, +{"_nativeClassInit", "()V", (void*)nativeClassInit }, +{"eglPresentationTimeANDROID", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;J)Z", (void *) android_eglPresentationTimeANDROID }, +{"eglDupNativeFenceFDANDROIDImpl", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSync;)I", (void *)android_eglDupNativeFenceFDANDROID }, }; int register_android_opengl_jni_EGLExt(JNIEnv *_env) diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp index d65b498404fa..2d921ad59458 100644 --- a/core/jni/android_opengl_GLES10.cpp +++ b/core/jni/android_opengl_GLES10.cpp @@ -18,6 +18,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <GLES/gl.h> diff --git a/core/jni/android_opengl_GLES10Ext.cpp b/core/jni/android_opengl_GLES10Ext.cpp index 3638b87e201f..35a9a68cd8ab 100644 --- a/core/jni/android_opengl_GLES10Ext.cpp +++ b/core/jni/android_opengl_GLES10Ext.cpp @@ -18,6 +18,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <GLES/gl.h> diff --git a/core/jni/android_opengl_GLES11.cpp b/core/jni/android_opengl_GLES11.cpp index 9724e6c2a5dd..e04b56e5fa44 100644 --- a/core/jni/android_opengl_GLES11.cpp +++ b/core/jni/android_opengl_GLES11.cpp @@ -18,6 +18,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <GLES/gl.h> diff --git a/core/jni/android_opengl_GLES11Ext.cpp b/core/jni/android_opengl_GLES11Ext.cpp index 1ffa4ec67ae1..bccbda6d3f08 100644 --- a/core/jni/android_opengl_GLES11Ext.cpp +++ b/core/jni/android_opengl_GLES11Ext.cpp @@ -18,6 +18,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <GLES/gl.h> diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp index d832558aa368..165262e0893d 100644 --- a/core/jni/android_opengl_GLES20.cpp +++ b/core/jni/android_opengl_GLES20.cpp @@ -18,6 +18,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <GLES2/gl2.h> diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp index 719c6b32fec6..d3fe439eafb7 100644 --- a/core/jni/android_opengl_GLES30.cpp +++ b/core/jni/android_opengl_GLES30.cpp @@ -18,6 +18,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <GLES3/gl3.h> diff --git a/core/jni/android_opengl_GLES31.cpp b/core/jni/android_opengl_GLES31.cpp index afe7c63b6d47..b123f9d403df 100644 --- a/core/jni/android_opengl_GLES31.cpp +++ b/core/jni/android_opengl_GLES31.cpp @@ -17,6 +17,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <stdint.h> diff --git a/core/jni/android_opengl_GLES31Ext.cpp b/core/jni/android_opengl_GLES31Ext.cpp index 81274331ffa4..1e4049b8671d 100644 --- a/core/jni/android_opengl_GLES31Ext.cpp +++ b/core/jni/android_opengl_GLES31Ext.cpp @@ -17,6 +17,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <GLES3/gl31.h> diff --git a/core/jni/android_opengl_GLES32.cpp b/core/jni/android_opengl_GLES32.cpp index 7ed754850ea3..e0175f079ab7 100644 --- a/core/jni/android_opengl_GLES32.cpp +++ b/core/jni/android_opengl_GLES32.cpp @@ -17,6 +17,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <stdint.h> diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp index 21de72397384..ef29c880a8a1 100644 --- a/core/jni/com_google_android_gles_jni_GLImpl.cpp +++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp @@ -18,6 +18,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" diff --git a/libs/hwui/jni/android_graphics_Canvas.cpp b/libs/hwui/jni/android_graphics_Canvas.cpp index 295f4dce72b5..e5bdeeea75be 100644 --- a/libs/hwui/jni/android_graphics_Canvas.cpp +++ b/libs/hwui/jni/android_graphics_Canvas.cpp @@ -763,41 +763,41 @@ static void punchHole(JNIEnv* env, jobject, jlong canvasPtr, jfloat left, jfloat }; // namespace CanvasJNI static const JNINativeMethod gMethods[] = { - {"nGetNativeFinalizer", "()J", (void*) CanvasJNI::getNativeFinalizer}, - {"nFreeCaches", "()V", (void*) CanvasJNI::freeCaches}, - {"nFreeTextLayoutCaches", "()V", (void*) CanvasJNI::freeTextLayoutCaches}, - {"nSetCompatibilityVersion", "(I)V", (void*) CanvasJNI::setCompatibilityVersion}, - - // ------------ @FastNative ---------------- - {"nInitRaster", "(J)J", (void*) CanvasJNI::initRaster}, - {"nSetBitmap", "(JJ)V", (void*) CanvasJNI::setBitmap}, - {"nGetClipBounds","(JLandroid/graphics/Rect;)Z", (void*) CanvasJNI::getClipBounds}, - - // ------------ @CriticalNative ---------------- - {"nIsOpaque","(J)Z", (void*) CanvasJNI::isOpaque}, - {"nGetWidth","(J)I", (void*) CanvasJNI::getWidth}, - {"nGetHeight","(J)I", (void*) CanvasJNI::getHeight}, - {"nSave","(JI)I", (void*) CanvasJNI::save}, - {"nSaveLayer","(JFFFFJ)I", (void*) CanvasJNI::saveLayer}, - {"nSaveLayerAlpha","(JFFFFI)I", (void*) CanvasJNI::saveLayerAlpha}, - {"nSaveUnclippedLayer","(JIIII)I", (void*) CanvasJNI::saveUnclippedLayer}, - {"nRestoreUnclippedLayer","(JIJ)V", (void*) CanvasJNI::restoreUnclippedLayer}, - {"nGetSaveCount","(J)I", (void*) CanvasJNI::getSaveCount}, - {"nRestore","(J)Z", (void*) CanvasJNI::restore}, - {"nRestoreToCount","(JI)V", (void*) CanvasJNI::restoreToCount}, - {"nGetMatrix", "(JJ)V", (void*)CanvasJNI::getMatrix}, - {"nSetMatrix","(JJ)V", (void*) CanvasJNI::setMatrix}, - {"nConcat","(JJ)V", (void*) CanvasJNI::concat}, - {"nConcat","(J[F)V", (void*) CanvasJNI::concat44}, - {"nRotate","(JF)V", (void*) CanvasJNI::rotate}, - {"nScale","(JFF)V", (void*) CanvasJNI::scale}, - {"nSkew","(JFF)V", (void*) CanvasJNI::skew}, - {"nTranslate","(JFF)V", (void*) CanvasJNI::translate}, - {"nQuickReject","(JJ)Z", (void*) CanvasJNI::quickRejectPath}, - {"nQuickReject","(JFFFF)Z", (void*)CanvasJNI::quickRejectRect}, - {"nClipRect","(JFFFFI)Z", (void*) CanvasJNI::clipRect}, - {"nClipPath","(JJI)Z", (void*) CanvasJNI::clipPath}, - {"nSetDrawFilter", "(JJ)V", (void*) CanvasJNI::setPaintFilter}, + {"nGetNativeFinalizer", "()J", (void*)CanvasJNI::getNativeFinalizer}, + {"nFreeCaches", "()V", (void*)CanvasJNI::freeCaches}, + {"nFreeTextLayoutCaches", "()V", (void*)CanvasJNI::freeTextLayoutCaches}, + {"nSetCompatibilityVersion", "(I)V", (void*)CanvasJNI::setCompatibilityVersion}, + + // ------------ @FastNative ---------------- + {"nInitRaster", "(J)J", (void*)CanvasJNI::initRaster}, + {"nSetBitmap", "(JJ)V", (void*)CanvasJNI::setBitmap}, + {"nGetClipBounds", "(JLandroid/graphics/Rect;)Z", (void*)CanvasJNI::getClipBounds}, + + // ------------ @CriticalNative ---------------- + {"nIsOpaque", "(J)Z", (void*)CanvasJNI::isOpaque}, + {"nGetWidth", "(J)I", (void*)CanvasJNI::getWidth}, + {"nGetHeight", "(J)I", (void*)CanvasJNI::getHeight}, + {"nSave", "(JI)I", (void*)CanvasJNI::save}, + {"nSaveLayer", "(JFFFFJ)I", (void*)CanvasJNI::saveLayer}, + {"nSaveLayerAlpha", "(JFFFFI)I", (void*)CanvasJNI::saveLayerAlpha}, + {"nSaveUnclippedLayer", "(JIIII)I", (void*)CanvasJNI::saveUnclippedLayer}, + {"nRestoreUnclippedLayer", "(JIJ)V", (void*)CanvasJNI::restoreUnclippedLayer}, + {"nGetSaveCount", "(J)I", (void*)CanvasJNI::getSaveCount}, + {"nRestore", "(J)Z", (void*)CanvasJNI::restore}, + {"nRestoreToCount", "(JI)V", (void*)CanvasJNI::restoreToCount}, + {"nGetMatrix", "(JJ)V", (void*)CanvasJNI::getMatrix}, + {"nSetMatrix", "(JJ)V", (void*)CanvasJNI::setMatrix}, + {"nConcat", "(JJ)V", (void*)CanvasJNI::concat}, + {"nConcat", "(J[F)V", (void*)CanvasJNI::concat44}, + {"nRotate", "(JF)V", (void*)CanvasJNI::rotate}, + {"nScale", "(JFF)V", (void*)CanvasJNI::scale}, + {"nSkew", "(JFF)V", (void*)CanvasJNI::skew}, + {"nTranslate", "(JFF)V", (void*)CanvasJNI::translate}, + {"nQuickReject", "(JJ)Z", (void*)CanvasJNI::quickRejectPath}, + {"nQuickReject", "(JFFFF)Z", (void*)CanvasJNI::quickRejectRect}, + {"nClipRect", "(JFFFFI)Z", (void*)CanvasJNI::clipRect}, + {"nClipPath", "(JJI)Z", (void*)CanvasJNI::clipPath}, + {"nSetDrawFilter", "(JJ)V", (void*)CanvasJNI::setPaintFilter}, }; // If called from Canvas these are regular JNI diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java index 7b6dc38fe22c..6b0620c58d31 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java @@ -17,6 +17,7 @@ package android.media.tv.interactive; import android.annotation.CallSuper; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.MainThread; import android.annotation.NonNull; @@ -44,6 +45,7 @@ import android.media.tv.TvInputManager; import android.media.tv.TvRecordingInfo; import android.media.tv.TvTrackInfo; import android.media.tv.TvView; +import android.media.tv.flags.Flags; import android.media.tv.interactive.TvInteractiveAppView.TvInteractiveAppCallback; import android.net.Uri; import android.net.http.SslCertificate; @@ -959,12 +961,12 @@ public abstract class TvInteractiveAppService extends Service { /** * Called when the TV App sends the selected track info as a response to - * requestSelectedTrackInfo. + * {@link #requestSelectedTrackInfo()} * - * @param tracks - * @hide + * @param tracks A list of {@link TvTrackInfo} that are currently selected */ - public void onSelectedTrackInfo(List<TvTrackInfo> tracks) { + @FlaggedApi(Flags.FLAG_TIAF_V_APIS) + public void onSelectedTrackInfo(@NonNull List<TvTrackInfo> tracks) { } @Override @@ -1373,13 +1375,13 @@ public abstract class TvInteractiveAppService extends Service { } /** - * Requests the currently selected {@link TvTrackInfo} from the TV App. + * Requests a list of the currently selected {@link TvTrackInfo} from the TV App. * * <p> Normally, track info cannot be synchronized until the channel has - * been changed. This is used when the session of the TIAS is newly - * created and the normal synchronization has not happened yet. - * @hide + * been changed. This is used when the session of the {@link TvInteractiveAppService} + * is newly created and the normal synchronization has not happened yet. */ + @FlaggedApi(Flags.FLAG_TIAF_V_APIS) @CallSuper public void requestSelectedTrackInfo() { executeOrPostRunnableOnMainThread(() -> { diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppView.java b/media/java/android/media/tv/interactive/TvInteractiveAppView.java index 3b295742c244..584ea841b18c 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppView.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppView.java @@ -17,6 +17,7 @@ package android.media.tv.interactive; import android.annotation.CallbackExecutor; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; @@ -30,6 +31,7 @@ import android.media.tv.TvInputManager; import android.media.tv.TvRecordingInfo; import android.media.tv.TvTrackInfo; import android.media.tv.TvView; +import android.media.tv.flags.Flags; import android.media.tv.interactive.TvInteractiveAppManager.Session; import android.media.tv.interactive.TvInteractiveAppManager.Session.FinishedInputEventCallback; import android.media.tv.interactive.TvInteractiveAppManager.SessionCallback; @@ -585,8 +587,9 @@ public class TvInteractiveAppView extends ViewGroup { /** * Sends the currently selected track info to the TV Interactive App. * - * @hide + * @param tracks list of {@link TvTrackInfo} of the currently selected track(s) */ + @FlaggedApi(Flags.FLAG_TIAF_V_APIS) public void sendSelectedTrackInfo(@Nullable List<TvTrackInfo> tracks) { if (DEBUG) { Log.d(TAG, "sendSelectedTrackInfo"); @@ -1248,8 +1251,8 @@ public class TvInteractiveAppView extends ViewGroup { * called. * * @param iAppServiceId The ID of the TV interactive app service bound to this view. - * @hide */ + @FlaggedApi(Flags.FLAG_TIAF_V_APIS) public void onRequestSelectedTrackInfo(@NonNull String iAppServiceId) { } diff --git a/media/tests/EffectsTest/src/com/android/effectstest/EffectsTest.java b/media/tests/EffectsTest/src/com/android/effectstest/EffectsTest.java index 70202463a79e..c18a2de44573 100644 --- a/media/tests/EffectsTest/src/com/android/effectstest/EffectsTest.java +++ b/media/tests/EffectsTest/src/com/android/effectstest/EffectsTest.java @@ -41,7 +41,7 @@ public class EffectsTest extends Activity { public EffectsTest() { - Log.d(TAG, "contructor"); + Log.d(TAG, "constructor"); } @Override diff --git a/opengl/java/android/opengl/EGLExt.java b/opengl/java/android/opengl/EGLExt.java index 1570e0e22f50..31104a0d0a08 100644 --- a/opengl/java/android/opengl/EGLExt.java +++ b/opengl/java/android/opengl/EGLExt.java @@ -46,14 +46,6 @@ public class EGLExt { _nativeClassInit(); } - // C function EGLBoolean eglPresentationTimeANDROID ( EGLDisplay dpy, EGLSurface sur, EGLnsecsANDROID time ) - - public static native boolean eglPresentationTimeANDROID( - EGLDisplay dpy, - EGLSurface sur, - long time - ); - /** * Retrieves the SyncFence for an EGLSync created with EGL_SYNC_NATIVE_FENCE_ANDROID * @@ -83,4 +75,13 @@ public class EGLExt { } private static native int eglDupNativeFenceFDANDROIDImpl(EGLDisplay display, EGLSync sync); + + // C function EGLBoolean eglPresentationTimeANDROID ( EGLDisplay dpy, EGLSurface sur, EGLnsecsANDROID time ) + + public static native boolean eglPresentationTimeANDROID( + EGLDisplay dpy, + EGLSurface sur, + long time + ); + } diff --git a/packages/CrashRecovery/services/Android.bp b/packages/CrashRecovery/services/Android.bp index 27ddff93247e..63e6c5083376 100644 --- a/packages/CrashRecovery/services/Android.bp +++ b/packages/CrashRecovery/services/Android.bp @@ -3,7 +3,15 @@ filegroup { srcs: [ "java/**/*.java", "java/**/*.aidl", + ":statslog-crashrecovery-java-gen", ], - path: "java", visibility: ["//frameworks/base:__subpackages__"], } + +genrule { + name: "statslog-crashrecovery-java-gen", + tools: ["stats-log-api-gen"], + cmd: "$(location stats-log-api-gen) --java $(out) --module crashrecovery " + + "--javaPackage com.android.server.crashrecovery.proto --javaClass CrashRecoveryStatsLog --worksource", + out: ["com/android/server/crashrecovery/proto/CrashRecoveryStatsLog.java"], +} diff --git a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java index dd543349fc4d..dffe4e239ec9 100644 --- a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java +++ b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java @@ -46,11 +46,11 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; -import com.android.internal.util.FrameworkStatsLog; import com.android.server.PackageWatchdog.FailureReasons; import com.android.server.PackageWatchdog.PackageHealthObserver; import com.android.server.PackageWatchdog.PackageHealthObserverImpact; import com.android.server.am.SettingsToPropertiesMapper; +import com.android.server.crashrecovery.proto.CrashRecoveryStatsLog; import java.io.File; import java.util.ArrayList; @@ -390,7 +390,7 @@ public class RescueParty { return; } - FrameworkStatsLog.write(FrameworkStatsLog.RESCUE_PARTY_RESET_REPORTED, level); + CrashRecoveryStatsLog.write(CrashRecoveryStatsLog.RESCUE_PARTY_RESET_REPORTED, level); // Try our best to reset all settings possible, and once finished // rethrow any exception that we encountered Exception res = null; diff --git a/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java index 2007079ea5ca..50322f09640f 100644 --- a/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java +++ b/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java @@ -39,13 +39,13 @@ import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.Preconditions; import com.android.server.PackageWatchdog; import com.android.server.PackageWatchdog.FailureReasons; import com.android.server.PackageWatchdog.PackageHealthObserver; import com.android.server.PackageWatchdog.PackageHealthObserverImpact; import com.android.server.SystemConfig; +import com.android.server.crashrecovery.proto.CrashRecoveryStatsLog; import com.android.server.pm.ApexManager; import java.io.BufferedReader; @@ -418,7 +418,7 @@ final class RollbackPackageHealthObserver implements PackageHealthObserver { final VersionedPackage logPackage = logPackageTemp; WatchdogRollbackLogger.logEvent(logPackage, - FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE, + CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE, reasonToLog, failedPackageToLog); Consumer<Intent> onResult = result -> { @@ -430,19 +430,19 @@ final class RollbackPackageHealthObserver implements PackageHealthObserver { int rollbackId = rollback.getRollbackId(); saveStagedRollbackId(rollbackId, logPackage); WatchdogRollbackLogger.logEvent(logPackage, - FrameworkStatsLog + CrashRecoveryStatsLog .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED, reasonToLog, failedPackageToLog); } else { WatchdogRollbackLogger.logEvent(logPackage, - FrameworkStatsLog + CrashRecoveryStatsLog .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS, reasonToLog, failedPackageToLog); } } else { WatchdogRollbackLogger.logEvent(logPackage, - FrameworkStatsLog + CrashRecoveryStatsLog .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE, reasonToLog, failedPackageToLog); } diff --git a/packages/CrashRecovery/services/java/com/android/server/rollback/WatchdogRollbackLogger.java b/packages/CrashRecovery/services/java/com/android/server/rollback/WatchdogRollbackLogger.java index f9ef994a523a..898c5439a293 100644 --- a/packages/CrashRecovery/services/java/com/android/server/rollback/WatchdogRollbackLogger.java +++ b/packages/CrashRecovery/services/java/com/android/server/rollback/WatchdogRollbackLogger.java @@ -16,16 +16,16 @@ package com.android.server.rollback; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_CRASH; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_NOT_RESPONDING; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_EXPLICIT_HEALTH_CHECK; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH_DURING_BOOT; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_CRASH; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_NOT_RESPONDING; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_EXPLICIT_HEALTH_CHECK; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH_DURING_BOOT; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS; import android.annotation.NonNull; import android.annotation.Nullable; @@ -42,8 +42,8 @@ import android.util.ArraySet; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.FrameworkStatsLog; import com.android.server.PackageWatchdog; +import com.android.server.crashrecovery.proto.CrashRecoveryStatsLog; import java.util.List; import java.util.Set; @@ -197,8 +197,8 @@ public final class WatchdogRollbackLogger { + " rollbackReason: " + rollbackReasonToString(rollbackReason) + " failedPackageName: " + failingPackageName); if (logPackage != null) { - FrameworkStatsLog.write( - FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED, + CrashRecoveryStatsLog.write( + CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED, type, logPackage.getPackageName(), logPackage.getVersionCode(), @@ -208,8 +208,8 @@ public final class WatchdogRollbackLogger { } else { // In the case that the log package is null, still log an empty string as an // indication that retrieving the logging parent failed. - FrameworkStatsLog.write( - FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED, + CrashRecoveryStatsLog.write( + CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED, type, "", 0, diff --git a/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml new file mode 100644 index 000000000000..a877853eaec8 --- /dev/null +++ b/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml @@ -0,0 +1,244 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" +xmlns:app="http://schemas.android.com/apk/res-auto" +xmlns:tools="http://schemas.android.com/tools" +android:layout_width="match_parent" +android:layout_height="match_parent"> + + <ImageView + android:id="@+id/logo" + android:layout_width="@dimen/biometric_auth_icon_size" + android:layout_height="@dimen/biometric_auth_icon_size" + android:layout_gravity="center" + android:scaleType="fitXY" + android:visibility="gone" /> + + <ImageView + android:id="@+id/background" + android:layout_width="0dp" + android:layout_height="0dp" + android:contentDescription="@string/biometric_dialog_empty_space_description" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <View + android:id="@+id/panel" + android:layout_width="0dp" + android:layout_height="0dp" + android:background="?android:attr/colorBackgroundFloating" + android:clickable="true" + android:clipToOutline="true" + android:importantForAccessibility="no" + android:paddingHorizontal="16dp" + android:paddingVertical="16dp" + android:visibility="visible" + app:layout_constraintBottom_toTopOf="@+id/bottomGuideline" + app:layout_constraintEnd_toStartOf="@+id/rightGuideline" + app:layout_constraintStart_toStartOf="@+id/leftGuideline" + app:layout_constraintTop_toTopOf="@+id/title" /> + + <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper + android:id="@+id/biometric_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.8" + tools:srcCompat="@tools:sample/avatars" /> + + <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper + android:id="@+id/biometric_icon_overlay" + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_gravity="center" + android:contentDescription="@null" + android:scaleType="fitXY" + app:layout_constraintBottom_toBottomOf="@+id/biometric_icon" + app:layout_constraintEnd_toEndOf="@+id/biometric_icon" + app:layout_constraintHorizontal_bias="1.0" + app:layout_constraintStart_toStartOf="@+id/biometric_icon" + app:layout_constraintTop_toTopOf="@+id/biometric_icon" + app:layout_constraintVertical_bias="0.0" /> + + <TextView + android:id="@+id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="@integer/biometric_dialog_text_gravity" + android:singleLine="true" + android:marqueeRepeatLimit="1" + android:ellipsize="marquee" + style="@style/TextAppearance.AuthCredential.Title" + app:layout_constraintBottom_toTopOf="@+id/subtitle" + app:layout_constraintEnd_toEndOf="@+id/panel" + app:layout_constraintStart_toStartOf="@+id/panel" /> + + <TextView + android:id="@+id/subtitle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="@integer/biometric_dialog_text_gravity" + android:singleLine="true" + android:marqueeRepeatLimit="1" + android:ellipsize="marquee" + style="@style/TextAppearance.AuthCredential.Subtitle" + app:layout_constraintBottom_toTopOf="@+id/description" + app:layout_constraintEnd_toEndOf="@+id/panel" + app:layout_constraintStart_toStartOf="@+id/panel" /> + + <Space + android:id="@+id/space_above_content" + android:layout_width="match_parent" + android:layout_height="@dimen/biometric_prompt_space_above_content" + android:visibility="gone" + app:layout_constraintTop_toBottomOf="@+id/subtitle" + app:layout_constraintEnd_toEndOf="@+id/panel" + app:layout_constraintStart_toStartOf="@+id/panel"/> + + <ScrollView + android:id="@+id/customized_view_container" + android:layout_width="0dp" + android:layout_height="0dp" + android:fillViewport="true" + android:fadeScrollbars="false" + android:gravity="center_vertical" + android:orientation="vertical" + android:paddingHorizontal="@dimen/biometric_prompt_content_container_padding_horizontal" + android:scrollbars="vertical" + android:visibility="gone" + app:layout_constraintTop_toBottomOf="@+id/space_above_content" + app:layout_constraintBottom_toTopOf="@+id/biometric_icon" + app:layout_constraintEnd_toEndOf="@+id/panel" + app:layout_constraintStart_toStartOf="@+id/panel"/> + + <TextView + android:id="@+id/description" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="24dp" + android:scrollbars="vertical" + android:gravity="@integer/biometric_dialog_text_gravity" + style="@style/TextAppearance.AuthCredential.Description" + app:layout_constraintBottom_toTopOf="@+id/biometric_icon" + app:layout_constraintEnd_toEndOf="@+id/panel" + app:layout_constraintStart_toStartOf="@+id/panel" /> + + <TextView + android:id="@+id/indicator" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:gravity="center_horizontal" + android:textColor="@color/biometric_dialog_gray" + android:textSize="12sp" + android:accessibilityLiveRegion="polite" + android:marqueeRepeatLimit="marquee_forever" + android:scrollHorizontally="true" + android:fadingEdge="horizontal" + app:layout_constraintEnd_toEndOf="@+id/panel" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toStartOf="@+id/panel" + app:layout_constraintTop_toBottomOf="@+id/biometric_icon" /> + + <!-- Negative Button, reserved for app --> + <Button + android:id="@+id/button_negative" + style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginLeft="8dp" + android:ellipsize="end" + android:maxLines="2" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/panel" + app:layout_constraintStart_toStartOf="@+id/panel" /> + + <!-- Cancel Button, replaces negative button when biometric is accepted --> + <Button + android:id="@+id/button_cancel" + style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginLeft="8dp" + android:text="@string/cancel" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/panel" + app:layout_constraintStart_toStartOf="@+id/panel" /> + + <!-- "Use Credential" Button, replaces if device credential is allowed --> + <Button + android:id="@+id/button_use_credential" + style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginLeft="8dp" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/panel" + app:layout_constraintStart_toStartOf="@+id/panel" /> + + <!-- Positive Button --> + <Button + android:id="@+id/button_confirm" + style="@*android:style/Widget.DeviceDefault.Button.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginRight="8dp" + android:ellipsize="end" + android:maxLines="2" + android:text="@string/biometric_dialog_confirm" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/panel" + app:layout_constraintEnd_toEndOf="@+id/panel" + tools:visibility="invisible" /> + + <!-- Try Again Button --> + <Button + android:id="@+id/button_try_again" + style="@*android:style/Widget.DeviceDefault.Button.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginRight="8dp" + android:ellipsize="end" + android:maxLines="2" + android:text="@string/biometric_dialog_try_again" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/panel" + app:layout_constraintEnd_toEndOf="@+id/panel" /> + + <!-- Guidelines for setting panel border --> + <androidx.constraintlayout.widget.Guideline + android:id="@+id/leftGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_begin="@dimen/biometric_dialog_border_padding" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/rightGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_end="@dimen/biometric_dialog_border_padding" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/bottomGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintGuide_end="@dimen/biometric_dialog_border_padding" /> + +</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java index dfeb1f318081..d821f1982e58 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java @@ -33,7 +33,7 @@ import com.android.systemui.res.R; public abstract class KeyguardAbsKeyInputView extends KeyguardInputView { protected View mEcaView; - // To avoid accidental lockout due to events while the device in in the pocket, ignore + // To avoid accidental lockout due to events while the device in the pocket, ignore // any passwords with length less than or equal to this length. protected static final int MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT = 3; private KeyDownListener mKeyDownListener; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java index bc12aeebd84c..ce03072e2f0b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java @@ -132,7 +132,7 @@ public interface KeyguardViewController { boolean shouldSubtleWindowAnimationsForUnlock(); /** - * Starts the animation before we dismiss Keyguard, i.e. an disappearing animation on the + * Starts the animation before we dismiss Keyguard, i.e. a disappearing animation on the * security view of the bouncer. * * @param finishRunnable the runnable to be run after the animation finished, or {@code null} if diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index 57e308ff16e8..3397906aa6ea 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -20,6 +20,7 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static com.android.internal.jank.InteractionJankMonitor.CUJ_BIOMETRIC_PROMPT_TRANSITION; +import static com.android.systemui.Flags.constraintBp; import android.animation.Animator; import android.annotation.IntDef; @@ -57,6 +58,7 @@ import android.widget.ScrollView; import android.window.OnBackInvokedCallback; import android.window.OnBackInvokedDispatcher; +import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.view.AccessibilityDelegateCompat; import androidx.core.view.ViewCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; @@ -153,7 +155,7 @@ public class AuthContainerView extends LinearLayout @Nullable private Spaghetti mBiometricView; @Nullable private View mCredentialView; private final AuthPanelController mPanelController; - private final FrameLayout mFrameLayout; + private final ViewGroup mLayout; private final ImageView mBackgroundView; private final ScrollView mBiometricScrollView; private final View mPanelView; @@ -339,11 +341,16 @@ public class AuthContainerView extends LinearLayout mBiometricCallback = new BiometricCallback(); final LayoutInflater layoutInflater = LayoutInflater.from(mContext); - mFrameLayout = (FrameLayout) layoutInflater.inflate( - R.layout.auth_container_view, this, false /* attachToRoot */); - addView(mFrameLayout); - mBiometricScrollView = mFrameLayout.findViewById(R.id.biometric_scrollview); - mBackgroundView = mFrameLayout.findViewById(R.id.background); + if (constraintBp()) { + mLayout = (ConstraintLayout) layoutInflater.inflate( + R.layout.biometric_prompt_constraint_layout, this, false /* attachToRoot */); + } else { + mLayout = (FrameLayout) layoutInflater.inflate( + R.layout.auth_container_view, this, false /* attachToRoot */); + } + mBiometricScrollView = mLayout.findViewById(R.id.biometric_scrollview); + addView(mLayout); + mBackgroundView = mLayout.findViewById(R.id.background); ViewCompat.setAccessibilityDelegate(mBackgroundView, new AccessibilityDelegateCompat() { @Override public void onInitializeAccessibilityNodeInfo(View host, @@ -358,7 +365,7 @@ public class AuthContainerView extends LinearLayout } }); - mPanelView = mFrameLayout.findViewById(R.id.panel); + mPanelView = mLayout.findViewById(R.id.panel); mPanelController = new AuthPanelController(mContext, mPanelView); mBackgroundExecutor = bgExecutor; mInteractionJankMonitor = jankMonitor; @@ -402,20 +409,31 @@ public class AuthContainerView extends LinearLayout new BiometricModalities(fpProps, faceProps), config.mOpPackageName); - final BiometricPromptLayout view = (BiometricPromptLayout) layoutInflater.inflate( - R.layout.biometric_prompt_layout, null, false); - mBiometricView = BiometricViewBinder.bind(view, viewModel, mPanelController, - // TODO(b/201510778): This uses the wrong timeout in some cases - getJankListener(view, TRANSIT, - BiometricViewSizeBinder.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS), - mBackgroundView, mBiometricCallback, mApplicationCoroutineScope, - vibratorHelper); - - // TODO(b/251476085): migrate these dependencies - if (fpProps != null && fpProps.isAnyUdfpsType()) { - view.setUdfpsAdapter(new UdfpsDialogMeasureAdapter(view, fpProps), - config.mScaleProvider); + if (constraintBp()) { + mBiometricView = BiometricViewBinder.bind(mLayout, viewModel, null, + // TODO(b/201510778): This uses the wrong timeout in some cases + getJankListener(mLayout, TRANSIT, + BiometricViewSizeBinder.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS), + mBackgroundView, mBiometricCallback, mApplicationCoroutineScope, + vibratorHelper); + } else { + final BiometricPromptLayout view = (BiometricPromptLayout) layoutInflater.inflate( + R.layout.biometric_prompt_layout, null, false); + mBiometricView = BiometricViewBinder.bind(view, viewModel, mPanelController, + // TODO(b/201510778): This uses the wrong timeout in some cases + getJankListener(view, TRANSIT, + BiometricViewSizeBinder.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS), + mBackgroundView, mBiometricCallback, mApplicationCoroutineScope, + vibratorHelper); + + // TODO(b/251476085): migrate these dependencies + if (fpProps != null && fpProps.isAnyUdfpsType()) { + view.setUdfpsAdapter(new UdfpsDialogMeasureAdapter(view, fpProps), + config.mScaleProvider); + } } + } else if (constraintBp() && Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo)) { + addCredentialView(true, false); } else { mPromptSelectorInteractorProvider.get().resetPrompt(); } @@ -477,7 +495,7 @@ public class AuthContainerView extends LinearLayout vm.setAnimateContents(animateContents); ((CredentialView) mCredentialView).init(vm, this, mPanelController, animatePanel); - mFrameLayout.addView(mCredentialView); + mLayout.addView(mCredentialView); } @Override @@ -488,7 +506,9 @@ public class AuthContainerView extends LinearLayout @Override public void onOrientationChanged() { - maybeUpdatePositionForUdfps(true /* invalidate */); + if (!constraintBp()) { + maybeUpdatePositionForUdfps(true /* invalidate */); + } } @Override @@ -502,8 +522,9 @@ public class AuthContainerView extends LinearLayout mWakefulnessLifecycle.addObserver(this); mPanelInteractionDetector.enable( () -> animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED)); - - if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) { + if (constraintBp()) { + // Do nothing on attachment with constraintLayout + } else if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) { mBiometricScrollView.addView(mBiometricView.asView()); } else if (Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo)) { addCredentialView(true /* animatePanel */, false /* animateContents */); @@ -512,7 +533,9 @@ public class AuthContainerView extends LinearLayout + mConfig.mPromptInfo.getAuthenticators()); } - maybeUpdatePositionForUdfps(false /* invalidate */); + if (!constraintBp()) { + maybeUpdatePositionForUdfps(false /* invalidate */); + } if (mConfig.mSkipIntro) { mContainerState = STATE_SHOWING; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt index 285ab4a800b6..efad21bda380 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt @@ -41,6 +41,7 @@ import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.airbnb.lottie.LottieAnimationView import com.airbnb.lottie.LottieCompositionFactory +import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.AuthPanelController import com.android.systemui.biometrics.shared.model.BiometricModalities import com.android.systemui.biometrics.shared.model.BiometricModality @@ -70,9 +71,9 @@ object BiometricViewBinder { @SuppressLint("ClickableViewAccessibility") @JvmStatic fun bind( - view: BiometricPromptLayout, + view: View, viewModel: PromptViewModel, - panelViewController: AuthPanelController, + panelViewController: AuthPanelController?, jankListener: BiometricJankListener, backgroundView: View, legacyCallback: Spaghetti.Callback, @@ -112,11 +113,18 @@ object BiometricViewBinder { val iconOverlayView = view.requireViewById<LottieAnimationView>(R.id.biometric_icon_overlay) val iconView = view.requireViewById<LottieAnimationView>(R.id.biometric_icon) + val iconSizeOverride = + if (constraintBp()) { + viewModel.fingerprintAffordanceSize + } else { + (view as BiometricPromptLayout).updatedFingerprintAffordanceSize + } + PromptIconViewBinder.bind( iconView, iconOverlayView, - view.getUpdatedFingerprintAffordanceSize(), - viewModel + iconSizeOverride, + viewModel, ) val indicatorMessageView = view.requireViewById<TextView>(R.id.indicator) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt index d5695f31f121..2417fe9cd333 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt @@ -19,29 +19,45 @@ package com.android.systemui.biometrics.ui.binder import android.animation.Animator import android.animation.AnimatorSet import android.animation.ValueAnimator +import android.graphics.Outline +import android.graphics.Rect +import android.transition.AutoTransition +import android.transition.TransitionManager import android.view.Surface import android.view.View import android.view.ViewGroup +import android.view.ViewOutlineProvider import android.view.WindowInsets import android.view.WindowManager import android.view.accessibility.AccessibilityManager import android.widget.ImageView import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.constraintlayout.widget.ConstraintSet +import androidx.constraintlayout.widget.Guideline import androidx.core.animation.addListener +import androidx.core.view.doOnAttach import androidx.core.view.doOnLayout import androidx.core.view.isGone import androidx.lifecycle.lifecycleScope +import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.AuthPanelController import com.android.systemui.biometrics.Utils -import com.android.systemui.biometrics.ui.BiometricPromptLayout +import com.android.systemui.biometrics.ui.viewmodel.PromptPosition import com.android.systemui.biometrics.ui.viewmodel.PromptSize import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel +import com.android.systemui.biometrics.ui.viewmodel.isBottom import com.android.systemui.biometrics.ui.viewmodel.isLarge +import com.android.systemui.biometrics.ui.viewmodel.isLeft import com.android.systemui.biometrics.ui.viewmodel.isMedium import com.android.systemui.biometrics.ui.viewmodel.isNullOrNotSmall +import com.android.systemui.biometrics.ui.viewmodel.isRight import com.android.systemui.biometrics.ui.viewmodel.isSmall +import com.android.systemui.biometrics.ui.viewmodel.isTop import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R +import kotlin.math.abs +import kotlin.math.min import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch @@ -54,18 +70,19 @@ object BiometricViewSizeBinder { /** Resizes [BiometricPromptLayout] and the [panelViewController] via the [PromptViewModel]. */ fun bind( - view: BiometricPromptLayout, + view: View, viewModel: PromptViewModel, viewsToHideWhenSmall: List<View>, viewsToFadeInOnSizeChange: List<View>, - panelViewController: AuthPanelController, + panelViewController: AuthPanelController?, jankListener: BiometricJankListener, ) { val windowManager = requireNotNull(view.context.getSystemService(WindowManager::class.java)) val accessibilityManager = requireNotNull(view.context.getSystemService(AccessibilityManager::class.java)) + fun notifyAccessibilityChanged() { - Utils.notifyAccessibilityContentChanged(accessibilityManager, view) + Utils.notifyAccessibilityContentChanged(accessibilityManager, view as ViewGroup) } fun startMonitoredAnimation(animators: List<Animator>) { @@ -77,149 +94,342 @@ object BiometricViewSizeBinder { } } - val iconHolderView = view.requireViewById<View>(R.id.biometric_icon_frame) - val iconPadding = view.resources.getDimension(R.dimen.biometric_dialog_icon_padding) - val fullSizeYOffset = - view.resources.getDimension(R.dimen.biometric_dialog_medium_to_large_translation_offset) - - // cache the original position of the icon view (as done in legacy view) - // this must happen before any size changes can be made - view.doOnLayout { - // TODO(b/251476085): this old way of positioning has proven itself unreliable - // remove this and associated thing like (UdfpsDialogMeasureAdapter) and - // pin to the physical sensor - val iconHolderOriginalY = iconHolderView.y - - // bind to prompt - // TODO(b/251476085): migrate the legacy panel controller and simplify this - view.repeatWhenAttached { - var currentSize: PromptSize? = null - lifecycleScope.launch { - /** - * View is only set visible in BiometricViewSizeBinder once PromptSize is - * determined that accounts for iconView size, to prevent prompt resizing being - * visible to the user. - * - * TODO(b/288175072): May be able to remove isIconViewLoaded once constraint - * layout is implemented - */ - combine(viewModel.isIconViewLoaded, viewModel.size, ::Pair).collect { - (isIconViewLoaded, size) -> - if (!isIconViewLoaded) { - return@collect - } + if (constraintBp()) { + val leftGuideline = view.requireViewById<Guideline>(R.id.leftGuideline) + val rightGuideline = view.requireViewById<Guideline>(R.id.rightGuideline) + val bottomGuideline = view.requireViewById<Guideline>(R.id.bottomGuideline) + + val iconHolderView = view.requireViewById<View>(R.id.biometric_icon) + val panelView = view.requireViewById<View>(R.id.panel) + val cornerRadius = view.resources.getDimension(R.dimen.biometric_dialog_corner_size) + + // ConstraintSets for animating between prompt sizes + val mediumConstraintSet = ConstraintSet() + mediumConstraintSet.clone(view as ConstraintLayout) + + val smallConstraintSet = ConstraintSet() + smallConstraintSet.clone(mediumConstraintSet) + viewsToHideWhenSmall.forEach { smallConstraintSet.setVisibility(it.id, View.GONE) } + + val largeConstraintSet = ConstraintSet() + largeConstraintSet.clone(mediumConstraintSet) + viewsToHideWhenSmall.forEach { largeConstraintSet.setVisibility(it.id, View.GONE) } + largeConstraintSet.setVisibility(iconHolderView.id, View.GONE) + largeConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE) + largeConstraintSet.setVisibility(R.id.indicator, View.GONE) + largeConstraintSet.setGuidelineBegin(leftGuideline.id, 0) + largeConstraintSet.setGuidelineEnd(rightGuideline.id, 0) + largeConstraintSet.setGuidelineEnd(bottomGuideline.id, 0) + + // Round the panel outline + panelView.outlineProvider = + object : ViewOutlineProvider() { + override fun getOutline(view: View, outline: Outline) { + outline.setRoundRect(0, 0, view.width, view.height, cornerRadius) + } + } - // prepare for animated size transitions - for (v in viewsToHideWhenSmall) { - v.showContentOrHide(forceHide = size.isSmall) + view.doOnLayout { + val windowBounds = windowManager.maximumWindowMetrics.bounds + val bottomInset = + windowManager.maximumWindowMetrics.windowInsets + .getInsets(WindowInsets.Type.navigationBars()) + .bottom + + fun measureBounds(position: PromptPosition) { + val width = min(windowBounds.height(), windowBounds.width()) + + var left = -1 + var top = -1 + var right = -1 + var bottom = -1 + + when { + position.isTop -> { + left = windowBounds.centerX() - width / 2 + viewModel.promptMargin + top = viewModel.promptMargin + right = windowBounds.centerX() - width / 2 + viewModel.promptMargin + bottom = iconHolderView.centerY() * 2 - iconHolderView.centerY() / 4 } - if (currentSize == null && size.isSmall) { - iconHolderView.alpha = 0f + position.isBottom -> { + if (view.isLandscape()) { + left = windowBounds.centerX() - width / 2 + viewModel.promptMargin + top = iconHolderView.centerY() + right = windowBounds.centerX() - width / 2 + viewModel.promptMargin + bottom = bottomInset + viewModel.promptMargin + } else { + left = windowBounds.centerX() - width / 2 + viewModel.promptMargin + top = + windowBounds.height() - + (windowBounds.height() - iconHolderView.centerY()) * 2 + + viewModel.promptMargin + right = windowBounds.centerX() - width / 2 + viewModel.promptMargin + bottom = viewModel.promptMargin + } } - if ((currentSize.isSmall && size.isMedium) || size.isSmall) { - viewsToFadeInOnSizeChange.forEach { it.alpha = 0f } + + // For Udfps exclusive left and right, measure guideline to center + // icon in BP + position.isLeft -> { + left = viewModel.promptMargin + top = + windowBounds.height() - + (windowBounds.height() - iconHolderView.centerY()) * 2 + + viewModel.promptMargin + right = + abs( + windowBounds.width() - iconHolderView.centerX() * 2 + + viewModel.promptMargin + ) + bottom = bottomInset + viewModel.promptMargin } + position.isRight -> { + left = + abs( + iconHolderView.centerX() - + (windowBounds.width() - iconHolderView.centerX()) - + viewModel.promptMargin + ) + top = + windowBounds.height() - + (windowBounds.height() - iconHolderView.centerY()) * 2 + + viewModel.promptMargin + right = viewModel.promptMargin + bottom = bottomInset + viewModel.promptMargin + } + } - // TODO(b/302735104): Fix wrong height due to the delay of - // PromptContentView. addOnLayoutChangeListener() will cause crash when - // showing credential view, since |PromptIconViewModel| won't release the - // flow. - // propagate size changes to legacy panel controller and animate transitions - view.doOnLayout { - val width = view.measuredWidth - val height = view.measuredHeight - - when { - size.isSmall -> { - iconHolderView.alpha = 1f - val bottomInset = - windowManager.maximumWindowMetrics.windowInsets - .getInsets(WindowInsets.Type.navigationBars()) - .bottom - iconHolderView.y = - if (view.isLandscape()) { - (view.height - iconHolderView.height - bottomInset) / 2f - } else { - view.height - - iconHolderView.height - - iconPadding - - bottomInset - } - val newHeight = - iconHolderView.height + (2 * iconPadding.toInt()) - - iconHolderView.paddingTop - - iconHolderView.paddingBottom - panelViewController.updateForContentDimensions( - width, - newHeight + bottomInset, - 0, /* animateDurationMs */ - ) - } - size.isMedium && currentSize.isSmall -> { - val duration = ANIMATE_SMALL_TO_MEDIUM_DURATION_MS - panelViewController.updateForContentDimensions( - width, - height, - duration, - ) - startMonitoredAnimation( - listOf( - iconHolderView.asVerticalAnimator( - duration = duration.toLong(), - toY = - iconHolderOriginalY - - viewsToHideWhenSmall - .filter { it.isGone } - .sumOf { it.height }, - ), - viewsToFadeInOnSizeChange.asFadeInAnimator( - duration = duration.toLong(), - delay = duration.toLong(), - ), + val bounds = Rect(left, top, right, bottom) + if (bounds.shouldAdjustLeftGuideline()) { + leftGuideline.setGuidelineBegin(bounds.left) + smallConstraintSet.setGuidelineBegin(leftGuideline.id, bounds.left) + mediumConstraintSet.setGuidelineBegin(leftGuideline.id, bounds.left) + } + if (bounds.shouldAdjustRightGuideline()) { + rightGuideline.setGuidelineEnd(bounds.right) + smallConstraintSet.setGuidelineEnd(rightGuideline.id, bounds.right) + mediumConstraintSet.setGuidelineEnd(rightGuideline.id, bounds.right) + } + if (bounds.shouldAdjustBottomGuideline()) { + bottomGuideline.setGuidelineEnd(bounds.bottom) + smallConstraintSet.setGuidelineEnd(bottomGuideline.id, bounds.bottom) + mediumConstraintSet.setGuidelineEnd(bottomGuideline.id, bounds.bottom) + } + } + + view.repeatWhenAttached { + var currentSize: PromptSize? = null + lifecycleScope.launch { + combine(viewModel.position, viewModel.size, ::Pair).collect { + (position, size) -> + view.doOnAttach { + measureBounds(position) + + when { + size.isSmall -> { + val ratio = + if (view.isLandscape()) { + (windowBounds.height() - + bottomInset - + viewModel.promptMargin) + .toFloat() / windowBounds.height() + } else { + (windowBounds.height() - viewModel.promptMargin) + .toFloat() / windowBounds.height() + } + smallConstraintSet.setVerticalBias(iconHolderView.id, ratio) + + smallConstraintSet.applyTo(view as ConstraintLayout?) + } + size.isMedium && currentSize.isSmall -> { + val autoTransition = AutoTransition() + autoTransition.setDuration( + ANIMATE_SMALL_TO_MEDIUM_DURATION_MS.toLong() ) - ) - } - size.isMedium && currentSize.isNullOrNotSmall -> { - panelViewController.updateForContentDimensions( - width, - height, - 0, /* animateDurationMs */ - ) + + TransitionManager.beginDelayedTransition( + view, + autoTransition + ) + mediumConstraintSet.applyTo(view) + } + size.isLarge -> { + val autoTransition = AutoTransition() + autoTransition.setDuration( + ANIMATE_MEDIUM_TO_LARGE_DURATION_MS.toLong() + ) + + TransitionManager.beginDelayedTransition( + view, + autoTransition + ) + largeConstraintSet.applyTo(view) + } } - size.isLarge -> { - val duration = ANIMATE_MEDIUM_TO_LARGE_DURATION_MS - panelViewController.setUseFullScreen(true) - panelViewController.updateForContentDimensions( - panelViewController.containerWidth, - panelViewController.containerHeight, - duration, - ) - - startMonitoredAnimation( - listOf( - view.asVerticalAnimator( - duration.toLong() * 2 / 3, - toY = view.y - fullSizeYOffset - ), - listOf(view) - .asFadeInAnimator( - duration = duration.toLong() / 2, + + currentSize = size + view.visibility = View.VISIBLE + viewModel.setIsIconViewLoaded(false) + notifyAccessibilityChanged() + + view.invalidate() + view.requestLayout() + } + } + } + } + } + } else if (panelViewController != null) { + val iconHolderView = view.requireViewById<View>(R.id.biometric_icon_frame) + val iconPadding = view.resources.getDimension(R.dimen.biometric_dialog_icon_padding) + val fullSizeYOffset = + view.resources.getDimension( + R.dimen.biometric_dialog_medium_to_large_translation_offset + ) + + // cache the original position of the icon view (as done in legacy view) + // this must happen before any size changes can be made + view.doOnLayout { + // TODO(b/251476085): this old way of positioning has proven itself unreliable + // remove this and associated thing like (UdfpsDialogMeasureAdapter) and + // pin to the physical sensor + val iconHolderOriginalY = iconHolderView.y + + // bind to prompt + // TODO(b/251476085): migrate the legacy panel controller and simplify this + view.repeatWhenAttached { + var currentSize: PromptSize? = null + lifecycleScope.launch { + /** + * View is only set visible in BiometricViewSizeBinder once PromptSize is + * determined that accounts for iconView size, to prevent prompt resizing + * being visible to the user. + * + * TODO(b/288175072): May be able to remove isIconViewLoaded once constraint + * layout is implemented + */ + combine(viewModel.isIconViewLoaded, viewModel.size, ::Pair).collect { + (isIconViewLoaded, size) -> + if (!isIconViewLoaded) { + return@collect + } + + // prepare for animated size transitions + for (v in viewsToHideWhenSmall) { + v.showContentOrHide(forceHide = size.isSmall) + } + if (currentSize == null && size.isSmall) { + iconHolderView.alpha = 0f + } + if ((currentSize.isSmall && size.isMedium) || size.isSmall) { + viewsToFadeInOnSizeChange.forEach { it.alpha = 0f } + } + + // TODO(b/302735104): Fix wrong height due to the delay of + // PromptContentView. addOnLayoutChangeListener() will cause crash when + // showing credential view, since |PromptIconViewModel| won't release + // the + // flow. + // propagate size changes to legacy panel controller and animate + // transitions + view.doOnLayout { + val width = view.measuredWidth + val height = view.measuredHeight + + when { + size.isSmall -> { + iconHolderView.alpha = 1f + val bottomInset = + windowManager.maximumWindowMetrics.windowInsets + .getInsets(WindowInsets.Type.navigationBars()) + .bottom + iconHolderView.y = + if (view.isLandscape()) { + (view.height - + iconHolderView.height - + bottomInset) / 2f + } else { + view.height - + iconHolderView.height - + iconPadding - + bottomInset + } + val newHeight = + iconHolderView.height + (2 * iconPadding.toInt()) - + iconHolderView.paddingTop - + iconHolderView.paddingBottom + panelViewController.updateForContentDimensions( + width, + newHeight + bottomInset, + 0, /* animateDurationMs */ + ) + } + size.isMedium && currentSize.isSmall -> { + val duration = ANIMATE_SMALL_TO_MEDIUM_DURATION_MS + panelViewController.updateForContentDimensions( + width, + height, + duration, + ) + startMonitoredAnimation( + listOf( + iconHolderView.asVerticalAnimator( + duration = duration.toLong(), + toY = + iconHolderOriginalY - + viewsToHideWhenSmall + .filter { it.isGone } + .sumOf { it.height }, + ), + viewsToFadeInOnSizeChange.asFadeInAnimator( + duration = duration.toLong(), delay = duration.toLong(), ), + ) ) - ) - // TODO(b/251476085): clean up (copied from legacy) - if (view.isAttachedToWindow) { - val parent = view.parent as? ViewGroup - parent?.removeView(view) + } + size.isMedium && currentSize.isNullOrNotSmall -> { + panelViewController.updateForContentDimensions( + width, + height, + 0, /* animateDurationMs */ + ) + } + size.isLarge -> { + val duration = ANIMATE_MEDIUM_TO_LARGE_DURATION_MS + panelViewController.setUseFullScreen(true) + panelViewController.updateForContentDimensions( + panelViewController.containerWidth, + panelViewController.containerHeight, + duration, + ) + + startMonitoredAnimation( + listOf( + view.asVerticalAnimator( + duration.toLong() * 2 / 3, + toY = view.y - fullSizeYOffset + ), + listOf(view) + .asFadeInAnimator( + duration = duration.toLong() / 2, + delay = duration.toLong(), + ), + ) + ) + // TODO(b/251476085): clean up (copied from legacy) + if (view.isAttachedToWindow) { + val parent = view.parent as? ViewGroup + parent?.removeView(view) + } } } - } - currentSize = size - view.visibility = View.VISIBLE - viewModel.setIsIconViewLoaded(false) - notifyAccessibilityChanged() + currentSize = size + view.visibility = View.VISIBLE + viewModel.setIsIconViewLoaded(false) + notifyAccessibilityChanged() + } } } } @@ -244,6 +454,20 @@ private fun View.showContentOrHide(forceHide: Boolean = false) { } } +private fun View.centerX(): Int { + return (x + width / 2).toInt() +} + +private fun View.centerY(): Int { + return (y + height / 2).toInt() +} + +private fun Rect.shouldAdjustLeftGuideline(): Boolean = left != -1 + +private fun Rect.shouldAdjustRightGuideline(): Boolean = right != -1 + +private fun Rect.shouldAdjustBottomGuideline(): Boolean = bottom != -1 + private fun View.asVerticalAnimator( duration: Long, toY: Float, diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt index 6e3bcf575072..2e47375b69fe 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt @@ -17,13 +17,17 @@ package com.android.systemui.biometrics.ui.binder +import android.graphics.Rect import android.graphics.drawable.Animatable2 import android.graphics.drawable.AnimatedVectorDrawable import android.graphics.drawable.Drawable +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.constraintlayout.widget.ConstraintSet import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.airbnb.lottie.LottieAnimationView import com.android.settingslib.widget.LottieColorUtils +import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel.AuthType import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel @@ -119,6 +123,24 @@ object PromptIconViewBinder { } launch { + viewModel.iconPosition.collect { position -> + if (constraintBp() && position != Rect()) { + val iconParams = iconView.layoutParams as ConstraintLayout.LayoutParams + + if (position.left != -1) { + iconParams.endToEnd = ConstraintSet.UNSET + iconParams.leftMargin = position.left + } + if (position.top != -1) { + iconParams.bottomToBottom = ConstraintSet.UNSET + iconParams.topMargin = position.top + } + iconView.layoutParams = iconParams + } + } + } + + launch { viewModel.iconAsset .sample( combine( diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt index 3defec5ca48d..b7cffaf2bcde 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt @@ -20,8 +20,11 @@ package com.android.systemui.biometrics.ui.viewmodel import android.annotation.DrawableRes import android.annotation.RawRes import android.content.res.Configuration +import android.graphics.Rect +import android.util.RotationUtils import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.biometrics.shared.model.DisplayRotation import com.android.systemui.biometrics.shared.model.FingerprintSensorType import com.android.systemui.res.R @@ -42,7 +45,8 @@ class PromptIconViewModel constructor( promptViewModel: PromptViewModel, private val displayStateInteractor: DisplayStateInteractor, - promptSelectorInteractor: PromptSelectorInteractor + promptSelectorInteractor: PromptSelectorInteractor, + udfpsOverlayInteractor: UdfpsOverlayInteractor, ) { /** Auth types for the UI to display. */ @@ -71,7 +75,40 @@ constructor( } else if (modalities.hasFingerprintOnly) { AuthType.Fingerprint } else { - throw IllegalStateException("unexpected modality: $modalities") + // TODO(b/288175072): Remove, currently needed for transition to credential view + AuthType.Fingerprint + } + } + + val udfpsSensorBounds: Flow<Rect> = + combine( + udfpsOverlayInteractor.udfpsOverlayParams, + displayStateInteractor.currentRotation + ) { params, rotation -> + val rotatedBounds = Rect(params.sensorBounds) + RotationUtils.rotateBounds( + rotatedBounds, + params.naturalDisplayWidth, + params.naturalDisplayHeight, + rotation.ordinal + ) + rotatedBounds + } + .distinctUntilChanged() + + val iconPosition: Flow<Rect> = + combine(udfpsSensorBounds, promptViewModel.size, promptViewModel.modalities) { + sensorBounds, + size, + modalities -> + // If not Udfps, icon does not change from default layout position + if (!modalities.hasUdfps) { + Rect() // Empty rect, don't offset from default position + } else if (size.isSmall) { + // When small with Udfps, only set horizontal position + Rect(sensorBounds.left, -1, sensorBounds.right, -1) + } else { + sensorBounds } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptPosition.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptPosition.kt new file mode 100644 index 000000000000..d45dad616e99 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptPosition.kt @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2024 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.biometrics.ui.viewmodel + +/** The position of a biometric prompt */ +enum class PromptPosition { + Top, + Bottom, + Left, + Right, +} + +val PromptPosition?.isBottom: Boolean + get() = this != null && this == PromptPosition.Bottom + +val PromptPosition?.isLeft: Boolean + get() = this != null && this == PromptPosition.Left + +val PromptPosition?.isRight: Boolean + get() = this != null && this == PromptPosition.Right + +val PromptPosition?.isTop: Boolean + get() = this != null && this == PromptPosition.Top diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt index a39aabfabd73..ef5c37eaa953 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt @@ -82,11 +82,23 @@ constructor( val faceIconHeight: Int = context.resources.getDimensionPixelSize(R.dimen.biometric_dialog_face_icon_size) + val fingerprintSensorDiameter: Int = + (udfpsOverlayInteractor.udfpsOverlayParams.value.sensorBounds.width() * + udfpsOverlayInteractor.udfpsOverlayParams.value.scaleFactor) + .toInt() + val fingerprintAffordanceSize: Pair<Int, Int>? = + if (fingerprintSensorDiameter != 0) + Pair(fingerprintSensorDiameter, fingerprintSensorDiameter) + else null + private val _accessibilityHint = MutableSharedFlow<String>() /** Hint for talkback directional guidance */ val accessibilityHint: Flow<String> = _accessibilityHint.asSharedFlow() + val promptMargin: Int = + context.resources.getDimensionPixelSize(R.dimen.biometric_dialog_border_padding) + private val _isAuthenticating: MutableStateFlow<Boolean> = MutableStateFlow(false) /** If the user is currently authenticating (i.e. at least one biometric is scanning). */ @@ -136,6 +148,22 @@ constructor( /** Event fired to the view indicating a [HapticFeedbackConstants] to be played */ val hapticsToPlay = _hapticsToPlay.asStateFlow() + /** The current position of the prompt */ + val position: Flow<PromptPosition> = + combine(_forceLargeSize, modalities, displayStateInteractor.currentRotation) { + forceLarge, + modalities, + rotation -> + when { + forceLarge || !modalities.hasUdfps -> PromptPosition.Bottom + rotation == DisplayRotation.ROTATION_90 -> PromptPosition.Right + rotation == DisplayRotation.ROTATION_270 -> PromptPosition.Left + rotation == DisplayRotation.ROTATION_180 -> PromptPosition.Top + else -> PromptPosition.Bottom + } + } + .distinctUntilChanged() + /** The size of the prompt. */ val size: Flow<PromptSize> = combine( @@ -196,7 +224,12 @@ constructor( .distinctUntilChanged() val iconViewModel: PromptIconViewModel = - PromptIconViewModel(this, displayStateInteractor, promptSelectorInteractor) + PromptIconViewModel( + this, + displayStateInteractor, + promptSelectorInteractor, + udfpsOverlayInteractor + ) private val _isIconViewLoaded = MutableStateFlow(false) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java index 9b83b75cec22..ee3706a3ba62 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java @@ -80,7 +80,7 @@ public class KeyguardIndication { } /** - * Click listener for messsage. + * Click listener for message. */ public @Nullable View.OnClickListener getClickListener() { return mOnClickListener; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index f085e88da954..4766a84b97ee 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -444,7 +444,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, /** * Whether a hide is pending and we are just waiting for #startKeyguardExitAnimation to be * called. - * */ + */ private boolean mHiding; /** diff --git a/services/contextualsearch/OWNERS b/services/contextualsearch/OWNERS new file mode 100644 index 000000000000..0c2612c9957b --- /dev/null +++ b/services/contextualsearch/OWNERS @@ -0,0 +1 @@ +include /core/java/android/service/contextualsearch/OWNERS diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index a15cb102747b..a23c08a9e5c6 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -716,7 +716,10 @@ public class HdmiCecMessageValidator { // Programmed int programedInfo = params[offset] & 0x0F; if (isValidProgrammedInfo(programedInfo)) { - if (programedInfo == 0x09 || programedInfo == 0x0B) { + offset = offset + 1; + // Duration Available (2 bytes) + if ((programedInfo == 0x09 || programedInfo == 0x0B) + && params.length - offset >= 2) { durationAvailable = true; } else { return true; @@ -726,16 +729,17 @@ public class HdmiCecMessageValidator { // Non programmed int nonProgramedErrorInfo = params[offset] & 0x0F; if (isValidNotProgrammedErrorInfo(nonProgramedErrorInfo)) { - if (nonProgramedErrorInfo == 0x0E) { + offset = offset + 1; + // Duration Available (2 bytes) + if (nonProgramedErrorInfo == 0x0E && params.length - offset >= 2) { durationAvailable = true; } else { return true; } } } - offset = offset + 1; // Duration Available (2 bytes) - if (durationAvailable && params.length - offset >= 2) { + if (durationAvailable) { return (isValidDurationHours(params[offset]) && isValidMinute(params[offset + 1])); } return false; diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index cb00e44f09a9..fff4939a5e0f 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -3185,24 +3185,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } } } - - if (mDeviceIdToShowIme == DEVICE_ID_DEFAULT) { - String ime = SecureSettingsWrapper.getString( - Settings.Secure.DEFAULT_INPUT_METHOD, null, mSettings.getUserId()); - String defaultDeviceIme = SecureSettingsWrapper.getString( - Settings.Secure.DEFAULT_DEVICE_INPUT_METHOD, null, mSettings.getUserId()); - if (defaultDeviceIme != null && !Objects.equals(ime, defaultDeviceIme)) { - if (DEBUG) { - Slog.v(TAG, "Current input method " + ime + " differs from the stored default" - + " device input method for user " + mSettings.getUserId() - + " - restoring " + defaultDeviceIme); - } - SecureSettingsWrapper.putString( - Settings.Secure.DEFAULT_INPUT_METHOD, defaultDeviceIme, - mSettings.getUserId()); - } - } - // We are assuming that whoever is changing DEFAULT_INPUT_METHOD and // ENABLED_INPUT_METHODS is taking care of keeping them correctly in // sync, so we will never have a DEFAULT_INPUT_METHOD that is not @@ -5388,11 +5370,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub if (!setSubtypeOnly) { // Set InputMethod here - final String imeId = imi != null ? imi.getId() : ""; - mSettings.putSelectedInputMethod(imeId); - if (mDeviceIdToShowIme == DEVICE_ID_DEFAULT) { - mSettings.putSelectedDefaultDeviceInputMethod(imeId); - } + mSettings.putSelectedInputMethod(imi != null ? imi.getId() : ""); } } @@ -5535,9 +5513,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub return false; // IME is not found or not enabled. } settings.putSelectedInputMethod(imeId); - if (mDeviceIdToShowIme == DEVICE_ID_DEFAULT) { - settings.putSelectedDefaultDeviceInputMethod(imeId); - } settings.putSelectedSubtype(NOT_A_SUBTYPE_ID); return true; } @@ -6584,9 +6559,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // Reset selected IME. settings.putSelectedInputMethod(nextIme); - if (mDeviceIdToShowIme == DEVICE_ID_DEFAULT) { - settings.putSelectedDefaultDeviceInputMethod(nextIme); - } settings.putSelectedSubtype(NOT_A_SUBTYPE_ID); } out.println("Reset current and enabled IMEs for user #" + userId); diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSettings.java b/services/core/java/com/android/server/inputmethod/InputMethodSettings.java index e444db1b79e8..a51002be344f 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodSettings.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodSettings.java @@ -36,6 +36,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.function.Predicate; /** @@ -87,6 +88,12 @@ final class InputMethodSettings { mMethodMap = methodMap; mMethodList = methodMap.values(); mUserId = userId; + String ime = getSelectedInputMethod(); + String defaultDeviceIme = getSelectedDefaultDeviceInputMethod(); + if (defaultDeviceIme != null && !Objects.equals(ime, defaultDeviceIme)) { + putSelectedInputMethod(defaultDeviceIme); + putSelectedDefaultDeviceInputMethod(null); + } } @AnyThread diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 1c9bbab3969e..31c1d7653926 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -8844,19 +8844,26 @@ public class NotificationManagerService extends SystemService { } } + private PendingIntent getNotificationTimeoutPendingIntent(NotificationRecord record, + int flags) { + flags |= PendingIntent.FLAG_IMMUTABLE; + return PendingIntent.getBroadcast(getContext(), + REQUEST_CODE_TIMEOUT, + new Intent(ACTION_NOTIFICATION_TIMEOUT) + .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME) + .setData(new Uri.Builder().scheme(SCHEME_TIMEOUT) + .appendPath(record.getKey()).build()) + .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) + .putExtra(EXTRA_KEY, record.getKey()), + flags); + } + @VisibleForTesting @GuardedBy("mNotificationLock") void scheduleTimeoutLocked(NotificationRecord record) { if (record.getNotification().getTimeoutAfter() > 0) { - final PendingIntent pi = PendingIntent.getBroadcast(getContext(), - REQUEST_CODE_TIMEOUT, - new Intent(ACTION_NOTIFICATION_TIMEOUT) - .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME) - .setData(new Uri.Builder().scheme(SCHEME_TIMEOUT) - .appendPath(record.getKey()).build()) - .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) - .putExtra(EXTRA_KEY, record.getKey()), - PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + final PendingIntent pi = getNotificationTimeoutPendingIntent( + record, PendingIntent.FLAG_UPDATE_CURRENT); mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + record.getNotification().getTimeoutAfter(), pi); } @@ -8864,6 +8871,16 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting @GuardedBy("mNotificationLock") + void cancelScheduledTimeoutLocked(NotificationRecord record) { + final PendingIntent pi = getNotificationTimeoutPendingIntent( + record, PendingIntent.FLAG_CANCEL_CURRENT); + if (pi != null) { + mAlarmManager.cancel(pi); + } + } + + @VisibleForTesting + @GuardedBy("mNotificationLock") /** * Determine whether this notification should attempt to make noise, vibrate, or flash the LED * @return buzzBeepBlink - bitfield (buzz ? 1 : 0) | (beep ? 2 : 0) | (blink ? 4 : 0) @@ -9894,21 +9911,7 @@ public class NotificationManagerService extends SystemService { 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 - // does not already exist, then null will be returned. - final PendingIntent pi = PendingIntent.getBroadcast(getContext(), - REQUEST_CODE_TIMEOUT, - new Intent(ACTION_NOTIFICATION_TIMEOUT) - .setData(new Uri.Builder().scheme(SCHEME_TIMEOUT) - .appendPath(r.getKey()).build()) - .addFlags(Intent.FLAG_RECEIVER_FOREGROUND), - PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE); - - // Cancel alarm corresponding to pi. - if (pi != null) { - mAlarmManager.cancel(pi); - } + cancelScheduledTimeoutLocked(r); // Record caller. recordCallerLocked(r); diff --git a/services/core/java/com/android/server/wm/TrustedPresentationListenerController.java b/services/core/java/com/android/server/wm/TrustedPresentationListenerController.java index 1688a1a91114..817901f96ad4 100644 --- a/services/core/java/com/android/server/wm/TrustedPresentationListenerController.java +++ b/services/core/java/com/android/server/wm/TrustedPresentationListenerController.java @@ -32,7 +32,6 @@ import android.os.HandlerThread; import android.os.IBinder; import android.os.RemoteException; import android.util.ArrayMap; -import android.util.ArraySet; import android.util.IntArray; import android.util.Pair; import android.util.Size; @@ -159,10 +158,6 @@ public class TrustedPresentationListenerController { private InputWindowHandle[] mLastWindowHandles; - private final Object mIgnoredWindowTokensLock = new Object(); - - private final ArraySet<IBinder> mIgnoredWindowTokens = new ArraySet<>(); - private void startHandlerThreadIfNeeded() { synchronized (mHandlerThreadLock) { if (mHandler == null) { @@ -173,18 +168,6 @@ public class TrustedPresentationListenerController { } } - void addIgnoredWindowTokens(IBinder token) { - synchronized (mIgnoredWindowTokensLock) { - mIgnoredWindowTokens.add(token); - } - } - - void removeIgnoredWindowTokens(IBinder token) { - synchronized (mIgnoredWindowTokensLock) { - mIgnoredWindowTokens.remove(token); - } - } - void registerListener(IBinder window, ITrustedPresentationListener listener, TrustedPresentationThresholds thresholds, int id) { startHandlerThreadIfNeeded(); @@ -271,12 +254,8 @@ public class TrustedPresentationListenerController { ArrayMap<ITrustedPresentationListener, Pair<IntArray, IntArray>> listenerUpdates = new ArrayMap<>(); - ArraySet<IBinder> ignoredWindowTokens; - synchronized (mIgnoredWindowTokensLock) { - ignoredWindowTokens = new ArraySet<>(mIgnoredWindowTokens); - } for (var windowHandle : mLastWindowHandles) { - if (ignoredWindowTokens.contains(windowHandle.getWindowToken())) { + if (!windowHandle.canOccludePresentation) { ProtoLog.v(WM_DEBUG_TPL, "Skipping %s", windowHandle.name); continue; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 24e50c54aa61..f5806c07c572 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1148,10 +1148,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP parentWindow.addChild(this, sWindowSubLayerComparator); } - if (token.mRoundedCornerOverlay) { - mWmService.mTrustedPresentationListenerController.addIgnoredWindowTokens( - getWindowToken()); - } } @Override @@ -1163,6 +1159,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (secureWindowState()) { getPendingTransaction().setSecure(mSurfaceControl, isSecureLocked()); } + // All apps should be considered as occluding when computing TrustedPresentation Thresholds. + final boolean canOccludePresentation = !mSession.mCanAddInternalSystemWindow; + getPendingTransaction().setCanOccludePresentation(mSurfaceControl, canOccludePresentation); } void updateTrustedOverlay() { @@ -2344,9 +2343,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mSession.onWindowRemoved(this); mWmService.postWindowRemoveCleanupLocked(this); - mWmService.mTrustedPresentationListenerController.removeIgnoredWindowTokens( - getWindowToken()); - consumeInsetsChange(); } diff --git a/services/tests/servicestests/utils/com/android/server/testutils/StubTransaction.java b/services/tests/servicestests/utils/com/android/server/testutils/StubTransaction.java index b8dcecdbfb95..e27bb4c8c3b6 100644 --- a/services/tests/servicestests/utils/com/android/server/testutils/StubTransaction.java +++ b/services/tests/servicestests/utils/com/android/server/testutils/StubTransaction.java @@ -320,4 +320,10 @@ public class StubTransaction extends SurfaceControl.Transaction { mWindowInfosReportedListeners.add(listener); return this; } + + @Override + public SurfaceControl.Transaction setCanOccludePresentation(SurfaceControl sc, + boolean canOccludePresentation) { + return this; + } } 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 ef0ac33bcfc5..df314c241179 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -1254,6 +1254,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verify(mAlarmManager).setExactAndAllowWhileIdle(anyInt(), anyLong(), captor.capture()); assertEquals(PackageManagerService.PLATFORM_PACKAGE_NAME, captor.getValue().getIntent().getPackage()); + + mService.cancelScheduledTimeoutLocked(r); + verify(mAlarmManager).cancel(captor.capture()); + assertEquals(PackageManagerService.PLATFORM_PACKAGE_NAME, + captor.getValue().getIntent().getPackage()); } @Test diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index a2105b02b97a..9ee48d85a600 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -21,6 +21,7 @@ import static android.Manifest.permission.MODIFY_PHONE_STATE; import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.ElapsedRealtimeLong; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; @@ -56,6 +57,7 @@ import android.view.Surface; import com.android.internal.os.SomeArgs; import com.android.internal.telecom.IVideoCallback; import com.android.internal.telecom.IVideoProvider; +import com.android.server.telecom.flags.Flags; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -4019,9 +4021,12 @@ public abstract class Connection extends Conferenceable { } /** + * Retrieves the direction of this connection. * @return The direction of the call. * @hide */ + @SystemApi + @FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) public final @Call.Details.CallDirection int getCallDirection() { return mCallDirection; } diff --git a/tools/aapt/ApkBuilder.h b/tools/aapt/ApkBuilder.h index 5d3abc63519f..92764020b120 100644 --- a/tools/aapt/ApkBuilder.h +++ b/tools/aapt/ApkBuilder.h @@ -44,7 +44,7 @@ public: android::status_t createSplitForConfigs(const std::set<ConfigDescription>& configs); /** - * Adds a file to be written to the final APK. It's name must not collide + * Adds a file to be written to the final APK. Its name must not collide * with that of any files previously added. When a Split APK is being * generated, duplicates can exist as long as they are in different splits * (resources.arsc, AndroidManifest.xml). diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp index 2f2ef92e72b4..66a05101c2a1 100644 --- a/tools/aapt/Main.cpp +++ b/tools/aapt/Main.cpp @@ -187,7 +187,7 @@ void usage(void) " be loaded alongside the base APK at runtime.\n" " --feature-of\n" " Builds a split APK that is a feature of the apk specified here. Resources\n" - " in the base APK can be referenced from the the feature APK.\n" + " in the base APK can be referenced from the feature APK.\n" " --feature-after\n" " An app can have multiple Feature Split APKs which must be totally ordered.\n" " If --feature-of is specified, this flag specifies which Feature Split APK\n" |