From ca66481244913c4a17b62c3ddff214d2ca72c439 Mon Sep 17 00:00:00 2001 From: Filip Gruszczynski Date: Fri, 4 Dec 2015 12:43:36 -0800 Subject: [PATCH] Update client configuration when resizing without crossing size threshold. Even though the activity won't be relaunched and won't receive a callback about the resize, we still need to update it's configuration. Otherwise when the application queries for it, it will receive wrong data. Bug: 23904868 Change-Id: I601e91b8e71691c1cb5edb2734894441c4fde8e2 --- core/java/android/app/ActivityThread.java | 33 +++++++++++-------- .../android/app/ApplicationThreadNative.java | 8 +++-- core/java/android/app/IApplicationThread.java | 4 +-- .../com/android/server/am/ActivityRecord.java | 13 ++++++++ .../com/android/server/am/ActivityStack.java | 16 ++++----- 5 files changed, 46 insertions(+), 28 deletions(-) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 74f0c0e0e1e3d..e867bb776b715 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -83,7 +83,6 @@ import android.util.AndroidRuntimeException; import android.util.ArrayMap; import android.util.DisplayMetrics; import android.util.EventLog; -import android.util.IntArray; import android.util.Log; import android.util.LogPrinter; import android.util.Pair; @@ -184,6 +183,9 @@ public final class ActivityThread { private static final int USER_LEAVING = 1; private static final int DONT_REPORT = 2; + // Whether to invoke an activity callback after delivering new configuration. + private static final boolean REPORT_TO_ACTIVITY = true; + private ContextImpl mSystemContext; static IPackageManager sPackageManager; @@ -943,9 +945,9 @@ public final class ActivityThread { @Override public void scheduleActivityConfigurationChanged( - IBinder token, Configuration overrideConfig) { + IBinder token, Configuration overrideConfig, boolean reportToActivity) { sendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, - new ActivityConfigChangeData(token, overrideConfig)); + new ActivityConfigChangeData(token, overrideConfig), reportToActivity ? 1 : 0); } @Override @@ -1537,7 +1539,8 @@ public final class ActivityThread { break; case ACTIVITY_CONFIGURATION_CHANGED: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged"); - handleActivityConfigurationChanged((ActivityConfigChangeData)msg.obj); + handleActivityConfigurationChanged((ActivityConfigChangeData) msg.obj, + msg.arg1 == 1 ? REPORT_TO_ACTIVITY : !REPORT_TO_ACTIVITY); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case PROFILER_CONTROL: @@ -3347,7 +3350,7 @@ public final class ActivityThread { } if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig " + r.tmpConfig); - performConfigurationChanged(r.activity, r.tmpConfig); + performConfigurationChanged(r.activity, r.tmpConfig, REPORT_TO_ACTIVITY); freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); r.newConfig = null; } @@ -3687,7 +3690,7 @@ public final class ActivityThread { } if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " + r.activityInfo.name + " with new config " + r.tmpConfig); - performConfigurationChanged(r.activity, r.tmpConfig); + performConfigurationChanged(r.activity, r.tmpConfig, REPORT_TO_ACTIVITY); freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); r.newConfig = null; } @@ -4340,7 +4343,8 @@ public final class ActivityThread { return callbacks; } - private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) { + private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config, + boolean reportToActivity) { // Only for Activity objects, check that they actually call up to their // superclass implementation. ComponentCallbacks2 is an interface, so // we check the runtime type and act accordingly. @@ -4371,10 +4375,12 @@ public final class ActivityThread { if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb + ": shouldChangeConfig=" + shouldChangeConfig); if (shouldChangeConfig) { - cb.onConfigurationChanged(config); + if (reportToActivity) { + cb.onConfigurationChanged(config); + } if (activity != null) { - if (!activity.mCalled) { + if (reportToActivity && !activity.mCalled) { throw new SuperNotCalledException( "Activity " + activity.getLocalClassName() + " did not call through to super.onConfigurationChanged()"); @@ -4449,7 +4455,7 @@ public final class ActivityThread { if (callbacks != null) { final int N = callbacks.size(); for (int i=0; i weakActivity; private final ActivityManagerService mService; diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 36a7ceea5853c..c4f363406eb97 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -4093,6 +4093,9 @@ final class ActivityStack { if (changes == 0 && !r.forceNewConfig) { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Configuration no differences in " + r); + // There are no significant differences, so we won't relaunch but should still deliver + // the new configuration to the client process. + r.scheduleConfigurationChanged(taskConfig, false); return true; } @@ -4115,7 +4118,8 @@ final class ActivityStack { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Checking to restart " + r.info.name + ": changed=0x" + Integer.toHexString(changes) + ", handles=0x" - + Integer.toHexString(r.info.getRealConfigChanged()) + ", newConfig=" + newConfig); + + Integer.toHexString(r.info.getRealConfigChanged()) + ", newConfig=" + newConfig + + ", taskConfig=" + taskConfig); if ((changes&(~r.info.getRealConfigChanged())) != 0 || r.forceNewConfig) { // Aha, the activity isn't handling the change, so DIE DIE DIE. @@ -4161,15 +4165,7 @@ final class ActivityStack { // NOTE: We only forward the task override configuration as the system level configuration // changes is always sent to all processes when they happen so it can just use whatever // system level configuration it last got. - if (r.app != null && r.app.thread != null) { - try { - if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending new config to " + r); - r.app.thread.scheduleActivityConfigurationChanged( - r.appToken, new Configuration(taskConfig)); - } catch (RemoteException e) { - // If process died, whatever. - } - } + r.scheduleConfigurationChanged(taskConfig, true); r.stopFreezingScreenLocked(false); return true;