From e5c58eefb1c28d56e6b4768cf624af137a867d21 Mon Sep 17 00:00:00 2001 From: Andrii Kulian Date: Mon, 27 Mar 2017 19:25:24 -0700 Subject: [PATCH] Add Configuration param to onMovedToDisplay To be consistent with other multi-window callbacks adding Configuration param to the onMovedToDisplay, so that app developer can handle configuration change at the same time when it receives a notification about move. Bug: 36649499 Test: android.server.ActivityManagerDisplayTests Test: #testOnMovedToDisplayCallback Change-Id: I80c765473bfc09ea1fb7aa4e2e77baf3b21606b8 (cherry picked from commit 2c32a11a71e2a1602b188b710b1916d919d99edb) --- api/current.txt | 4 +-- api/system-current.txt | 4 +-- api/test-current.txt | 4 +-- core/java/android/app/Activity.java | 17 ++++++++----- core/java/android/app/ActivityThread.java | 42 ++++++++++++++++++------------- core/java/android/view/View.java | 17 ++++++++----- core/java/android/view/ViewGroup.java | 6 ++--- core/java/android/view/ViewRootImpl.java | 27 ++++++++++++++------ 8 files changed, 74 insertions(+), 47 deletions(-) diff --git a/api/current.txt b/api/current.txt index 8d2790568f9b..0a3d23008945 100644 --- a/api/current.txt +++ b/api/current.txt @@ -3673,7 +3673,7 @@ package android.app { method public void onLowMemory(); method public boolean onMenuItemSelected(int, android.view.MenuItem); method public boolean onMenuOpened(int, android.view.Menu); - method public void onMovedToDisplay(int); + method public void onMovedToDisplay(int, android.content.res.Configuration); method public void onMultiWindowModeChanged(boolean); method public boolean onNavigateUp(); method public boolean onNavigateUpFromChild(android.app.Activity); @@ -45488,7 +45488,7 @@ package android.view { method public boolean onKeyUp(int, android.view.KeyEvent); method protected void onLayout(boolean, int, int, int, int); method protected void onMeasure(int, int); - method public void onMovedToDisplay(int); + method public void onMovedToDisplay(int, android.content.res.Configuration); method protected void onOverScrolled(int, int, boolean, boolean); method public void onPointerCaptureChange(boolean); method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent); diff --git a/api/system-current.txt b/api/system-current.txt index badd31e3583a..511667f07596 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -3799,7 +3799,7 @@ package android.app { method public void onLowMemory(); method public boolean onMenuItemSelected(int, android.view.MenuItem); method public boolean onMenuOpened(int, android.view.Menu); - method public void onMovedToDisplay(int); + method public void onMovedToDisplay(int, android.content.res.Configuration); method public void onMultiWindowModeChanged(boolean); method public boolean onNavigateUp(); method public boolean onNavigateUpFromChild(android.app.Activity); @@ -48942,7 +48942,7 @@ package android.view { method public boolean onKeyUp(int, android.view.KeyEvent); method protected void onLayout(boolean, int, int, int, int); method protected void onMeasure(int, int); - method public void onMovedToDisplay(int); + method public void onMovedToDisplay(int, android.content.res.Configuration); method protected void onOverScrolled(int, int, boolean, boolean); method public void onPointerCaptureChange(boolean); method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent); diff --git a/api/test-current.txt b/api/test-current.txt index 3a23cd98730a..8edac7171a48 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -3675,7 +3675,7 @@ package android.app { method public void onLowMemory(); method public boolean onMenuItemSelected(int, android.view.MenuItem); method public boolean onMenuOpened(int, android.view.Menu); - method public void onMovedToDisplay(int); + method public void onMovedToDisplay(int, android.content.res.Configuration); method public void onMultiWindowModeChanged(boolean); method public boolean onNavigateUp(); method public boolean onNavigateUpFromChild(android.app.Activity); @@ -45863,7 +45863,7 @@ package android.view { method public boolean onKeyUp(int, android.view.KeyEvent); method protected void onLayout(boolean, int, int, int, int); method protected void onMeasure(int, int); - method public void onMovedToDisplay(int); + method public void onMovedToDisplay(int, android.content.res.Configuration); method protected void onOverScrolled(int, int, boolean, boolean); method public void onPointerCaptureChange(boolean); method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent); diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index fa1de030e729..bace226b2edb 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -1990,27 +1990,32 @@ public class Activity extends ContextThemeWrapper } } - void dispatchMovedToDisplay(int displayId) { + void dispatchMovedToDisplay(int displayId, Configuration config) { updateDisplay(displayId); - onMovedToDisplay(displayId); + onMovedToDisplay(displayId, config); } /** * Called by the system when the activity is moved from one display to another without * recreation. This means that this activity is declared to handle all changes to configuration * that happened when it was switched to another display, so it wasn't destroyed and created - * again. This call will be followed by {@link #onConfigurationChanged(Configuration)} if the - * applied configuration actually changed. + * again. + * + *

This call will be followed by {@link #onConfigurationChanged(Configuration)} if the + * applied configuration actually changed. It is up to app developer to choose whether to handle + * the change in this method or in the following {@link #onConfigurationChanged(Configuration)} + * call. * *

Use this callback to track changes to the displays if some activity functionality relies * on an association with some display properties. * * @param displayId The id of the display to which activity was moved. + * @param config Configuration of the activity resources on new display after move. * * @see #onConfigurationChanged(Configuration) - * @see View#onMovedToDisplay(int) + * @see View#onMovedToDisplay(int, Configuration) */ - public void onMovedToDisplay(int displayId) { + public void onMovedToDisplay(int displayId, Configuration config) { } /** diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index e89dc0bd1956..b5d1fa8550df 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -4801,16 +4801,18 @@ public final class ActivityThread { * {@link ActivityClientRecord#overrideConfig}. * @param displayId The id of the display where the Activity currently resides. * @param movedToDifferentDisplay Indicates if the activity was moved to different display. + * @return {@link Configuration} instance sent to client, null if not sent. */ - private void performConfigurationChangedForActivity(ActivityClientRecord r, + private Configuration performConfigurationChangedForActivity(ActivityClientRecord r, Configuration newBaseConfig, int displayId, boolean movedToDifferentDisplay) { r.tmpConfig.setTo(newBaseConfig); if (r.overrideConfig != null) { r.tmpConfig.updateFrom(r.overrideConfig); } - performActivityConfigurationChanged(r.activity, r.tmpConfig, r.overrideConfig, displayId, - movedToDifferentDisplay); + final Configuration reportedConfig = performActivityConfigurationChanged(r.activity, + r.tmpConfig, r.overrideConfig, displayId, movedToDifferentDisplay); freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); + return reportedConfig; } /** @@ -4864,9 +4866,11 @@ public final class ActivityThread { * ActivityManager. * @param displayId Id of the display where activity currently resides. * @param movedToDifferentDisplay Indicates if the activity was moved to different display. + * @return Configuration sent to client, null if no changes and not moved to different display. */ - private void performActivityConfigurationChanged(Activity activity, Configuration newConfig, - Configuration amOverrideConfig, int displayId, boolean movedToDifferentDisplay) { + private Configuration performActivityConfigurationChanged(Activity activity, + Configuration newConfig, Configuration amOverrideConfig, int displayId, + boolean movedToDifferentDisplay) { if (activity == null) { throw new IllegalArgumentException("No activity provided."); } @@ -4897,7 +4901,7 @@ public final class ActivityThread { } if (!shouldChangeConfig && !movedToDifferentDisplay) { // Nothing significant, don't proceed with updating and reporting. - return; + return null; } // Propagate the configuration change to ResourcesManager and Activity. @@ -4920,22 +4924,22 @@ public final class ActivityThread { activity.mConfigChangeFlags = 0; activity.mCurrentConfig = new Configuration(newConfig); + // Apply the ContextThemeWrapper override if necessary. + // NOTE: Make sure the configurations are not modified, as they are treated as immutable + // in many places. + final Configuration configToReport = createNewConfigAndUpdateIfNotNull(newConfig, + contextThemeWrapperOverrideConfig); + if (!REPORT_TO_ACTIVITY) { // Not configured to report to activity. - return; + return configToReport; } if (movedToDifferentDisplay) { - activity.dispatchMovedToDisplay(displayId); + activity.dispatchMovedToDisplay(displayId, configToReport); } if (shouldChangeConfig) { - // Apply the ContextThemeWrapper override if necessary. - // NOTE: Make sure the configurations are not modified, as they are treated as immutable - // in many places. - final Configuration configToReport = createNewConfigAndUpdateIfNotNull( - newConfig, contextThemeWrapperOverrideConfig); - activity.mCalled = false; activity.onConfigurationChanged(configToReport); if (!activity.mCalled) { @@ -4943,6 +4947,8 @@ public final class ActivityThread { " did not call through to super.onConfigurationChanged()"); } } + + return configToReport; } public final void applyConfigurationToResources(Configuration config) { @@ -5115,10 +5121,10 @@ public final class ActivityThread { + r.activityInfo.name + ", displayId=" + displayId + ", config=" + data.overrideConfig); - performConfigurationChangedForActivity(r, mCompatConfiguration, displayId, - true /* movedToDifferentDisplay */); + final Configuration reportedConfig = performConfigurationChangedForActivity(r, + mCompatConfiguration, displayId, true /* movedToDifferentDisplay */); if (viewRoot != null) { - viewRoot.onMovedToDisplay(displayId); + viewRoot.onMovedToDisplay(displayId, reportedConfig); } } else { if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " @@ -5128,7 +5134,7 @@ public final class ActivityThread { // Notify the ViewRootImpl instance about configuration changes. It may have initiated this // update to make sure that resources are updated before updating itself. if (viewRoot != null) { - viewRoot.updateConfiguration(); + viewRoot.updateConfiguration(displayId); } mSomeActivitiesChanged = true; } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 6c73b9b5ecef..3f52a9d59168 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -16457,29 +16457,34 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * @see #onMovedToDisplay(int) + * @see #onMovedToDisplay(int, Configuration) */ - void dispatchMovedToDisplay(Display display) { + void dispatchMovedToDisplay(Display display, Configuration config) { mAttachInfo.mDisplay = display; mAttachInfo.mDisplayState = display.getState(); - onMovedToDisplay(display.getDisplayId()); + onMovedToDisplay(display.getDisplayId(), config); } /** * Called by the system when the hosting activity is moved from one display to another without * recreation. This means that the activity is declared to handle all changes to configuration * that happened when it was switched to another display, so it wasn't destroyed and created - * again. This call will be followed by {@link #onConfigurationChanged(Configuration)} if the - * applied configuration actually changed. + * again. + * + *

This call will be followed by {@link #onConfigurationChanged(Configuration)} if the + * applied configuration actually changed. It is up to app developer to choose whether to handle + * the change in this method or in the following {@link #onConfigurationChanged(Configuration)} + * call. * *

Use this callback to track changes to the displays if some functionality relies on an * association with some display properties. * * @param displayId The id of the display to which the view was moved. + * @param config Configuration of the resources on new display after move. * * @see #onConfigurationChanged(Configuration) */ - public void onMovedToDisplay(int displayId) { + public void onMovedToDisplay(int displayId, Configuration config) { } /** diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index de0ec40ac97b..792193839a38 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -3281,13 +3281,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } @Override - void dispatchMovedToDisplay(Display display) { - super.dispatchMovedToDisplay(display); + void dispatchMovedToDisplay(Display display, Configuration config) { + super.dispatchMovedToDisplay(display, config); final int count = mChildrenCount; final View[] children = mChildren; for (int i = 0; i < count; i++) { - children[i].dispatchMovedToDisplay(display); + children[i].dispatchMovedToDisplay(display, config); } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 168178702ebf..cf52c60fb2fc 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1106,10 +1106,11 @@ public final class ViewRootImpl implements ViewParent, /** * Notify about move to a different display. * @param displayId The id of the display where this view root is moved to. + * @param config Configuration of the resources on new display after move. * * @hide */ - public void onMovedToDisplay(int displayId) { + public void onMovedToDisplay(int displayId, Configuration config) { if (mDisplay.getDisplayId() == displayId) { return; } @@ -1120,7 +1121,7 @@ public final class ViewRootImpl implements ViewParent, mView.getResources()); mAttachInfo.mDisplayState = mDisplay.getState(); // Internal state updated, now notify the view hierarchy. - mView.dispatchMovedToDisplay(mDisplay); + mView.dispatchMovedToDisplay(mDisplay, config); } void pokeDrawLockIfNeeded() { @@ -3485,15 +3486,16 @@ public final class ViewRootImpl implements ViewParent, mActivityConfigCallback.onConfigurationChanged(overrideConfig, newDisplayId); } else { // There is no activity callback - update the configuration right away. - updateConfiguration(); + updateConfiguration(newDisplayId); } mForceNextConfigUpdate = false; } /** * Update display and views if last applied merged configuration changed. + * @param newDisplayId Id of new display if moved, {@link Display#INVALID_DISPLAY} otherwise. */ - public void updateConfiguration() { + public void updateConfiguration(int newDisplayId) { if (mView == null) { return; } @@ -3503,6 +3505,13 @@ public final class ViewRootImpl implements ViewParent, // the one in them which may be newer. final Resources localResources = mView.getResources(); final Configuration config = localResources.getConfiguration(); + + // Handle move to display. + if (newDisplayId != INVALID_DISPLAY) { + onMovedToDisplay(newDisplayId, config); + } + + // Handle configuration change. if (mForceNextConfigUpdate || mLastConfigurationFromResources.diff(config) != 0) { // Update the display with new DisplayAdjustments. mDisplay = ResourcesManager.getInstance().getAdjustedDisplay( @@ -3674,15 +3683,17 @@ public final class ViewRootImpl implements ViewParent, SomeArgs args = (SomeArgs) msg.obj; final int displayId = args.argi3; + final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4; final boolean displayChanged = mDisplay.getDisplayId() != displayId; - if (displayChanged) { - onMovedToDisplay(displayId); - } - final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4; if (mergedConfiguration != null) { + // If configuration changed - notify about that and, maybe, about move to + // display. performConfigurationChange(mergedConfiguration, false /* force */, displayChanged ? displayId : INVALID_DISPLAY /* same display */); + } else if (displayChanged) { + // Moved to display without config change - report last applied one. + onMovedToDisplay(displayId, mLastConfigurationFromResources); } final boolean framesChanged = !mWinFrame.equals(args.arg1) -- 2.11.0