Fix SysUI when an app started from the affordances crashes
- Fix infinite recursion in this case.
- If the app crashes, we are waiting for either setOccluded or
hideKeyguard to be called. However, neither of these gets called
in this case, so we recover from it by adding a timeout of 5
seconds.
Bug: 18652789
Change-Id: Ib9a043f5692a8578703df1db08e1a6b9dcfbc742
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 08844f31..d2dc425 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1629,6 +1629,7 @@
} else {
mSecureCameraLaunchManager.startSecureCameraLaunch();
}
+ mStatusBar.startLaunchTransitionTimeout();
mBlockTouches = true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index ec2d30c..8b328aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -203,8 +203,12 @@
private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
private static final int MSG_CLOSE_PANELS = 1001;
private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
+ private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
// 1020-1040 reserved for BaseStatusBar
+ // Time after we abort the launch transition.
+ private static final long LAUNCH_TRANSITION_TIMEOUT_MS = 5000;
+
private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
@@ -2196,6 +2200,9 @@
escalateHeadsUp();
setHeadsUpVisibility(false);
break;
+ case MSG_LAUNCH_TRANSITION_TIMEOUT:
+ onLaunchTransitionTimeout();
+ break;
}
}
}
@@ -3528,12 +3535,10 @@
if (mLaunchTransitionFadingAway) {
mNotificationPanel.animate().cancel();
mNotificationPanel.setAlpha(1f);
- if (mLaunchTransitionEndRunnable != null) {
- mLaunchTransitionEndRunnable.run();
- }
- mLaunchTransitionEndRunnable = null;
+ runLaunchTransitionEndRunnable();
mLaunchTransitionFadingAway = false;
}
+ mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
setBarState(StatusBarState.KEYGUARD);
updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
if (!mScreenOnFromKeyguard) {
@@ -3574,6 +3579,7 @@
*/
public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
Runnable endRunnable) {
+ mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
mLaunchTransitionEndRunnable = endRunnable;
Runnable hideRunnable = new Runnable() {
@Override
@@ -3592,10 +3598,7 @@
@Override
public void run() {
mNotificationPanel.setAlpha(1);
- if (mLaunchTransitionEndRunnable != null) {
- mLaunchTransitionEndRunnable.run();
- }
- mLaunchTransitionEndRunnable = null;
+ runLaunchTransitionEndRunnable();
mLaunchTransitionFadingAway = false;
}
});
@@ -3609,6 +3612,32 @@
}
/**
+ * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
+ * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
+ * because the launched app crashed or something else went wrong.
+ */
+ public void startLaunchTransitionTimeout() {
+ mHandler.sendEmptyMessageDelayed(MSG_LAUNCH_TRANSITION_TIMEOUT,
+ LAUNCH_TRANSITION_TIMEOUT_MS);
+ }
+
+ private void onLaunchTransitionTimeout() {
+ Log.w(TAG, "Launch transition: Timeout!");
+ mNotificationPanel.resetViews();
+ }
+
+ private void runLaunchTransitionEndRunnable() {
+ if (mLaunchTransitionEndRunnable != null) {
+ Runnable r = mLaunchTransitionEndRunnable;
+
+ // mLaunchTransitionEndRunnable might call showKeyguard, which would execute it again,
+ // which would lead to infinite recursion. Protect against it.
+ mLaunchTransitionEndRunnable = null;
+ r.run();
+ }
+ }
+
+ /**
* @return true if we would like to stay in the shade, false if it should go away entirely
*/
public boolean hideKeyguard() {
@@ -3631,6 +3660,7 @@
if (mQSPanel != null) {
mQSPanel.refreshAllTiles();
}
+ mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
return staying;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 77da70a..f4edab5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -199,7 +199,7 @@
new Runnable() {
@Override
public void run() {
- mStatusBarWindowManager.setKeyguardOccluded(true);
+ mStatusBarWindowManager.setKeyguardOccluded(mOccluded);
reset();
}
});