diff options
9 files changed, 157 insertions, 24 deletions
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index f58baffb1367..2ec5dbc5612a 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -1146,6 +1146,14 @@ interface IWindowManager */ KeyboardShortcutGroup getApplicationLaunchKeyboardShortcuts(int deviceId); + /* + * Notifies about IME insets animation. + * + * @param running Indicates the insets animation state. + * @param animationType Indicates the {@link InsetsController.AnimationType} + */ + oneway void notifyImeInsetsAnimationStateChanged(boolean running, int animationType); + /** * Returns whether the display with {@code displayId} ignores orientation request. */ diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index c174fbe0bbcd..e097a0764512 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -214,9 +214,14 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation * Notifies when the state of running animation is changed. The state is either "running" or * "idle". * - * @param running {@code true} if there is any animation running; {@code false} otherwise. + * @param running {@code true} if the given insets types start running + * {@code false} otherwise. + * @param animationType {@link AnimationType} + * @param insetsTypes {@link Type}. */ - default void notifyAnimationRunningStateChanged(boolean running) {} + default void notifyAnimationRunningStateChanged(boolean running, + @AnimationType int animationType, @InsetsType int insetsTypes) { + } /** @see ViewRootImpl#isHandlingPointerEvent */ default boolean isHandlingPointerEvent() { @@ -744,9 +749,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation final InsetsAnimationControlRunner runner = new InsetsResizeAnimationRunner( mFrame, mFromState, mToState, RESIZE_INTERPOLATOR, ANIMATION_DURATION_RESIZE, mTypes, InsetsController.this); - if (mRunningAnimations.isEmpty()) { - mHost.notifyAnimationRunningStateChanged(true); - } + mHost.notifyAnimationRunningStateChanged(true, + runner.getAnimationType(), mTypes); mRunningAnimations.add(new RunningAnimation(runner, runner.getAnimationType())); } }; @@ -1560,9 +1564,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } } ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_ANIMATION_RUNNING); - if (mRunningAnimations.isEmpty()) { - mHost.notifyAnimationRunningStateChanged(true); - } + mHost.notifyAnimationRunningStateChanged(true, animationType, types); mRunningAnimations.add(new RunningAnimation(runner, animationType)); if (DEBUG) Log.d(TAG, "Animation added to runner. useInsetsAnimationThread: " + useInsetsAnimationThread); @@ -1842,9 +1844,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation break; } } - if (mRunningAnimations.isEmpty()) { - mHost.notifyAnimationRunningStateChanged(false); - } + mHost.notifyAnimationRunningStateChanged( + false, control.getAnimationType(), removedTypes); onAnimationStateChanged(removedTypes, false /* running */); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index cd8a85a66c1a..7c5b300e9d24 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -24,6 +24,7 @@ import static android.graphics.HardwareRenderer.SYNC_CONTEXT_IS_STOPPED; import static android.graphics.HardwareRenderer.SYNC_LOST_SURFACE_REWARD_IF_FOUND; import static android.os.IInputConstants.INVALID_INPUT_EVENT_ID; import static android.os.Trace.TRACE_TAG_VIEW; +import static android.service.autofill.Flags.improveFillDialogAconfig; import static android.util.SequenceUtils.getInitSeq; import static android.util.SequenceUtils.isIncomingSeqStale; import static android.view.Display.DEFAULT_DISPLAY; @@ -922,6 +923,8 @@ public final class ViewRootImpl implements ViewParent, private boolean mInsetsAnimationRunning; + private int mInsetsAnimatingTypes = 0; + private long mPreviousFrameDrawnTime = -1; // The largest view size percentage to the display size. Used on trace to collect metric. private float mLargestChildPercentage = 0.0f; @@ -2520,17 +2523,49 @@ public final class ViewRootImpl implements ViewParent, * Notify the when the running state of a insets animation changed. */ @VisibleForTesting - public void notifyInsetsAnimationRunningStateChanged(boolean running) { + public void notifyInsetsAnimationRunningStateChanged(boolean running, + @InsetsController.AnimationType int animationType, + @InsetsType int insetsTypes) { + @InsetsType int previousInsetsType = mInsetsAnimatingTypes; + // If improveFillDialogAconfig is disabled, we notify WindowSession of all the updates we + // receive here + boolean notifyWindowSession = !improveFillDialogAconfig(); + if (running) { + mInsetsAnimatingTypes |= insetsTypes; + } else { + mInsetsAnimatingTypes &= ~insetsTypes; + } if (sToolkitSetFrameRateReadOnlyFlagValue) { - if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { - Trace.instant(Trace.TRACE_TAG_VIEW, - TextUtils.formatSimple("notifyInsetsAnimationRunningStateChanged(%s)", - Boolean.toString(running))); - } mInsetsAnimationRunning = running; - try { - mWindowSession.notifyInsetsAnimationRunningStateChanged(mWindow, running); - } catch (RemoteException e) { + // If improveFillDialogAconfig is enabled, we need to confirm other animations aren't + // running to maintain the existing behavior. System server were notified previously + // only when animation started running or stopped when there were no running animations. + if (improveFillDialogAconfig()) { + if ((previousInsetsType == 0 && mInsetsAnimatingTypes != 0) + || (previousInsetsType != 0 && mInsetsAnimatingTypes == 0)) { + notifyWindowSession = true; + } + } + if (notifyWindowSession) { + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.instant(Trace.TRACE_TAG_VIEW, + TextUtils.formatSimple("notifyInsetsAnimationRunningStateChanged(%s)", + Boolean.toString(running))); + } + try { + mWindowSession.notifyInsetsAnimationRunningStateChanged(mWindow, running); + } catch (RemoteException e) { + } + } + } + if (improveFillDialogAconfig()) { + // Update WindowManager for ImeAnimation + if ((insetsTypes & WindowInsets.Type.ime()) != 0) { + try { + WindowManagerGlobal.getWindowManagerService() + .notifyImeInsetsAnimationStateChanged(running, animationType); + } catch (RemoteException e) { + } } } } diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java index 889acca4b8b1..f1666dbebd7b 100644 --- a/core/java/android/view/ViewRootInsetsControllerHost.java +++ b/core/java/android/view/ViewRootInsetsControllerHost.java @@ -275,9 +275,12 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host { } @Override - public void notifyAnimationRunningStateChanged(boolean running) { + public void notifyAnimationRunningStateChanged(boolean running, + @InsetsController.AnimationType int animationType, + @WindowInsets.Type.InsetsType int insetsTypes) { if (mViewRoot != null) { - mViewRoot.notifyInsetsAnimationRunningStateChanged(running); + mViewRoot.notifyInsetsAnimationRunningStateChanged( + running, animationType, insetsTypes); } } diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java index c40137f1bd34..cef6970ba25a 100644 --- a/core/tests/coretests/src/android/view/ViewRootImplTest.java +++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java @@ -1054,7 +1054,8 @@ public class ViewRootImplTest { ViewRootImpl viewRootImpl = mView.getViewRootImpl(); sInstrumentation.runOnMainSync(() -> { mView.invalidate(); - viewRootImpl.notifyInsetsAnimationRunningStateChanged(true); + viewRootImpl.notifyInsetsAnimationRunningStateChanged(true, 0 /* animationType */, + 0 /* insetsTypes */ /* areOtherAnimationsRunning */); mView.invalidate(); }); sInstrumentation.waitForIdleSync(); diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java index c68e54956c99..d504d1e2ccb6 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java @@ -19,6 +19,7 @@ package com.android.server.autofill; import static android.Manifest.permission.MANAGE_AUTO_FILL; import static android.content.Context.AUTOFILL_MANAGER_SERVICE; import static android.service.autofill.Flags.fixGetAutofillComponent; +import static android.service.autofill.Flags.improveFillDialogAconfig; import static android.view.autofill.AutofillManager.MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS; import static android.view.autofill.AutofillManager.getSmartSuggestionModeToString; @@ -70,6 +71,7 @@ import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.TimeUtils; +import android.view.InsetsController; import android.view.autofill.AutofillFeatureFlags; import android.view.autofill.AutofillId; import android.view.autofill.AutofillManager; @@ -96,6 +98,7 @@ import com.android.server.autofill.ui.AutoFillUI; import com.android.server.infra.AbstractMasterSystemService; import com.android.server.infra.FrameworkResourcesServiceNameResolver; import com.android.server.infra.SecureSettingsServiceNameResolver; +import com.android.server.wm.WindowManagerInternal; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -301,6 +304,36 @@ public final class AutofillManagerService mCredentialAutofillService = null; Slog.w(TAG, "Invalid CredentialAutofillService"); } + + if (improveFillDialogAconfig()) { + WindowManagerInternal windowManagerInternal = LocalServices.getService( + WindowManagerInternal.class); + WindowManagerInternal.ImeInsetsAnimationChangeListener + imeInsetsAnimationChangeListener = + new WindowManagerInternal.ImeInsetsAnimationChangeListener() { + @Override + public void onAnimationStart( + @InsetsController.AnimationType int animationType, + int userId) { + // TODO: Add logic + if (sVerbose) { + Slog.e(TAG, "onAnimationStart()"); + } + } + + @Override + public void onAnimationEnd( + @InsetsController.AnimationType int animationType, + int userId) { + // TODO: Add logic + if (sVerbose) { + Slog.e(TAG, "onAnimationEnd()"); + } + } + }; + windowManagerInternal.setImeInsetsAnimationChangeListener( + imeInsetsAnimationChangeListener); + } } @Override // from AbstractMasterSystemService diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index 4bcba13448e9..f465c95addb7 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -899,7 +899,9 @@ class InsetsPolicy { } @Override - public void notifyAnimationRunningStateChanged(boolean running) { + public void notifyAnimationRunningStateChanged(boolean running, + @InsetsController.AnimationType int animationType, + @InsetsType int insetsTypes) { mInsetsAnimationRunning = running; } } diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index c77b1d9a7bcf..7a8230f1f963 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -41,6 +41,7 @@ import android.view.Display; import android.view.IInputFilter; import android.view.IRemoteAnimationFinishedCallback; import android.view.IWindow; +import android.view.InsetsController; import android.view.MagnificationSpec; import android.view.RemoteAnimationTarget; import android.view.Surface; @@ -469,6 +470,24 @@ public abstract class WindowManagerInternal { public abstract void getMagnificationRegion(int displayId, @NonNull Region magnificationRegion); /** + * Set by the autofill service to observe changes in the ime animations. + * + * @param listener The callbacks to invoke. + */ + public abstract void setImeInsetsAnimationChangeListener( + @Nullable ImeInsetsAnimationChangeListener listener); + + /** Listener for changes in ime insets animation */ + public interface ImeInsetsAnimationChangeListener { + + /** Notify on start of animation */ + void onAnimationStart(@InsetsController.AnimationType int animationType, int userId); + + /** Notify on end of animation */ + void onAnimationEnd(@InsetsController.AnimationType int animationType, int userId); + } + + /** * Sets a callback for observing which windows are touchable for the purposes * of accessibility on specified display. * diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5de0e9b6ed93..049d56d3ddc7 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.service.autofill.Flags.improveFillDialogAconfig; import static android.Manifest.permission.ACCESS_SURFACE_FLINGER; import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS; import static android.Manifest.permission.INPUT_CONSUMER; @@ -277,6 +278,7 @@ import android.view.InputApplicationHandle; import android.view.InputChannel; import android.view.InputDevice; import android.view.InputWindowHandle; +import android.view.InsetsController; import android.view.InsetsFrameProvider; import android.view.InsetsSourceControl; import android.view.InsetsState; @@ -792,6 +794,9 @@ public class WindowManagerService extends IWindowManager.Stub final TrustedPresentationListenerController mTrustedPresentationListenerController = new TrustedPresentationListenerController(); + private WindowManagerInternal.ImeInsetsAnimationChangeListener + mImeInsetsAnimationChangeListener; + @VisibleForTesting final class SettingsObserver extends ContentObserver { private final Uri mDisplayInversionEnabledUri = @@ -8602,6 +8607,14 @@ public class WindowManagerService extends IWindowManager.Stub // WMS.takeAssistScreenshot takes care of the locking. return WindowManagerService.this.takeAssistScreenshot(windowTypesToExclude); } + + @Override + public void setImeInsetsAnimationChangeListener( + @Nullable WindowManagerInternal.ImeInsetsAnimationChangeListener listener) { + synchronized (mGlobalLock) { + mImeInsetsAnimationChangeListener = listener; + } + } } private final class ImeTargetVisibilityPolicyImpl extends ImeTargetVisibilityPolicy { @@ -10159,6 +10172,24 @@ public class WindowManagerService extends IWindowManager.Stub } } + @Override + public void notifyImeInsetsAnimationStateChanged( + boolean running, @InsetsController.AnimationType int animationType) { + if (improveFillDialogAconfig()) { + synchronized (mGlobalLock) { + if (mImeInsetsAnimationChangeListener == null) { + return; + } + if (running) { + mImeInsetsAnimationChangeListener.onAnimationStart( + animationType, mCurrentUserId); + } else { + mImeInsetsAnimationChangeListener.onAnimationEnd(animationType, mCurrentUserId); + } + } + } + } + boolean getDisableSecureWindows() { return mDisableSecureWindows; } |