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
This commit is contained in:
Dianne Hackborn
2010-03-12 15:07:06 -08:00
parent 069b3cfcd4
commit 061d58a101
4 changed files with 51 additions and 7 deletions

View File

@@ -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

View File

@@ -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 "

View File

@@ -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;
}

View File

@@ -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) {