Navigation adjustment for updated design guidelines and QuickContact cards

Bug 6362611

Change QuickContactActivity to task affinity "" to keep it from starting
orphaned/confused tasks.

Launch ContactDetailActivity in the same task from QuickContactActivity.

Launch app-supplied intents from QuickContactActivity in the same task.

Clear the QuickContactActivity task when launching it from a launcher
shortcut or widget. This prevents activities launched from the
finished QuickContactActivity from hanging around as the root and
failing to be reset.

Remove app-specific Up navigation code from ContactDetailActivity and
let the JB framework handle it automatically.

Change-Id: I4abebcb135b2d3269039b3307a49115c13528295
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a1f8b4a..56c7b9f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -407,7 +407,7 @@
             android:launchMode="singleTop"
             android:excludeFromRecents="true"
             android:noHistory="true"
-            android:taskAffinity="android.task.quickcontact"
+            android:taskAffinity=""
             android:windowSoftInputMode="stateUnchanged">
 
             <intent-filter>
@@ -474,7 +474,8 @@
         <!-- Views the details of a single contact -->
         <activity android:name=".activities.ContactDetailActivity"
             android:label="@string/viewContactTitle"
-            android:theme="@style/DetailActivityTheme">
+            android:theme="@style/DetailActivityTheme"
+            android:parentActivityName=".activities.PeopleActivity">
 
             <intent-filter android:label="@string/viewContactDesription">
                 <action android:name="android.intent.action.VIEW" />
diff --git a/src/com/android/contacts/activities/ContactDetailActivity.java b/src/com/android/contacts/activities/ContactDetailActivity.java
index ea9e116..1ccf32c 100644
--- a/src/com/android/contacts/activities/ContactDetailActivity.java
+++ b/src/com/android/contacts/activities/ContactDetailActivity.java
@@ -57,17 +57,8 @@
     /** Shows a toogle button for hiding/showing updates. Don't submit with true */
     private static final boolean DEBUG_TRANSITIONS = false;
 
-    /**
-     * Boolean intent key that specifies whether pressing the "up" affordance in this activity
-     * should cause it to finish itself or launch an intent to bring the user back to a specific
-     * parent activity - the {@link PeopleActivity}.
-     */
-    public static final String INTENT_KEY_FINISH_ACTIVITY_ON_UP_SELECTED =
-            "finishActivityOnUpSelected";
-
     private ContactLoader.Result mContactData;
     private Uri mLookupUri;
-    private boolean mFinishActivityOnUpSelected;
 
     private ContactDetailLayoutController mContactDetailLayoutController;
     private ContactLoaderFragment mLoaderFragment;
@@ -94,9 +85,6 @@
             return;
         }
 
-        mFinishActivityOnUpSelected = getIntent().getBooleanExtra(
-                INTENT_KEY_FINISH_ACTIVITY_ON_UP_SELECTED, false);
-
         setContentView(R.layout.contact_detail_activity);
 
         mContactDetailLayoutController = new ContactDetailLayoutController(this, savedState,
@@ -309,24 +297,4 @@
          */
         public boolean handleKeyDown(int keyCode);
     }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-
-        switch (item.getItemId()) {
-            case android.R.id.home:
-                if (mFinishActivityOnUpSelected) {
-                    finish();
-                    return true;
-                }
-                Intent intent = new Intent(this, PeopleActivity.class);
-                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-                startActivity(intent);
-                finish();
-                return true;
-            default:
-                break;
-        }
-        return super.onOptionsItemSelected(item);
-    }
 }
diff --git a/src/com/android/contacts/activities/GroupDetailActivity.java b/src/com/android/contacts/activities/GroupDetailActivity.java
index 6c36b5d..6562278 100644
--- a/src/com/android/contacts/activities/GroupDetailActivity.java
+++ b/src/com/android/contacts/activities/GroupDetailActivity.java
@@ -106,7 +106,6 @@
         @Override
         public void onContactSelected(Uri contactUri) {
             Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
-            intent.putExtra(ContactDetailActivity.INTENT_KEY_FINISH_ACTIVITY_ON_UP_SELECTED, true);
             startActivity(intent);
         }
 
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 95e7d3b..0283e06 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -1056,12 +1056,6 @@
                 setupContactDetailFragment(contactLookupUri);
             } else {
                 Intent intent = new Intent(Intent.ACTION_VIEW, contactLookupUri);
-                // In search mode, the "up" affordance in the contact detail page should return the
-                // user to the search results, so finish the activity when that button is selected.
-                if (mActionBarAdapter.isSearchMode()) {
-                    intent.putExtra(
-                            ContactDetailActivity.INTENT_KEY_FINISH_ACTIVITY_ON_UP_SELECTED, true);
-                }
                 startActivity(intent);
             }
         }
diff --git a/src/com/android/contacts/list/ShortcutIntentBuilder.java b/src/com/android/contacts/list/ShortcutIntentBuilder.java
index 1be0b74..6c593b0 100644
--- a/src/com/android/contacts/list/ShortcutIntentBuilder.java
+++ b/src/com/android/contacts/list/ShortcutIntentBuilder.java
@@ -248,15 +248,18 @@
         Intent shortcutIntent;
         // This is a simple shortcut to view a contact.
         shortcutIntent = new Intent(ContactsContract.QuickContact.ACTION_QUICK_CONTACT);
-        shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
-                Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+
+        // When starting from the launcher, start in a new, cleared task.
+        // CLEAR_WHEN_TASK_RESET cannot reset the root of a task, so we
+        // clear the whole thing preemptively here since QuickContactActivity will
+        // finish itself when launching other detail activities.
+        shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
 
         shortcutIntent.setData(contactUri);
         shortcutIntent.putExtra(ContactsContract.QuickContact.EXTRA_MODE,
                 ContactsContract.QuickContact.MODE_LARGE);
         shortcutIntent.putExtra(ContactsContract.QuickContact.EXTRA_EXCLUDE_MIMES,
                 (String[]) null);
-        shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
 
         final Bitmap icon = generateQuickContactIcon(bitmap);
 
diff --git a/src/com/android/contacts/quickcontact/DataAction.java b/src/com/android/contacts/quickcontact/DataAction.java
index 6728913..45565a1 100644
--- a/src/com/android/contacts/quickcontact/DataAction.java
+++ b/src/com/android/contacts/quickcontact/DataAction.java
@@ -224,13 +224,7 @@
             mIntent.setDataAndType(mDataUri, mimeType);
         }
 
-        // Always launch as new task, since we're like a launcher
-        setCommonIntentFlags(mIntent);
-        if (mAlternateIntent != null) setCommonIntentFlags(mAlternateIntent);
-    }
-
-    private static void setCommonIntentFlags(Intent intent) {
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        mIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
     }
 
     @Override
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 81aa2e8..7087167 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -31,6 +31,7 @@
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.LoaderManager.LoaderCallbacks;
+import android.app.TaskStackBuilder;
 import android.content.ActivityNotFoundException;
 import android.content.ContentUris;
 import android.content.ContentValues;
@@ -180,8 +181,8 @@
             @Override
             public void onClick(View v) {
                 final Intent intent = new Intent(Intent.ACTION_VIEW, mLookupUri);
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                 mContactLoader.cacheResult();
+                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                 startActivity(intent);
                 hide(false);
             }
diff --git a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
index afc88af..38dac60 100644
--- a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
+++ b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
@@ -147,9 +147,12 @@
 
             // OnClick launch QuickContact
             final Intent intent = new Intent(QuickContact.ACTION_QUICK_CONTACT);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_CLEAR_TOP
-                    | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+
+            // When starting from the launcher, start in a new, cleared task.
+            // CLEAR_WHEN_TASK_RESET cannot reset the root of a task, so we
+            // clear the whole thing preemptively here since QuickContactActivity will
+            // finish itself when launching other detail activities.
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
 
             intent.setData(contactData.getLookupUri());
             intent.putExtra(QuickContact.EXTRA_MODE, QuickContact.MODE_SMALL);