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

Commit 621e17de authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Implement issue #3221502: New APIs to support new back stack / task navigation

What this adds:

- A new Intent activity flag to completely replace an existing task.
- A new Intent activity flag to bring the current home task up behind
  a new task being started/brought to the foreground.
- New versions of startActivity() that take an array of Intents to be
  started, allowing applications to start a task in a specific state.
- A public moveTaskToFront() method on ActivityManager, with a new flag
  that allows the caller to have the task moved to the front with the
  current home task immediately behind it.

Change-Id: Ie8028d09acffb5349d98043c67676daba09f75c8
parent 703c5f39
Loading
Loading
Loading
Loading
+106 −0
Original line number Diff line number Diff line
@@ -23927,6 +23927,21 @@
<parameter name="packageName" type="java.lang.String">
</parameter>
</method>
<method name="moveTaskToFront"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="taskId" type="int">
</parameter>
<parameter name="flags" type="int">
</parameter>
</method>
<method name="restartPackage"
 return="void"
 abstract="false"
@@ -23940,6 +23955,17 @@
<parameter name="packageName" type="java.lang.String">
</parameter>
</method>
<field name="MOVE_TASK_WITH_HOME"
 type="int"
 transient="false"
 volatile="false"
 value="1"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="RECENT_WITH_EXCLUDED"
 type="int"
 transient="false"
@@ -33066,6 +33092,25 @@
 visibility="public"
>
</method>
<method name="getActivities"
 return="android.app.PendingIntent"
 abstract="false"
 native="false"
 synchronized="false"
 static="true"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="context" type="android.content.Context">
</parameter>
<parameter name="requestCode" type="int">
</parameter>
<parameter name="intents" type="android.content.Intent[]">
</parameter>
<parameter name="flags" type="int">
</parameter>
</method>
<method name="getActivity"
 return="android.app.PendingIntent"
 abstract="false"
@@ -47145,6 +47190,19 @@
<exception name="IOException" type="java.io.IOException">
</exception>
</method>
<method name="startActivities"
 return="void"
 abstract="true"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="intents" type="android.content.Intent[]">
</parameter>
</method>
<method name="startActivity"
 return="void"
 abstract="true"
@@ -48602,6 +48660,19 @@
<exception name="IOException" type="java.io.IOException">
</exception>
</method>
<method name="startActivities"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="intents" type="android.content.Intent[]">
</parameter>
</method>
<method name="startActivity"
 return="void"
 abstract="false"
@@ -52554,6 +52625,17 @@
 visibility="public"
>
</field>
<field name="FLAG_ACTIVITY_CLEAR_TASK"
 type="int"
 transient="false"
 volatile="false"
 value="32768"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="FLAG_ACTIVITY_CLEAR_TOP"
 type="int"
 transient="false"
@@ -52708,6 +52790,17 @@
 visibility="public"
>
</field>
<field name="FLAG_ACTIVITY_TASK_ON_HOME"
 type="int"
 transient="false"
 volatile="false"
 value="16384"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="FLAG_DEBUG_LOG_RESOLUTION"
 type="int"
 transient="false"
@@ -174471,6 +174564,19 @@
<exception name="IOException" type="java.io.IOException">
</exception>
</method>
<method name="startActivities"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="intents" type="android.content.Intent[]">
</parameter>
</method>
<method name="startActivity"
 return="void"
 abstract="false"
+25 −1
Original line number Diff line number Diff line
@@ -3134,6 +3134,30 @@ public class Activity extends ContextThemeWrapper
        startActivityForResult(intent, -1);
    }

    /**
     * Launch a new activity.  You will not receive any information about when
     * the activity exits.  This implementation overrides the base version,
     * providing information about
     * the activity performing the launch.  Because of this additional
     * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not
     * required; if not specified, the new activity will be added to the
     * task of the caller.
     *
     * <p>This method throws {@link android.content.ActivityNotFoundException}
     * if there was no Activity found to run the given Intent.
     *
     * @param intents The intents to start.
     *
     * @throws android.content.ActivityNotFoundException
     *
     * @see #startActivityForResult
     */
    @Override
    public void startActivities(Intent[] intents) {
        mInstrumentation.execStartActivities(this, mMainThread.getApplicationThread(),
                mToken, this, intents);
    }

    /**
     * Like {@link #startActivity(Intent)}, but taking a IntentSender
     * to start; see
@@ -3616,7 +3640,7 @@ public class Activity extends ContextThemeWrapper
                ActivityManagerNative.getDefault().getIntentSender(
                        IActivityManager.INTENT_SENDER_ACTIVITY_RESULT, packageName,
                        mParent == null ? mToken : mParent.mToken,
                        mEmbeddedID, requestCode, data, null, flags);
                        mEmbeddedID, requestCode, new Intent[] { data }, null, flags);
            return target != null ? new PendingIntent(target) : null;
        } catch (RemoteException e) {
            // Empty
+26 −0
Original line number Diff line number Diff line
@@ -333,6 +333,32 @@ public class ActivityManager {
        return getRunningTasks(maxNum, 0, null);
    }

    /**
     * Flag for {@link #moveTaskToFront(int, int)}: also move the "home"
     * activity along with the task, so it is positioned immediately behind
     * the task.
     */
    public static final int MOVE_TASK_WITH_HOME = 0x00000001;

    /**
     * Ask that the task associated with a given task ID be moved to the
     * front of the stack, so it is now visible to the user.  Requires that
     * the caller hold permission {@link android.Manifest.permission#REORDER_TASKS}
     * or a SecurityException will be thrown.
     *
     * @param taskId The identifier of the task to be moved, as found in
     * {@link RunningTaskInfo} or {@link RecentTaskInfo}.
     * @param flags Additional operational flags, 0 or more of
     * {@link #MOVE_TASK_WITH_HOME}.
     */
    public void moveTaskToFront(int taskId, int flags) {
        try {
            ActivityManagerNative.getDefault().moveTaskToFront(taskId, flags);
        } catch (RemoteException e) {
            // System dead, we will be dead too soon!
        }
    }

    /**
     * Information you can retrieve about a particular Service that is
     * currently running in the system.
+80 −11
Original line number Diff line number Diff line
@@ -492,7 +492,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        case MOVE_TASK_TO_FRONT_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            int task = data.readInt();
            moveTaskToFront(task);
            int fl = data.readInt();
            moveTaskToFront(task, fl);
            reply.writeNoException();
            return true;
        }
@@ -791,13 +792,19 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            IBinder token = data.readStrongBinder();
            String resultWho = data.readString();
            int requestCode = data.readInt();
            Intent requestIntent = data.readInt() != 0
                    ? Intent.CREATOR.createFromParcel(data) : null;
            String requestResolvedType = data.readString();
            Intent[] requestIntents;
            String[] requestResolvedTypes;
            if (data.readInt() != 0) {
                requestIntents = data.createTypedArray(Intent.CREATOR);
                requestResolvedTypes = data.createStringArray();
            } else {
                requestIntents = null;
                requestResolvedTypes = null;
            }
            int fl = data.readInt();
            IIntentSender res = getIntentSender(type, packageName, token,
                    resultWho, requestCode, requestIntent,
                    requestResolvedType, fl);
                    resultWho, requestCode, requestIntents,
                    requestResolvedTypes, fl);
            reply.writeNoException();
            reply.writeStrongBinder(res != null ? res.asBinder() : null);
            return true;
@@ -1355,6 +1362,33 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            return true;
        }

        case START_ACTIVITIES_IN_PACKAGE_TRANSACTION:
        {
            data.enforceInterface(IActivityManager.descriptor);
            int uid = data.readInt();
            Intent[] intents = data.createTypedArray(Intent.CREATOR);
            String[] resolvedTypes = data.createStringArray();
            IBinder resultTo = data.readStrongBinder();
            int result = startActivitiesInPackage(uid, intents, resolvedTypes, resultTo);
            reply.writeNoException();
            reply.writeInt(result);
            return true;
        }

        case START_ACTIVITIES_TRANSACTION:
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            Intent[] intents = data.createTypedArray(Intent.CREATOR);
            String[] resolvedTypes = data.createStringArray();
            IBinder resultTo = data.readStrongBinder();
            int result = startActivities(app, intents, resolvedTypes, resultTo);
            reply.writeNoException();
            reply.writeInt(result);
            return true;
        }

        }
        
        return super.onTransact(code, data, reply, flags);
@@ -1829,12 +1863,13 @@ class ActivityManagerProxy implements IActivityManager
        reply.recycle();
        return list;
    }
    public void moveTaskToFront(int task) throws RemoteException
    public void moveTaskToFront(int task, int flags) throws RemoteException
    {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeInt(task);
        data.writeInt(flags);
        mRemote.transact(MOVE_TASK_TO_FRONT_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
@@ -2283,7 +2318,7 @@ class ActivityManagerProxy implements IActivityManager
    }
    public IIntentSender getIntentSender(int type,
            String packageName, IBinder token, String resultWho,
            int requestCode, Intent intent, String resolvedType, int flags)
            int requestCode, Intent[] intents, String[] resolvedTypes, int flags)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
@@ -2293,13 +2328,13 @@ class ActivityManagerProxy implements IActivityManager
        data.writeStrongBinder(token);
        data.writeString(resultWho);
        data.writeInt(requestCode);
        if (intent != null) {
        if (intents != null) {
            data.writeInt(1);
            intent.writeToParcel(data, 0);
            data.writeTypedArray(intents, 0);
            data.writeStringArray(resolvedTypes);
        } else {
            data.writeInt(0);
        }
        data.writeString(resolvedType);
        data.writeInt(flags);
        mRemote.transact(GET_INTENT_SENDER_TRANSACTION, data, reply, 0);
        reply.readException();
@@ -3026,5 +3061,39 @@ class ActivityManagerProxy implements IActivityManager
        return res;
    }
    
    public int startActivities(IApplicationThread caller,
            Intent[] intents, String[] resolvedTypes, IBinder resultTo) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        data.writeTypedArray(intents, 0);
        data.writeStringArray(resolvedTypes);
        data.writeStrongBinder(resultTo);
        mRemote.transact(START_ACTIVITIES_TRANSACTION, data, reply, 0);
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }

    public int startActivitiesInPackage(int uid,
            Intent[] intents, String[] resolvedTypes, IBinder resultTo) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeInt(uid);
        data.writeTypedArray(intents, 0);
        data.writeStringArray(resolvedTypes);
        data.writeStrongBinder(resultTo);
        mRemote.transact(START_ACTIVITIES_IN_PACKAGE_TRANSACTION, data, reply, 0);
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }

    private IBinder mRemote;
}
+13 −0
Original line number Diff line number Diff line
@@ -843,6 +843,19 @@ class ContextImpl extends Context {
            (Activity)null, intent, -1);
    }

    @Override
    public void startActivities(Intent[] intents) {
        if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
            throw new AndroidRuntimeException(
                    "Calling startActivities() from outside of an Activity "
                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
                    + " Is this really what you want?");
        }
        mMainThread.getInstrumentation().execStartActivities(
            getOuterContext(), mMainThread.getApplicationThread(), null,
            (Activity)null, intents);
    }

    @Override
    public void startIntentSender(IntentSender intent,
            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
Loading