diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 2d7658a8ada1e..3b8aee9afc23e 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -315,8 +315,12 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM case ACTIVITY_IDLE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); + Configuration config = null; + if (data.readInt() != 0) { + config = Configuration.CREATOR.createFromParcel(data); + } if (token != null) { - activityIdle(token); + activityIdle(token, config); } reply.writeNoException(); return true; @@ -1397,12 +1401,18 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); reply.recycle(); } - public void activityIdle(IBinder token) throws RemoteException + public void activityIdle(IBinder token, Configuration config) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(token); + if (config != null) { + data.writeInt(1); + config.writeToParcel(data, 0); + } else { + data.writeInt(0); + } mRemote.transact(ACTIVITY_IDLE_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); reply.readException(); data.recycle(); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index fc00a4c324d7c..b4ac159ea4ceb 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1116,6 +1116,7 @@ public final class ActivityThread { boolean stopped; boolean hideForNow; Configuration newConfig; + Configuration createdConfig; ActivityRecord nextIdle; ActivityInfo activityInfo; @@ -1944,7 +1945,8 @@ public final class ActivityThread { (a.activity != null ? a.activity.mFinished : false)); if (a.activity != null && !a.activity.mFinished) { try { - am.activityIdle(a.token); + am.activityIdle(a.token, a.createdConfig); + a.createdConfig = null; } catch (RemoteException ex) { } } @@ -2464,6 +2466,7 @@ public final class ActivityThread { Activity a = performLaunchActivity(r, customIntent); if (a != null) { + r.createdConfig = new Configuration(a.getResources().getConfiguration()); handleResumeActivity(r.token, false, r.isForward); if (!r.activity.mFinished && r.startsNotResumed) { diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 7ad7561655e53..9f505acc854a6 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -109,7 +109,7 @@ public interface IActivityManager extends IInterface { public void setPersistent(IBinder token, boolean isPersistent) throws RemoteException; public void attachApplication(IApplicationThread app) throws RemoteException; /* oneway */ - public void activityIdle(IBinder token) throws RemoteException; + public void activityIdle(IBinder token, Configuration config) throws RemoteException; public void activityPaused(IBinder token, Bundle state) throws RemoteException; /* oneway */ public void activityStopped(IBinder token, diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 5c1a7bc710fa3..3daae29fa27d3 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -1093,7 +1093,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // so we need to be conservative and assume it isn't. IBinder token = (IBinder)msg.obj; Log.w(TAG, "Activity idle timeout for " + token); - activityIdleInternal(token, true); + activityIdleInternal(token, true, null); } break; case DESTROY_TIMEOUT_MSG: { IBinder token = (IBinder)msg.obj; @@ -1104,7 +1104,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } break; case IDLE_NOW_MSG: { IBinder token = (IBinder)msg.obj; - activityIdle(token); + activityIdle(token, null); } break; case SERVICE_TIMEOUT_MSG: { if (mDidDexOpt) { @@ -5419,9 +5419,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } - public final void activityIdle(IBinder token) { + public final void activityIdle(IBinder token, Configuration config) { final long origId = Binder.clearCallingIdentity(); - activityIdleInternal(token, false); + activityIdleInternal(token, false, config); Binder.restoreCallingIdentity(origId); } @@ -5474,7 +5474,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen mWindowManager.enableScreenAfterBoot(); } - final void activityIdleInternal(IBinder token, boolean fromTimeout) { + final void activityIdleInternal(IBinder token, boolean fromTimeout, + Configuration config) { if (localLOGV) Log.v(TAG, "Activity idle: " + token); ArrayList stops = null; @@ -5497,6 +5498,15 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (index >= 0) { HistoryRecord r = (HistoryRecord)mHistory.get(index); + // This is a hack to semi-deal with a race condition + // in the client where it can be constructed with a + // newer configuration from when we asked it to launch. + // We'll update with whatever configuration it now says + // it used to launch. + if (config != null) { + r.configuration = config; + } + // No longer need to keep the device awake. if (mResumedActivity == r && mLaunchingActivity.isHeld()) { mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);