summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author wilsonshih <wilsonshih@google.com> 2018-08-20 10:36:25 +0800
committer wilsonshih <wilsonshih@google.com> 2018-08-22 09:43:55 +0800
commit0042e4516ffcea66cb209d8c2dad7aeaa53b50fb (patch)
treeeca184b0eabb5bbf9fa76a233032a3fd6ba186aa
parenta2e28a4b86409415e84d36fcc072e6c3c2f0e561 (diff)
Prevent ViewRootImpl.mDisplay become null.
For some timing cases client side may not get desired display with old displayId. For this issue, client side has just received configuration change and handle it in ActivityThread#handleActivityConfigurationChanged. At the same time, DisplayManagerService was about to destory display. When ViewRootImpl want to update display with new DisplayAdjustments, it got null because the old displayId was removed. For this scenario, fallback to use default display. Usually there should be other displayId change event comes from server side to ask client update. Change-Id: Ifb843f82b753761cb6306e7482b38a0ffd89498d Fix: 73558361 Test: atest CtsWindowManagerDeviceTestCases Test: atest CtsActivityManagerDeviceTestCases
-rw-r--r--core/java/android/view/ViewRootImpl.java25
1 files changed, 21 insertions, 4 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 23fc4d5045a9..1351f6f1ef26 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -16,6 +16,7 @@
package android.view;
+import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.View.PFLAG_DRAW_ANIMATION;
import static android.view.WindowCallbacks.RESIZE_MODE_DOCKED_DIVIDER;
@@ -1212,13 +1213,30 @@ public final class ViewRootImpl implements ViewParent,
// Get new instance of display based on current display adjustments. It may be updated later
// if moving between the displays also involved a configuration change.
- mDisplay = ResourcesManager.getInstance().getAdjustedDisplay(displayId,
- mView.getResources());
+ updateInternalDisplay(displayId, mView.getResources());
mAttachInfo.mDisplayState = mDisplay.getState();
// Internal state updated, now notify the view hierarchy.
mView.dispatchMovedToDisplay(mDisplay, config);
}
+ /**
+ * Updates {@link #mDisplay} to the display object corresponding to {@param displayId}.
+ * Uses DEFAULT_DISPLAY if there isn't a display object in the system corresponding
+ * to {@param displayId}.
+ */
+ private void updateInternalDisplay(int displayId, Resources resources) {
+ final Display preferredDisplay =
+ ResourcesManager.getInstance().getAdjustedDisplay(displayId, resources);
+ if (preferredDisplay == null) {
+ // Fallback to use default display.
+ Slog.w(TAG, "Cannot get desired display with Id: " + displayId);
+ mDisplay = ResourcesManager.getInstance()
+ .getAdjustedDisplay(DEFAULT_DISPLAY, resources);
+ } else {
+ mDisplay = preferredDisplay;
+ }
+ }
+
void pokeDrawLockIfNeeded() {
final int displayState = mAttachInfo.mDisplayState;
if (mView != null && mAdded && mTraversalScheduled
@@ -3944,8 +3962,7 @@ public final class ViewRootImpl implements ViewParent,
// Handle configuration change.
if (mForceNextConfigUpdate || mLastConfigurationFromResources.diff(config) != 0) {
// Update the display with new DisplayAdjustments.
- mDisplay = ResourcesManager.getInstance().getAdjustedDisplay(
- mDisplay.getDisplayId(), localResources);
+ updateInternalDisplay(mDisplay.getDisplayId(), localResources);
final int lastLayoutDirection = mLastConfigurationFromResources.getLayoutDirection();
final int currentLayoutDirection = config.getLayoutDirection();