Merge "Fixed the memory leak when receiving Nav messages" into nyc-mr1-dev
diff --git a/libs/hwui/PropertyValuesAnimatorSet.cpp b/libs/hwui/PropertyValuesAnimatorSet.cpp
index 38fb70a..e3258e3 100644
--- a/libs/hwui/PropertyValuesAnimatorSet.cpp
+++ b/libs/hwui/PropertyValuesAnimatorSet.cpp
@@ -46,8 +46,17 @@
void PropertyValuesAnimatorSet::onFinished(BaseRenderNodeAnimator* animator) {
if (mOneShotListener.get()) {
- mOneShotListener->onAnimationFinished(animator);
+ sp<AnimationListener> listener = std::move(mOneShotListener);
+ // Set the listener to nullptr before the onAnimationFinished callback, rather than after,
+ // for two reasons:
+ // 1) We need to prevent changes to mOneShotListener during the onAnimationFinished
+ // callback (specifically in AnimationListenerBridge::onAnimationFinished(...) from
+ // triggering dtor of the bridge and potentially unsafely re-entering
+ // AnimationListenerBridge::onAnimationFinished(...).
+ // 2) It's possible that there are changes to the listener during the callback, therefore
+ // we need to reset the listener before the callback rather than afterwards.
mOneShotListener = nullptr;
+ listener->onAnimationFinished(animator);
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 3ec3cea..b8f7d1f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -140,6 +140,7 @@
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.policy.PhoneWindow;
import com.android.internal.policy.IShortcutService;
@@ -590,6 +591,13 @@
private static final int DISMISS_KEYGUARD_CONTINUE = 2; // Keyguard has been dismissed.
int mDismissKeyguard = DISMISS_KEYGUARD_NONE;
+ /**
+ * Indicates that we asked the Keyguard to be dismissed and we just wait for the Keyguard to
+ * dismiss itself.
+ */
+ @GuardedBy("Lw")
+ private boolean mCurrentlyDismissingKeyguard;
+
/** The window that is currently dismissing the keyguard. Dismissing the keyguard must only
* be done once per window. */
private WindowState mWinDismissingKeyguard;
@@ -3590,10 +3598,11 @@
@Override
public boolean canShowDismissingWindowWhileLockedLw() {
- // If the keyguard is trusted, it will unlock without a challange. Therefore, windows with
- // FLAG_DISMISS_KEYGUARD don't need to be force hidden, as they will unlock the phone right
- // away anyways.
- return mKeyguardDelegate != null && mKeyguardDelegate.isTrusted();
+ // If the keyguard is trusted, it will unlock without a challenge. Therefore, if we are in
+ // the process of dismissing Keyguard, we don't need to hide them as the phone will be
+ // unlocked right away in any case.
+ return mKeyguardDelegate != null && mKeyguardDelegate.isTrusted()
+ && mCurrentlyDismissingKeyguard;
}
private void launchAssistLongPressAction() {
@@ -5300,22 +5309,27 @@
}
} else if (mDismissKeyguard != DISMISS_KEYGUARD_NONE) {
mKeyguardHidden = false;
- final boolean trusted = mKeyguardDelegate.isTrusted();
- if (trusted) {
- // No need to un-occlude keyguard - we'll dimiss it right away anyways.
- } else if (setKeyguardOccludedLw(false)) {
- changes |= FINISH_LAYOUT_REDO_LAYOUT
- | FINISH_LAYOUT_REDO_CONFIG
- | FINISH_LAYOUT_REDO_WALLPAPER;
- }
+ boolean willDismiss = false;
if (mDismissKeyguard == DISMISS_KEYGUARD_START) {
+ final boolean trusted = mKeyguardDelegate.isTrusted();
+ willDismiss = trusted && mKeyguardOccluded && mKeyguardDelegate != null
+ && mKeyguardDelegate.isShowing();
+ if (willDismiss) {
+ mCurrentlyDismissingKeyguard = true;
+ }
+
// Only launch the next keyguard unlock window once per window.
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mKeyguardDelegate.dismiss(trusted /* allowWhileOccluded */);
- }
- });
+ mHandler.post(() -> mKeyguardDelegate.dismiss(
+ trusted /* allowWhileOccluded */));
+ }
+
+ // If we are currently dismissing Keyguard, there is no need to unocclude it.
+ if (!mCurrentlyDismissingKeyguard) {
+ if (setKeyguardOccludedLw(false)) {
+ changes |= FINISH_LAYOUT_REDO_LAYOUT
+ | FINISH_LAYOUT_REDO_CONFIG
+ | FINISH_LAYOUT_REDO_WALLPAPER;
+ }
}
} else {
mWinDismissingKeyguard = null;
@@ -5370,6 +5384,14 @@
}
}
+ private void onKeyguardShowingStateChanged(boolean showing) {
+ if (!showing) {
+ synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
+ mCurrentlyDismissingKeyguard = false;
+ }
+ }
+ }
+
private boolean isStatusBarKeyguard() {
return mStatusBar != null
&& (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
@@ -6908,7 +6930,8 @@
/** {@inheritDoc} */
@Override
public void systemReady() {
- mKeyguardDelegate = new KeyguardServiceDelegate(mContext);
+ mKeyguardDelegate = new KeyguardServiceDelegate(mContext,
+ this::onKeyguardShowingStateChanged);
mKeyguardDelegate.onSystemReady();
readCameraLensCoverState();
@@ -7989,6 +8012,7 @@
pw.print(" mForceStatusBarFromKeyguard=");
pw.println(mForceStatusBarFromKeyguard);
pw.print(prefix); pw.print("mDismissKeyguard="); pw.print(mDismissKeyguard);
+ pw.print(" mCurrentlyDismissingKeyguard="); pw.println(mCurrentlyDismissingKeyguard);
pw.print(" mWinDismissingKeyguard="); pw.print(mWinDismissingKeyguard);
pw.print(" mHomePressed="); pw.println(mHomePressed);
pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn);
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 2af4c9b..29a1f07 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -23,6 +23,7 @@
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardService;
import com.android.server.UiThread;
+import com.android.server.policy.keyguard.KeyguardStateMonitor.OnShowingStateChangedCallback;
import java.io.PrintWriter;
@@ -49,6 +50,7 @@
private final Handler mScrimHandler;
private final KeyguardState mKeyguardState = new KeyguardState();
private DrawnListener mDrawnListenerWhenConnect;
+ private final OnShowingStateChangedCallback mShowingStateChangedCallback;
private static final class KeyguardState {
KeyguardState() {
@@ -116,9 +118,11 @@
}
};
- public KeyguardServiceDelegate(Context context) {
+ public KeyguardServiceDelegate(Context context,
+ OnShowingStateChangedCallback showingStateChangedCallback) {
mContext = context;
mScrimHandler = UiThread.getHandler();
+ mShowingStateChangedCallback = showingStateChangedCallback;
mScrim = createScrim(context, mScrimHandler);
}
@@ -154,7 +158,7 @@
public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)");
mKeyguardService = new KeyguardServiceWrapper(mContext,
- IKeyguardService.Stub.asInterface(service));
+ IKeyguardService.Stub.asInterface(service), mShowingStateChangedCallback);
if (mKeyguardState.systemIsReady) {
// If the system is ready, it means keyguard crashed and restarted.
mKeyguardService.onSystemReady();
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
index 2169927..de906e6 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
@@ -26,6 +26,7 @@
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardService;
import com.android.internal.policy.IKeyguardStateCallback;
+import com.android.server.policy.keyguard.KeyguardStateMonitor.OnShowingStateChangedCallback;
import java.io.PrintWriter;
@@ -39,9 +40,11 @@
private IKeyguardService mService;
private String TAG = "KeyguardServiceWrapper";
- public KeyguardServiceWrapper(Context context, IKeyguardService service) {
+ public KeyguardServiceWrapper(Context context, IKeyguardService service,
+ OnShowingStateChangedCallback showingStateChangedCallback) {
mService = service;
- mKeyguardStateMonitor = new KeyguardStateMonitor(context, service);
+ mKeyguardStateMonitor = new KeyguardStateMonitor(context, service,
+ showingStateChangedCallback);
}
@Override // Binder interface
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index 08eaaa9..712b625 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -49,10 +49,13 @@
private int mCurrentUserId;
private final LockPatternUtils mLockPatternUtils;
+ private final OnShowingStateChangedCallback mOnShowingStateChangedCallback;
- public KeyguardStateMonitor(Context context, IKeyguardService service) {
+ public KeyguardStateMonitor(Context context, IKeyguardService service,
+ OnShowingStateChangedCallback showingStateChangedCallback) {
mLockPatternUtils = new LockPatternUtils(context);
mCurrentUserId = ActivityManager.getCurrentUser();
+ mOnShowingStateChangedCallback = showingStateChangedCallback;
try {
service.addStateMonitorCallback(this);
} catch (RemoteException e) {
@@ -83,6 +86,7 @@
@Override // Binder interface
public void onShowingStateChanged(boolean showing) {
mIsShowing = showing;
+ mOnShowingStateChangedCallback.onShowingStateChanged(showing);
}
@Override // Binder interface
@@ -122,4 +126,8 @@
pw.println(prefix + "mTrusted=" + mTrusted);
pw.println(prefix + "mCurrentUserId=" + mCurrentUserId);
}
+
+ public interface OnShowingStateChangedCallback {
+ void onShowingStateChanged(boolean showing);
+ }
}
\ No newline at end of file