diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-09-01 02:15:29 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-09-01 02:15:29 +0000 |
commit | 1826f52f12876eb2fe90c0f59b4dd8745137d46e (patch) | |
tree | f8507d803b11cdda47c908c64f0ab79aa3fdbe0f | |
parent | e9d071e8333db88a8f81b0fcd21f5f18a3ae8222 (diff) | |
parent | 987179a2f16839f7e850c7063ddb6b77cf9d77bf (diff) | |
download | base-1826f52f12876eb2fe90c0f59b4dd8745137d46e.tar.gz |
Merge cherrypicks of [15732630, 15732754, 15732755, 15732756, 15732757, 15733137, 15733138, 15732858, 15733570, 15733571, 15733572, 15733573, 15733574, 15732859, 15733575, 15733576, 15733685, 15733686] into sc-d1-release
Change-Id: Id632c9017517e2f36dd6be234269658f83f095a3
13 files changed, 138 insertions, 73 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 12b1df44b6f5..fc4bb1a00da5 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -464,11 +464,7 @@ public final class ActivityThread extends ClientTransactionHandler @Override public int hashCode() { - return hashCode(authority, userId); - } - - public static int hashCode(final String auth, final int userIdent) { - return ((auth != null) ? auth.hashCode() : 0) ^ userIdent; + return ((authority != null) ? authority.hashCode() : 0) ^ userId; } } @@ -490,7 +486,7 @@ public final class ActivityThread extends ClientTransactionHandler // Note we never removes items from this map but that's okay because there are only so many // users and so many authorities. @GuardedBy("mGetProviderKeys") - final SparseArray<ProviderKey> mGetProviderKeys = new SparseArray<>(); + final ArrayMap<ProviderKey, ProviderKey> mGetProviderKeys = new ArrayMap<>(); final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>(); @@ -7016,11 +7012,11 @@ public final class ActivityThread extends ClientTransactionHandler } private ProviderKey getGetProviderKey(String auth, int userId) { - final int key = ProviderKey.hashCode(auth, userId); + final ProviderKey key = new ProviderKey(auth, userId); synchronized (mGetProviderKeys) { ProviderKey lock = mGetProviderKeys.get(key); if (lock == null) { - lock = new ProviderKey(auth, userId); + lock = key; mGetProviderKeys.put(key, lock); } return lock; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java index d46426a03621..9015396d26ab 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java @@ -155,6 +155,13 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { updateAlpha(); } + /** + * @return alpha between 0 and 255 + */ + int getUnpausedAlpha() { + return mAlpha; + } + @Override protected int updateAlpha() { int alpha = super.updateAlpha(); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java index 3ca7a9face95..22d7a3ff44f0 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java @@ -153,7 +153,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud pw.println("mIsBouncerVisible=" + mIsBouncerVisible); pw.println("mInputBouncerHiddenAmount=" + mInputBouncerHiddenAmount); pw.println("mStatusBarExpansion=" + mStatusBarExpansion); - pw.println("mAlpha=" + mView.getAlpha()); + pw.println("unpausedAlpha=" + mView.getUnpausedAlpha()); pw.println("mUdfpsRequested=" + mUdfpsRequested); pw.println("mView.mUdfpsRequested=" + mView.mUdfpsRequested); pw.println("mLaunchTransitionFadingAway=" + mLaunchTransitionFadingAway); @@ -168,10 +168,10 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud return false; } + boolean udfpsAffordanceWasNotShowing = shouldPauseAuth(); mShowingUdfpsBouncer = show; - updatePauseAuth(); if (mShowingUdfpsBouncer) { - if (mStatusBarState == StatusBarState.SHADE_LOCKED) { + if (udfpsAffordanceWasNotShowing) { mView.animateInUdfpsBouncer(null); } @@ -184,6 +184,8 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud } else { mKeyguardUpdateMonitor.requestFaceAuthOnOccludingApp(false); } + updateAlpha(); + updatePauseAuth(); return true; } @@ -308,6 +310,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud public void requestUdfps(boolean request, int color) { mUdfpsRequested = request; mView.requestUdfps(request, color); + updateAlpha(); updatePauseAuth(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java index 47e060ef8f97..5eb913856187 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java @@ -313,6 +313,25 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase { verify(mView).setUnpausedAlpha(0); } + @Test + public void testShowUdfpsBouncer() { + // GIVEN view is attached and status bar expansion is 0 + mController.onViewAttached(); + captureExpansionListeners(); + captureKeyguardStateControllerCallback(); + captureAltAuthInterceptor(); + updateStatusBarExpansion(0, true); + reset(mView); + when(mView.getContext()).thenReturn(mResourceContext); + when(mResourceContext.getString(anyInt())).thenReturn("test string"); + + // WHEN status bar expansion is 0 but udfps bouncer is requested + mAltAuthInterceptor.showAlternateAuthBouncer(); + + // THEN alpha is 0 + verify(mView).setUnpausedAlpha(255); + } + private void sendStatusBarStateChanged(int statusBarState) { mStatusBarStateListener.onStateChanged(statusBarState); } diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java index 6af192371e3d..147050cd271f 100644 --- a/services/core/java/com/android/server/display/DisplayPowerState.java +++ b/services/core/java/com/android/server/display/DisplayPowerState.java @@ -411,7 +411,7 @@ final class DisplayPowerState { * Updates the state of the screen and backlight asynchronously on a separate thread. */ private final class PhotonicModulator extends Thread { - private static final int INITIAL_SCREEN_STATE = Display.STATE_OFF; // unknown, assume off + private static final int INITIAL_SCREEN_STATE = Display.STATE_UNKNOWN; private static final float INITIAL_BACKLIGHT_FLOAT = PowerManager.BRIGHTNESS_INVALID_FLOAT; private final Object mLock = new Object(); @@ -494,7 +494,9 @@ final class DisplayPowerState { if (!backlightChanged) { mBacklightChangeInProgress = false; } - if (!stateChanged && !backlightChanged) { + boolean valid = state != Display.STATE_UNKNOWN && !Float.isNaN(brightnessState); + boolean changed = stateChanged || backlightChanged; + if (!valid || !changed) { try { mLock.wait(); } catch (InterruptedException ex) { diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index dc955337fdbc..3e52f5e07e62 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -2582,14 +2582,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } if (mCurToken != null) { - try { - if (DEBUG) { - Slog.v(TAG, "Removing window token: " + mCurToken + " for display: " - + mCurTokenDisplayId); - } - mIWindowManager.removeWindowToken(mCurToken, mCurTokenDisplayId); - } catch (RemoteException e) { + if (DEBUG) { + Slog.v(TAG, "Removing window token: " + mCurToken + " for display: " + + mCurTokenDisplayId); } + mWindowManagerInternal.removeWindowToken(mCurToken, false /* removeWindows */, + false /* animateExit */, mCurTokenDisplayId); // Set IME window status as invisible when unbind current method. mImeWindowVis = 0; mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT; diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index dbc1116ad389..6892dbc158d4 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1165,10 +1165,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } } - WindowToken removeWindowToken(IBinder binder) { + WindowToken removeWindowToken(IBinder binder, boolean animateExit) { final WindowToken token = mTokenMap.remove(binder); if (token != null && token.asActivityRecord() == null) { - token.setExiting(); + token.setExiting(animateExit); } return token; } @@ -1252,7 +1252,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } void removeAppToken(IBinder binder) { - final WindowToken token = removeWindowToken(binder); + final WindowToken token = removeWindowToken(binder, true /* animateExit */); if (token == null) { Slog.w(TAG_WM, "removeAppToken: Attempted to remove non-existing token: " + binder); return; diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java index 194f48f57cc4..b54e8b7a7b4e 100644 --- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java +++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java @@ -66,8 +66,8 @@ class WallpaperWindowToken extends WindowToken { } @Override - void setExiting() { - super.setExiting(); + void setExiting(boolean animateExit) { + super.setExiting(animateExit); mDisplayContent.mWallpaperController.removeWallpaperToken(this); } diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index 47087cfbd147..4fac05c349c5 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -445,8 +445,21 @@ public abstract class WindowManagerInternal { * @param removeWindows Whether to also remove the windows associated with the token. * @param displayId The display to remove the token from. */ + public final void removeWindowToken(android.os.IBinder token, boolean removeWindows, + int displayId) { + removeWindowToken(token, removeWindows, true /* animateExit */, displayId); + } + + /** + * Removes a window token. + * + * @param token The toke to remove. + * @param removeWindows Whether to also remove the windows associated with the token. + * @param animateExit Whether to play the windows exit animation after the token removal. + * @param displayId The display to remove the token from. + */ public abstract void removeWindowToken(android.os.IBinder token, boolean removeWindows, - int displayId); + boolean animateExit, int displayId); /** * Registers a listener to be notified about app transition events. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 1ec9187d7a76..9caef70f6b51 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2816,6 +2816,31 @@ public class WindowManagerService extends IWindowManager.Stub } + void removeWindowToken(IBinder binder, boolean removeWindows, boolean animateExit, + int displayId) { + synchronized (mGlobalLock) { + final DisplayContent dc = mRoot.getDisplayContent(displayId); + + if (dc == null) { + ProtoLog.w(WM_ERROR, "removeWindowToken: Attempted to remove token: %s" + + " for non-exiting displayId=%d", binder, displayId); + return; + } + final WindowToken token = dc.removeWindowToken(binder, animateExit); + if (token == null) { + ProtoLog.w(WM_ERROR, + "removeWindowToken: Attempted to remove non-existing token: %s", + binder); + return; + } + + if (removeWindows) { + token.removeAllWindowsIfPossible(); + } + dc.getInputMonitor().updateInputWindowsLw(true /* force */); + } + } + @Override public void removeWindowToken(IBinder binder, int displayId) { if (!checkCallingPermission(MANAGE_APP_TOKENS, "removeWindowToken()")) { @@ -2823,23 +2848,7 @@ public class WindowManagerService extends IWindowManager.Stub } final long origId = Binder.clearCallingIdentity(); try { - synchronized (mGlobalLock) { - final DisplayContent dc = mRoot.getDisplayContent(displayId); - - if (dc == null) { - ProtoLog.w(WM_ERROR, "removeWindowToken: Attempted to remove token: %s" - + " for non-exiting displayId=%d", binder, displayId); - return; - } - final WindowToken token = dc.removeWindowToken(binder); - if (token == null) { - ProtoLog.w(WM_ERROR, - "removeWindowToken: Attempted to remove non-existing token: %s", - binder); - return; - } - dc.getInputMonitor().updateInputWindowsLw(true /*force*/); - } + removeWindowToken(binder, false /* removeWindows */, true /* animateExit */, displayId); } finally { Binder.restoreCallingIdentity(origId); } @@ -7536,28 +7545,10 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public void removeWindowToken(IBinder binder, boolean removeWindows, int displayId) { - synchronized (mGlobalLock) { - if (removeWindows) { - final DisplayContent dc = mRoot.getDisplayContent(displayId); - if (dc == null) { - ProtoLog.w(WM_ERROR, "removeWindowToken: Attempted to remove token: %s" - + " for non-exiting displayId=%d", binder, displayId); - return; - } - - final WindowToken token = dc.removeWindowToken(binder); - if (token == null) { - ProtoLog.w(WM_ERROR, - "removeWindowToken: Attempted to remove non-existing token: %s", - binder); - return; - } - - token.removeAllWindowsIfPossible(); - } - WindowManagerService.this.removeWindowToken(binder, displayId); - } + public void removeWindowToken(IBinder binder, boolean removeWindows, boolean animateExit, + int displayId) { + WindowManagerService.this.removeWindowToken(binder, removeWindows, animateExit, + displayId); } @Override diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index c3fc99554bcc..5e042efa2f11 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2180,11 +2180,18 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } - boolean onSetAppExiting() { + boolean onSetAppExiting(boolean animateExit) { final DisplayContent displayContent = getDisplayContent(); boolean changed = false; - if (isVisibleNow()) { + if (!animateExit) { + // Hide the window permanently if no window exist animation is performed, so we can + // avoid the window surface becoming visible again unexpectedly during the next + // relayout. + mPermanentlyHidden = true; + hide(false /* doAnimation */, false /* requestAnim */); + } + if (isVisibleNow() && animateExit) { mWinAnimator.applyAnimationLocked(TRANSIT_EXIT, false); if (mWmService.mAccessibilityController != null) { mWmService.mAccessibilityController.onWindowTransition(this, TRANSIT_EXIT); @@ -2197,7 +2204,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowState c = mChildren.get(i); - changed |= c.onSetAppExiting(); + changed |= c.onSetAppExiting(animateExit); } return changed; diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index fbfa400ba852..3cbc67c004cd 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -24,6 +24,7 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_MOVEMENT; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; @@ -232,7 +233,7 @@ class WindowToken extends WindowContainer<WindowState> { } } - void setExiting() { + void setExiting(boolean animateExit) { if (isEmpty()) { super.removeImmediately(); return; @@ -247,11 +248,12 @@ class WindowToken extends WindowContainer<WindowState> { final int count = mChildren.size(); boolean changed = false; - final boolean delayed = isAnimating(TRANSITION | PARENTS | CHILDREN); + final boolean delayed = isAnimating(TRANSITION | PARENTS) + || (isAnimating(CHILDREN, ANIMATION_TYPE_WINDOW_ANIMATION) && animateExit); for (int i = 0; i < count; i++) { final WindowState win = mChildren.get(i); - changed |= win.onSetAppExiting(); + changed |= win.onSetAppExiting(animateExit); } final ActivityRecord app = asActivityRecord(); @@ -353,7 +355,7 @@ class WindowToken extends WindowContainer<WindowState> { @Override void removeImmediately() { if (mDisplayContent != null) { - mDisplayContent.removeWindowToken(token); + mDisplayContent.removeWindowToken(token, true /* animateExit */); } // Needs to occur after the token is removed from the display above to avoid attempt at // duplicate removal of this window container from it's parent. diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java index d048f1842aa3..589f9134f227 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java @@ -24,6 +24,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; +import static com.android.server.policy.WindowManagerPolicy.TRANSIT_EXIT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -44,6 +45,7 @@ import androidx.test.filters.SmallTest; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import java.util.function.BiFunction; @@ -126,7 +128,7 @@ public class WindowTokenTests extends WindowTestsBase { final WindowState window1 = createWindow(null, TYPE_TOAST, token, "window1"); final WindowState window2 = createWindow(null, TYPE_TOAST, token, "window2"); - mDisplayContent.removeWindowToken(token.token); + mDisplayContent.removeWindowToken(token.token, true /* animateExit */); // Verify that the token is no longer mapped on the display assertNull(mDisplayContent.getWindowToken(token.token)); // Verify that the token is still attached to its parent @@ -261,4 +263,29 @@ public class WindowTokenTests extends WindowTestsBase { assertNotNull(app.getFrozenInsetsState()); assertNull(mDisplayContent.mInputMethodWindow.getFrozenInsetsState()); } + + @Test + public void testRemoveWindowToken_noAnimateExitWhenSet() { + final TestWindowToken token = createTestWindowToken(0, mDisplayContent); + final WindowState win = createWindow(null, TYPE_APPLICATION, token, "win"); + makeWindowVisible(win); + assertTrue(win.isOnScreen()); + spyOn(win); + spyOn(win.mWinAnimator); + spyOn(win.mToken); + + // Invoking removeWindowToken with setting no window exit animation and not remove window + // immediately. verify the window will hide without applying exit animation. + mWm.removeWindowToken(win.mToken.token, false /* removeWindows */, false /* animateExit */, + mDisplayContent.mDisplayId); + verify(win).onSetAppExiting(Mockito.eq(false) /* animateExit */); + verify(win).hide(false /* doAnimation */, false /* requestAnim */); + assertFalse(win.isOnScreen()); + verify(win.mWinAnimator, Mockito.never()).applyAnimationLocked(TRANSIT_EXIT, false); + assertTrue(win.mToken.hasChild()); + + // Even though the window is being removed afterwards, it won't apply exit animation. + win.removeIfPossible(); + verify(win.mWinAnimator, Mockito.never()).applyAnimationLocked(TRANSIT_EXIT, false); + } } |