From 061d58a10122b2ef56d4c2ed46090add16fb5b17 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Fri, 12 Mar 2010 15:07:06 -0800 Subject: [PATCH] Fix problem with starting a translucent activity in onCreate(). Fixes issue #2437252: Starting activity by means of startActivityForResult causes 5 seconds delay if "android:windowIsTranslucent" is true The optimization to avoid showing an activity window when a new activity is being started was a little too aggressive. Now it avoids doing this if there is not actually a fullscreen activity on top to cover it. Change-Id: I630e37a1f1d3b874b5a25572cbf887cebc2e3e91 --- .../android/app/ActivityManagerNative.java | 21 +++++++++++++++++++ core/java/android/app/ActivityThread.java | 19 ++++++++++------- core/java/android/app/IActivityManager.java | 2 ++ .../server/am/ActivityManagerService.java | 16 ++++++++++++++ 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 6849fd7660351..6d5686a40c336 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -227,6 +227,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } + case WILL_ACTIVITY_BE_VISIBLE_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IBinder token = data.readStrongBinder(); + boolean res = willActivityBeVisible(token); + reply.writeNoException(); + reply.writeInt(res ? 1 : 0); + return true; + } + case REGISTER_RECEIVER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); @@ -1360,6 +1369,18 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); reply.recycle(); } + public boolean willActivityBeVisible(IBinder token) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(token); + mRemote.transact(WILL_ACTIVITY_BE_VISIBLE_TRANSACTION, data, reply, 0); + reply.readException(); + boolean res = reply.readInt() != 0; + data.recycle(); + reply.recycle(); + return res; + } public Intent registerReceiver(IApplicationThread caller, IIntentReceiver receiver, IntentFilter filter, String perm) throws RemoteException diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 7b5b63e1d21a2..35d1948d87031 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3095,9 +3095,6 @@ public final class ActivityThread { r.paused = false; r.stopped = false; - if (r.activity.mStartedActivity) { - r.hideForNow = true; - } r.state = null; } catch (Exception e) { if (!mInstrumentation.onException(r.activity, e)) { @@ -3132,7 +3129,15 @@ public final class ActivityThread { // If the window hasn't yet been added to the window manager, // and this guy didn't finish itself or start another activity, // then go ahead and add the window. - if (r.window == null && !a.mFinished && !a.mStartedActivity) { + boolean willBeVisible = !a.mStartedActivity; + if (!willBeVisible) { + try { + willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible( + a.getActivityToken()); + } catch (RemoteException e) { + } + } + if (r.window == null && !a.mFinished && willBeVisible) { r.window = r.activity.getWindow(); View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); @@ -3148,8 +3153,8 @@ public final class ActivityThread { // If the window has already been added, but during resume // we started another activity, then don't yet make the - // window visisble. - } else if (a.mStartedActivity) { + // window visible. + } else if (!willBeVisible) { if (localLOGV) Log.v( TAG, "Launch " + r + " mStartedActivity set"); r.hideForNow = true; @@ -3157,7 +3162,7 @@ public final class ActivityThread { // The window is now visible if it has been added, we are not // simply finishing, and we are not starting another activity. - if (!r.activity.mFinished && !a.mStartedActivity + if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) { if (r.newConfig != null) { if (DEBUG_CONFIGURATION) Log.v(TAG, "Resuming activity " diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 3913ed5da0a24..14571defc6fa4 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -97,6 +97,7 @@ public interface IActivityManager extends IInterface { public boolean finishActivity(IBinder token, int code, Intent data) throws RemoteException; public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException; + public boolean willActivityBeVisible(IBinder token) throws RemoteException; public Intent registerReceiver(IApplicationThread caller, IIntentReceiver receiver, IntentFilter filter, String requiredPermission) throws RemoteException; @@ -501,4 +502,5 @@ public interface IActivityManager extends IInterface { int KILL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+102; int IS_USER_A_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+103; int START_ACTIVITY_AND_WAIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+104; + int WILL_ACTIVITY_BE_VISIBLE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+105; } diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index a501cebe2975b..b6064e8160868 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -4268,6 +4268,22 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } + public boolean willActivityBeVisible(IBinder token) { + synchronized(this) { + int i; + for (i=mHistory.size()-1; i>=0; i--) { + HistoryRecord r = (HistoryRecord)mHistory.get(i); + if (r == token) { + return true; + } + if (r.fullscreen && !r.finishing) { + return false; + } + } + return true; + } + } + public void overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim) { synchronized(this) {