TaskStackBuilder and Activity navigation features for framework

Promote navigation helpers from the support library to the core
platform.

The support library's meta-data element has been replaced with a
first-class parentActivityName attribute. This attribute is valid
on both activity and activity-alias elements. An activity-alias
will inherit the target activity's parentActivityName if one is
not explicitly specified.

Automatic Up navigation for Activities

Add the public method onNavigateUp() to Activity. The default
implementation will use the metadata supplied in the manifest about an
activity's hierarchical parent (parentActivityName) to do the right
thing.

If any activities in the parent chain require special Intent
arguments, the Activity subclass should override onNavigateUp() to
properly implement Up navigation for the app, supplying such arguments
as needed.

If automatic Up navigation within the same task can't find an activity
matching the supplied intent in the current task stack, it will act as
an in-app "home" and return to the root activity (presumably the app's
front page) in that task. (From this state, pressing "back" with
default behavior will return to the launcher.)

Change-Id: If163e27e59587f7af36975a09c986cb117ec3bc6
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 5917cbf..000abc5 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -17,10 +17,10 @@
 package android.app;
 
 import android.content.ComponentName;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.IIntentSender;
-import android.content.IIntentReceiver;
 import android.content.IntentSender;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ConfigurationInfo;
@@ -32,11 +32,11 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Debug;
-import android.os.Parcelable;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
 import android.os.IBinder;
 import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.os.Parcelable;
+import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StrictMode;
 import android.text.TextUtils;
@@ -1605,6 +1605,31 @@
             return true;
         }
 
+        case TARGET_TASK_AFFINITY_MATCHES_ACTIVITY_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            String destAffinity = data.readString();
+            boolean res = targetTaskAffinityMatchesActivity(token, destAffinity);
+            reply.writeNoException();
+            reply.writeInt(res ? 1 : 0);
+            return true;
+        }
+
+        case NAVIGATE_UP_TO_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            Intent target = Intent.CREATOR.createFromParcel(data);
+            int resultCode = data.readInt();
+            Intent resultData = null;
+            if (data.readInt() != 0) {
+                resultData = Intent.CREATOR.createFromParcel(data);
+            }
+            boolean res = navigateUpTo(token, target, resultCode, resultData);
+            reply.writeNoException();
+            reply.writeInt(res ? 1 : 0);
+            return true;
+        }
+
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -3662,5 +3687,42 @@
         reply.recycle();
     }
 
+    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        data.writeString(destAffinity);
+        mRemote.transact(TARGET_TASK_AFFINITY_MATCHES_ACTIVITY_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean result = reply.readInt() != 0;
+        data.recycle();
+        reply.recycle();
+        return result;
+    }
+
+    public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent resultData)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        target.writeToParcel(data, 0);
+        data.writeInt(resultCode);
+        if (resultData != null) {
+            data.writeInt(1);
+            resultData.writeToParcel(data, 0);
+        } else {
+            data.writeInt(0);
+        }
+        mRemote.transact(NAVIGATE_UP_TO_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean result = reply.readInt() != 0;
+        data.recycle();
+        reply.recycle();
+        return result;
+    }
+
     private IBinder mRemote;
 }