summaryrefslogtreecommitdiffstats
path: root/core/java/android/app
diff options
context:
space:
mode:
authorCraig Mautner <cmautner@google.com>2015-02-26 20:40:19 -0800
committerCraig Mautner <cmautner@google.com>2015-03-03 10:15:21 -0800
commitb916836e8dcd4aa3564479be508d7a9d73dcbce8 (patch)
treee9c6750c951f515919737afe67852f4c74845d84 /core/java/android/app
parent654a473bfea9a4197868ae81091812505da8ca87 (diff)
downloadframeworks_base-b916836e8dcd4aa3564479be508d7a9d73dcbce8.zip
frameworks_base-b916836e8dcd4aa3564479be508d7a9d73dcbce8.tar.gz
frameworks_base-b916836e8dcd4aa3564479be508d7a9d73dcbce8.tar.bz2
Change ActivityView startActivity state sequence
Problems arise if an activity is started in an ActivityView when the parent activity is not resumed. In particular the ActivityView can be brought to the front in front of other activities that have been started by the parent. This change checks the state of the parent when the ActivityView is starting and if it is not resumed, throws an Exception. This change also removes the queueing up of Intents if the surface does not exist when startActivity is called. Now, the owner of the ActivityView is notified when the surface becomes available. If startActivity is called before that notification an Exception will be thrown. Fixes bug 19147472. Change-Id: I6712cf1929fe65c4238ce7f3feb4e8511ed97244
Diffstat (limited to 'core/java/android/app')
-rw-r--r--core/java/android/app/ActivityView.java96
-rw-r--r--core/java/android/app/IActivityContainer.aidl2
2 files changed, 44 insertions, 54 deletions
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 94ea2c5..fecaf6f 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -16,6 +16,8 @@
package android.app;
+import static android.app.ActivityManager.START_CANCELED;
+
import android.content.Context;
import android.content.ContextWrapper;
import android.content.IIntentSender;
@@ -23,6 +25,7 @@ import android.content.Intent;
import android.content.IntentSender;
import android.graphics.SurfaceTexture;
import android.os.IBinder;
+import android.os.OperationCanceledException;
import android.os.RemoteException;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -55,10 +58,6 @@ public class ActivityView extends ViewGroup {
private int mLastVisibility;
private ActivityViewCallback mActivityViewCallback;
- // Only one IIntentSender or Intent may be queued at a time. Most recent one wins.
- IIntentSender mQueuedPendingIntent;
- Intent mQueuedIntent;
-
public ActivityView(Context context) {
this(context, null);
}
@@ -167,14 +166,13 @@ public class ActivityView extends ViewGroup {
if (mActivityContainer == null) {
throw new IllegalStateException("Attempt to call startActivity after release");
}
+ if (mSurface == null) {
+ throw new IllegalStateException("Surface not yet created.");
+ }
if (DEBUG) Log.v(TAG, "startActivity(): intent=" + intent + " " +
(isAttachedToDisplay() ? "" : "not") + " attached");
- if (mSurface != null) {
- mActivityContainer.startActivity(intent);
- } else {
- mActivityContainer.checkEmbeddedAllowed(intent);
- mQueuedIntent = intent;
- mQueuedPendingIntent = null;
+ if (mActivityContainer.startActivity(intent) == START_CANCELED) {
+ throw new OperationCanceledException();
}
}
@@ -182,15 +180,14 @@ public class ActivityView extends ViewGroup {
if (mActivityContainer == null) {
throw new IllegalStateException("Attempt to call startActivity after release");
}
+ if (mSurface == null) {
+ throw new IllegalStateException("Surface not yet created.");
+ }
if (DEBUG) Log.v(TAG, "startActivityIntentSender(): intentSender=" + intentSender + " " +
(isAttachedToDisplay() ? "" : "not") + " attached");
final IIntentSender iIntentSender = intentSender.getTarget();
- if (mSurface != null) {
- mActivityContainer.startActivityIntentSender(iIntentSender);
- } else {
- mActivityContainer.checkEmbeddedAllowedIntentSender(iIntentSender);
- mQueuedPendingIntent = iIntentSender;
- mQueuedIntent = null;
+ if (mActivityContainer.startActivityIntentSender(iIntentSender) == START_CANCELED) {
+ throw new OperationCanceledException();
}
}
@@ -198,15 +195,14 @@ public class ActivityView extends ViewGroup {
if (mActivityContainer == null) {
throw new IllegalStateException("Attempt to call startActivity after release");
}
+ if (mSurface == null) {
+ throw new IllegalStateException("Surface not yet created.");
+ }
if (DEBUG) Log.v(TAG, "startActivityPendingIntent(): PendingIntent=" + pendingIntent + " "
+ (isAttachedToDisplay() ? "" : "not") + " attached");
final IIntentSender iIntentSender = pendingIntent.getTarget();
- if (mSurface != null) {
- mActivityContainer.startActivityIntentSender(iIntentSender);
- } else {
- mActivityContainer.checkEmbeddedAllowedIntentSender(iIntentSender);
- mQueuedPendingIntent = iIntentSender;
- mQueuedIntent = null;
+ if (mActivityContainer.startActivityIntentSender(iIntentSender) == START_CANCELED) {
+ throw new OperationCanceledException();
}
}
@@ -243,26 +239,24 @@ public class ActivityView extends ViewGroup {
mSurface = null;
throw new RuntimeException("ActivityView: Unable to create ActivityContainer. " + e);
}
-
- if (DEBUG) Log.v(TAG, "attachToSurfaceWhenReady: " + (mQueuedIntent != null ||
- mQueuedPendingIntent != null ? "" : "no") + " queued intent");
- if (mQueuedIntent != null) {
- mActivityContainer.startActivity(mQueuedIntent);
- mQueuedIntent = null;
- } else if (mQueuedPendingIntent != null) {
- mActivityContainer.startActivityIntentSender(mQueuedPendingIntent);
- mQueuedPendingIntent = null;
- }
}
/**
* Set the callback to use to report certain state changes.
- * @param callback The callback to report events to.
+ *
+ * Note: If the surface has been created prior to this call being made, then
+ * ActivityViewCallback.onSurfaceAvailable will be called from within setCallback.
+ *
+ * @param callback The callback to report events to.
*
* @see ActivityViewCallback
*/
public void setCallback(ActivityViewCallback callback) {
mActivityViewCallback = callback;
+
+ if (mSurface != null) {
+ mActivityViewCallback.onSurfaceAvailable(this);
+ }
}
public static abstract class ActivityViewCallback {
@@ -272,6 +266,16 @@ public class ActivityView extends ViewGroup {
* have at most one callback registered.
*/
public abstract void onAllActivitiesComplete(ActivityView view);
+ /**
+ * Called when the surface is ready to be drawn to. Calling startActivity prior to this
+ * callback will result in an IllegalStateException.
+ */
+ public abstract void onSurfaceAvailable(ActivityView view);
+ /**
+ * Called when the surface has been removed. Calling startActivity after this callback
+ * will result in an IllegalStateException.
+ */
+ public abstract void onSurfaceDestroyed(ActivityView view);
}
private class ActivityViewSurfaceTextureListener implements SurfaceTextureListener {
@@ -286,6 +290,9 @@ public class ActivityView extends ViewGroup {
mWidth = width;
mHeight = height;
attachToSurfaceWhenReady();
+ if (mActivityViewCallback != null) {
+ mActivityViewCallback.onSurfaceAvailable(ActivityView.this);
+ }
}
@Override
@@ -311,6 +318,9 @@ public class ActivityView extends ViewGroup {
throw new RuntimeException(
"ActivityView: Unable to set surface of ActivityContainer. " + e);
}
+ if (mActivityViewCallback != null) {
+ mActivityViewCallback.onSurfaceDestroyed(ActivityView.this);
+ }
return true;
}
@@ -325,7 +335,7 @@ public class ActivityView extends ViewGroup {
private final WeakReference<ActivityView> mActivityViewWeakReference;
ActivityContainerCallback(ActivityView activityView) {
- mActivityViewWeakReference = new WeakReference<ActivityView>(activityView);
+ mActivityViewWeakReference = new WeakReference<>(activityView);
}
@Override
@@ -391,24 +401,6 @@ public class ActivityView extends ViewGroup {
}
}
- void checkEmbeddedAllowed(Intent intent) {
- try {
- mIActivityContainer.checkEmbeddedAllowed(intent);
- } catch (RemoteException e) {
- throw new RuntimeException(
- "ActivityView: Unable to startActivity from Intent. " + e);
- }
- }
-
- void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
- try {
- mIActivityContainer.checkEmbeddedAllowedIntentSender(intentSender);
- } catch (RemoteException e) {
- throw new RuntimeException(
- "ActivityView: Unable to startActivity from IntentSender. " + e);
- }
- }
-
int getDisplayId() {
try {
return mIActivityContainer.getDisplayId();
diff --git a/core/java/android/app/IActivityContainer.aidl b/core/java/android/app/IActivityContainer.aidl
index 52884f7..cc3b10c 100644
--- a/core/java/android/app/IActivityContainer.aidl
+++ b/core/java/android/app/IActivityContainer.aidl
@@ -29,8 +29,6 @@ interface IActivityContainer {
void setSurface(in Surface surface, int width, int height, int density);
int startActivity(in Intent intent);
int startActivityIntentSender(in IIntentSender intentSender);
- void checkEmbeddedAllowed(in Intent intent);
- void checkEmbeddedAllowedIntentSender(in IIntentSender intentSender);
int getDisplayId();
boolean injectEvent(in InputEvent event);
void release();