From e88846eeaf70f9f4299af9e3d54ba5dacede42b6 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Wed, 30 Sep 2009 21:34:25 -0700 Subject: [PATCH] Semi-workaround for #2027266: app drawer showing up on the side of the screen (when booted while docked) This isn't really a fix, but we now have the activity report the configuration it actually launched in, so the activity manager will later adjust it if needed. Should help us recover from hitting the race in this particular case. Change-Id: I3bb83a48c2d692b4cb1822d8ae7d924cfa9187b2 --- .../android/app/ActivityManagerNative.java | 14 +++++++++++-- core/java/android/app/ActivityThread.java | 5 ++++- core/java/android/app/IActivityManager.java | 2 +- .../server/am/ActivityManagerService.java | 20 ++++++++++++++----- 4 files changed, 32 insertions(+), 9 deletions(-) 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 c62444de6d51a..20fc1da33f002 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);