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

Commit df88d730 authored by Craig Mautner's avatar Craig Mautner
Browse files

Add IIntentSender to ActivityContainer.startActivity

PendingIntents and IntentSenders can now be launched. Still does not
work once the host activity has been paused and resumed.

Window manager TaskStacks now exist independently of Displays and app
windows persist after Displays are removed below them. Attaching the
stack to a new Display does not yet restore the windows to it.

Fixes bug 12747909.

Change-Id: I509007ee23fda400b353f483cf6ecce08177763b
parent 70f908d7
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -3084,8 +3084,11 @@ package android.app {
    ctor public ActivityView(android.content.Context);
    ctor public ActivityView(android.content.Context, android.util.AttributeSet);
    ctor public ActivityView(android.content.Context, android.util.AttributeSet, int);
    method public boolean isAttachedToDisplay();
    method protected void onLayout(boolean, int, int, int, int);
    method public void startActivity(android.content.Intent);
    method public void startActivity(android.content.IntentSender);
    method public void startActivity(android.app.PendingIntent);
  }
  public class AlarmManager {
+53 −24
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.app;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentSender;
import android.graphics.SurfaceTexture;
import android.os.IBinder;
import android.os.RemoteException;
@@ -28,6 +29,7 @@ import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;

@@ -37,7 +39,6 @@ public class ActivityView extends ViewGroup {
    private final TextureView mTextureView;
    private IActivityContainer mActivityContainer;
    private Activity mActivity;
    private boolean mAttached;
    private int mWidth;
    private int mHeight;
    private Surface mSurface;
@@ -85,24 +86,33 @@ public class ActivityView extends ViewGroup {
                    + e);
        }

        final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
        if (surfaceTexture != null) {
            attachToSurface(surfaceTexture);
        }
        attachToSurfaceWhenReady();
    }

    @Override
    protected void onDetachedFromWindow() {
        detachFromSurface();
        if (mActivityContainer != null) {
            detach();
            mActivityContainer = null;
        }
    }

    @Override
    public boolean isAttachedToWindow() {
        return mAttached;
    protected void onWindowVisibilityChanged(int visibility) {
        super.onWindowVisibilityChanged(visibility);
        if (visibility == View.VISIBLE) {
            attachToSurfaceWhenReady();
        } else {
            detach();
        }
    }

    public boolean isAttachedToDisplay() {
        return mSurface != null;
    }

    public void startActivity(Intent intent) {
        if (mActivityContainer != null && mAttached) {
        if (mSurface != null) {
            try {
                mActivityContainer.startActivity(intent);
            } catch (RemoteException e) {
@@ -111,40 +121,59 @@ public class ActivityView extends ViewGroup {
        }
    }

    /** Call when both mActivityContainer and mTextureView's SurfaceTexture are not null */
    private void attachToSurface(SurfaceTexture surfaceTexture) {
    public void startActivity(IntentSender intentSender) {
        if (mSurface != null) {
            try {
                mActivityContainer.startActivityIntentSender(intentSender.getTarget());
            } catch (RemoteException e) {
                throw new IllegalStateException(
                        "ActivityView: Unable to startActivity from IntentSender. " + e);
            }
        }
    }

    public void startActivity(PendingIntent pendingIntent) {
        if (mSurface != null) {
            try {
                mActivityContainer.startActivityIntentSender(pendingIntent.getTarget());
            } catch (RemoteException e) {
                throw new IllegalStateException(
                        "ActivityView: Unable to startActivity from PendingIntent. " + e);
            }
        }
    }

    private void attachToSurfaceWhenReady() {
        final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
        if (mActivityContainer == null || surfaceTexture == null || mSurface != null) {
            // Either not ready to attach, or already attached.
            return;
        }

        WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics metrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(metrics);

        mSurface = new Surface(surfaceTexture);
        try {
            mActivityContainer.attachToSurface(mSurface, mWidth, mHeight,
                    metrics.densityDpi);
            mActivityContainer.attachToSurface(mSurface, mWidth, mHeight, metrics.densityDpi);
        } catch (RemoteException e) {
            mActivityContainer = null;
            mSurface.release();
            mSurface = null;
            mAttached = false;
            throw new IllegalStateException(
                    "ActivityView: Unable to create ActivityContainer. " + e);
        }
        mAttached = true;
    }

    private void detachFromSurface() {
        if (mActivityContainer != null) {
    private void detach() {
        if (mSurface != null) {
            try {
                mActivityContainer.detachFromDisplay();
            } catch (RemoteException e) {
            }
            mActivityContainer = null;
        }
        if (mSurface != null) {
            mSurface.release();
            mSurface = null;
        }
        mAttached = false;
    }

    private class ActivityViewSurfaceTextureListener implements SurfaceTextureListener {
@@ -154,7 +183,7 @@ public class ActivityView extends ViewGroup {
            mWidth = width;
            mHeight = height;
            if (mActivityContainer != null) {
                attachToSurface(surfaceTexture);
                attachToSurfaceWhenReady();
            }
        }

@@ -167,7 +196,7 @@ public class ActivityView extends ViewGroup {
        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
            Log.d(TAG, "onSurfaceTextureDestroyed");
            detachFromSurface();
            detach();
            return true;
        }

+2 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.app;

import android.app.IActivityContainerCallback;
import android.content.Intent;
import android.content.IIntentSender;
import android.os.IBinder;
import android.view.Surface;

@@ -27,5 +28,6 @@ interface IActivityContainer {
    void attachToSurface(in Surface surface, int width, int height, int density);
    void detachFromDisplay();
    int startActivity(in Intent intent);
    int startActivityIntentSender(in IIntentSender intentSender);
    int getDisplayId();
}
+4 −3
Original line number Diff line number Diff line
@@ -3124,7 +3124,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            }
        }
        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
        return ret;
    }
@@ -3236,7 +3236,8 @@ public final class ActivityManagerService extends ActivityManagerNative
    final int startActivityInPackage(int uid, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
                    IActivityContainer container) {
        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                false, true, "startActivityInPackage", null);
@@ -3244,7 +3245,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        // TODO: Switch to user app stacks here.
        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags,
                null, null, null, null, options, userId, null);
                null, null, null, null, options, userId, container);
        return ret;
    }
+13 −0
Original line number Diff line number Diff line
@@ -736,6 +736,12 @@ final class ActivityStack {
            mStackSupervisor.resumeTopActivitiesLocked();
            return;
        }

        if (mActivityContainer.mParentActivity == null) {
            // Top level stack, not a child. Look for child stacks.
            mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping);
        }

        if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev);
        else if (DEBUG_PAUSE) Slog.v(TAG, "Start pausing: " + prev);
        mResumedActivity = null;
@@ -1254,6 +1260,13 @@ final class ActivityStack {
    final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");

        ActivityRecord parent = mActivityContainer.mParentActivity;
        if (parent != null && parent.state != ActivityState.RESUMED) {
            // Do not resume this stack if its parent is not resumed.
            // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st.
            return false;
        }

        // Find the first activity that is not finishing.
        ActivityRecord next = topRunningActivityLocked(null);

Loading