Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d3f00e3 authored by Craig Mautner's avatar Craig Mautner Committed by Android Git Automerger
Browse files

am 358188f5: Merge "Change ActivityView startActivity state sequence" into lmp-mr1-modular-dev

* commit '358188f5':
  Change ActivityView startActivity state sequence
parents 59e06d3a 358188f5
Loading
Loading
Loading
Loading
+44 −52
Original line number Diff line number Diff line
@@ -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.
     *
     * 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();
+0 −2
Original line number Diff line number Diff line
@@ -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();
+27 −37
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ import android.hardware.display.DisplayManagerGlobal;
import android.hardware.display.VirtualDisplay;
import android.hardware.input.InputManager;
import android.hardware.input.InputManagerInternal;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
@@ -855,6 +856,11 @@ public final class ActivityStackSupervisor implements DisplayListener {

        ActivityContainer container = (ActivityContainer)iContainer;
        synchronized (mService) {
            if (container != null && container.mParentActivity != null &&
                    container.mParentActivity.state != ActivityState.RESUMED) {
                // Cannot start a child activity if the parent is not resumed.
                return ActivityManager.START_CANCELED;
            }
            final int realCallingPid = Binder.getCallingPid();
            final int realCallingUid = Binder.getCallingUid();
            int callingPid;
@@ -3789,18 +3795,21 @@ public final class ActivityStackSupervisor implements DisplayListener {
        @Override
        public final int startActivity(Intent intent) {
            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
            final int userId = mService.handleIncomingUser(Binder.getCallingPid(),
                    Binder.getCallingUid(), mCurrentUser, false,
                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);

            // TODO: Switch to user app stacks here.
            intent.addFlags(FORCE_NEW_TASK_FLAGS);
            String mimeType = intent.getType();
            if (mimeType == null && intent.getData() != null
                    && "content".equals(intent.getData().getScheme())) {
                mimeType = mService.getProviderMimeType(intent.getData(), userId);
            final Uri data = intent.getData();
            if (mimeType == null && data != null && "content".equals(data.getScheme())) {
                mimeType = mService.getProviderMimeType(data, userId);
            }
            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0,
                    0, null, null, null, null, userId, this, null);
            checkEmbeddedAllowedInner(userId, intent, mimeType);

            intent.addFlags(FORCE_NEW_TASK_FLAGS);
            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null,
                    0, 0, null, null, null, null, userId, this, null);
        }

        @Override
@@ -3811,21 +3820,19 @@ public final class ActivityStackSupervisor implements DisplayListener {
                throw new IllegalArgumentException("Bad PendingIntent object");
            }

            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
                    null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
        }

        private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) {
            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
            final int userId = mService.handleIncomingUser(Binder.getCallingPid(),
                    Binder.getCallingUid(), mCurrentUser, false,
                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
            if (resolvedType == null) {
                resolvedType = intent.getType();
                if (resolvedType == null && intent.getData() != null
                        && "content".equals(intent.getData().getScheme())) {
                    resolvedType = mService.getProviderMimeType(intent.getData(), userId);
                }

            final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
            checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent,
                    pendingIntent.key.requestResolvedType);

            return pendingIntent.sendInner(0, null, null, null, null, null, null, 0,
                    FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
        }

        private void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) {
            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId);
            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
                throw new SecurityException(
@@ -3833,23 +3840,6 @@ public final class ActivityStackSupervisor implements DisplayListener {
            }
        }

        /** Throw a SecurityException if allowEmbedded is not true */
        @Override
        public final void checkEmbeddedAllowed(Intent intent) {
            checkEmbeddedAllowedInner(intent, null);
        }

        /** Throw a SecurityException if allowEmbedded is not true */
        @Override
        public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
            if (!(intentSender instanceof PendingIntentRecord)) {
                throw new IllegalArgumentException("Bad PendingIntent object");
            }
            PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
            checkEmbeddedAllowedInner(pendingIntent.key.requestIntent,
                    pendingIntent.key.requestResolvedType);
        }

        @Override
        public IBinder asBinder() {
            return this;
+9 −0
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Slog;

import com.android.server.am.ActivityStackSupervisor.ActivityContainer;

import java.io.PrintWriter;
import java.lang.ref.WeakReference;

@@ -201,6 +203,13 @@ final class PendingIntentRecord extends IIntentSender.Stub {
            IBinder resultTo, String resultWho, int requestCode,
            int flagsMask, int flagsValues, Bundle options, IActivityContainer container) {
        synchronized(owner) {
            final ActivityContainer activityContainer = (ActivityContainer)container;
            if (activityContainer != null && activityContainer.mParentActivity != null &&
                    activityContainer.mParentActivity.state
                            != ActivityStack.ActivityState.RESUMED) {
                // Cannot start a child activity if the parent is not resumed.
                return ActivityManager.START_CANCELED;
            }
            if (!canceled) {
                sent = true;
                if ((key.flags&PendingIntent.FLAG_ONE_SHOT) != 0) {