Create API for launching from recents

Relaunch apps from recents using the same uid and package as was used
in the original launch.

Fixes bug 16358208.

Change-Id: I340800bfee79926b197929360d69f1d570bbf1eb
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index fb70098..342155d 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -284,6 +284,17 @@
             return true;
         }
 
+        case START_ACTIVITY_FROM_RECENTS_TRANSACTION:
+        {
+            data.enforceInterface(IActivityManager.descriptor);
+            int taskId = data.readInt();
+            Bundle options = data.readInt() == 0 ? null : Bundle.CREATOR.createFromParcel(data);
+            int result = startActivityFromRecents(taskId, options);
+            reply.writeNoException();
+            reply.writeInt(result);
+            return true;
+        }
+
         case FINISH_ACTIVITY_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
@@ -2482,6 +2493,24 @@
         data.recycle();
         return result != 0;
     }
+    public int startActivityFromRecents(int taskId, Bundle options) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(taskId);
+        if (options == null) {
+            data.writeInt(0);
+        } else {
+            data.writeInt(1);
+            options.writeToParcel(data, 0);
+        }
+        mRemote.transact(START_ACTIVITY_FROM_RECENTS_TRANSACTION, data, reply, 0);
+        reply.readException();
+        int result = reply.readInt();
+        reply.recycle();
+        data.recycle();
+        return result;
+    }
     public boolean finishActivity(IBinder token, int resultCode, Intent resultData, boolean finishTask)
             throws RemoteException {
         Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index ac29161..cc13a3b 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -86,6 +86,7 @@
             ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException;
     public boolean startNextMatchingActivity(IBinder callingActivity,
             Intent intent, Bundle options) throws RemoteException;
+    public int startActivityFromRecents(int taskId, Bundle options) throws RemoteException;
     public boolean finishActivity(IBinder token, int code, Intent data, boolean finishTask)
             throws RemoteException;
     public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException;
@@ -756,4 +757,5 @@
     int IS_BG_MEDIA_PLAYING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+226;
     int MEDIA_RESOURCES_RELEASED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+227;
     int NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+228;
+    int START_ACTIVITY_FROM_RECENTS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 229;
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7f97726..d4a3b12 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1364,6 +1364,14 @@
         android:label="@string/permlab_getTasks"
         android:description="@string/permdesc_getTasks" />
 
+    <!-- Allows an application to start a task from a ActivityManager#RecentTaskInfo.
+         @hide -->
+    <permission android:name="android.permission.START_TASKS_FROM_RECENTS"
+        android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+        android:protectionLevel="signature|system"
+        android:label="@string/permlab_startTasksFromRecents"
+        android:description="@string/permdesc_startTasksFromRecents" />
+
     <!-- @SystemApi @hide Allows an application to call APIs that allow it to do interactions
          across the users on the device, using singleton services and
          user-targeted broadcasts.  This permission is not available to
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 0d9da35..b41e37c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -774,6 +774,12 @@
        about currently and recently running tasks.  This may allow the app to
        discover information about which applications are used on the device.</string>
 
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_startTasksFromRecents">start a task from recents</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_startTasksFromRecents">Allows the app to use an ActivityManager.RecentTaskInfo
+        object to launch a defunct task that was returned from ActivityManager.getRecentTaskList().</string>
+
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->
     <string name="permlab_interactAcrossUsers">interact across users</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->