Use extra to exclude specific MIME-types for Fast-Track.

This is used so that the header widget can hide the profile
icon when launched while already looking at the profile.

Also fixes http://b/2058751
diff --git a/src/com/android/contacts/BaseContactCardActivity.java b/src/com/android/contacts/BaseContactCardActivity.java
index 441aea1..f123c89 100644
--- a/src/com/android/contacts/BaseContactCardActivity.java
+++ b/src/com/android/contacts/BaseContactCardActivity.java
@@ -36,6 +36,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.RawContacts;
 import android.util.Log;
 import android.util.SparseArray;
@@ -92,10 +93,14 @@
         mContactHeaderWidget = (ContactHeaderWidget) findViewById(R.id.contact_header_widget);
         mContactHeaderWidget.showStar(true);
         mContactHeaderWidget.bindFromContactId(ContentUris.parseId(mUri));
-        mTabWidget = (ScrollingTabWidget) findViewById(R.id.tab_widget);
+        mContactHeaderWidget.setExcludeMimes(new String[] {
+            Contacts.CONTENT_ITEM_TYPE
+        });
 
+        mTabWidget = (ScrollingTabWidget) findViewById(R.id.tab_widget);
         mTabWidget.setTabSelectionListener(this);
         mTabWidget.setVisibility(View.INVISIBLE);
+
         mTabRawContactIdMap = new SparseArray<Long>();
 
         mHandler = new NotifyingAsyncQueryHandler(this, this);
diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index 2eb1ddd..8718b10 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -565,7 +565,7 @@
         mRect.bottom = mRect.top + anchor.getHeight();
 
         mFastTrack.dismiss();
-        mFastTrack.show(contactUri, mRect, Intents.MODE_MEDIUM);
+        mFastTrack.show(contactUri, mRect, Intents.MODE_MEDIUM, null);
     }
 
     /** {@inheritDoc} */
diff --git a/src/com/android/contacts/ShowOrCreateActivity.java b/src/com/android/contacts/ShowOrCreateActivity.java
index 27fce18..e47a556 100755
--- a/src/com/android/contacts/ShowOrCreateActivity.java
+++ b/src/com/android/contacts/ShowOrCreateActivity.java
@@ -166,9 +166,10 @@
 
         // Use requested display mode, defaulting to medium
         final int mode = extras.getInt(Intents.EXTRA_MODE, Intents.MODE_MEDIUM);
+        final String[] excludeMimes = extras.getStringArray(Intents.EXTRA_EXCLUDE_MIMES);
 
         mFastTrack = new FastTrackWindow(this, this);
-        mFastTrack.show(aggUri, targetRect, mode);
+        mFastTrack.show(aggUri, targetRect, mode, excludeMimes);
     }
 
     /** {@inheritDoc} */
diff --git a/src/com/android/contacts/SocialStreamActivity.java b/src/com/android/contacts/SocialStreamActivity.java
index 11f9367..3110e92 100644
--- a/src/com/android/contacts/SocialStreamActivity.java
+++ b/src/com/android/contacts/SocialStreamActivity.java
@@ -150,7 +150,7 @@
         mRect.bottom = mRect.top + anchor.getHeight();
 
         mFastTrack.dismiss();
-        mFastTrack.show(aggUri, mRect, Intents.MODE_MEDIUM);
+        mFastTrack.show(aggUri, mRect, Intents.MODE_MEDIUM, null);
     }
 
     /** {@inheritDoc} */
diff --git a/src/com/android/contacts/ui/FastTrackWindow.java b/src/com/android/contacts/ui/FastTrackWindow.java
index a2e21cb..8551059 100644
--- a/src/com/android/contacts/ui/FastTrackWindow.java
+++ b/src/com/android/contacts/ui/FastTrackWindow.java
@@ -46,6 +46,7 @@
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.CommonDataKinds.Photo;
 import android.provider.SocialContract.Activities;
+import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.Log;
 import android.view.ContextThemeWrapper;
@@ -96,7 +97,6 @@
     }
 
     private final Context mContext;
-    private final PackageManager mPackageManager;
     private final LayoutInflater mInflater;
     private final WindowManager mWindowManager;
     private Window mWindow;
@@ -131,6 +131,8 @@
      */
     private ActionMap mActions = new ActionMap();
 
+    private String[] mExcludeMimes;
+
     /**
      * Specific MIME-type for {@link Phone#CONTENT_ITEM_TYPE} entries that
      * distinguishes actions that should initiate a text message.
@@ -163,7 +165,6 @@
      */
     public FastTrackWindow(Context context) {
         mContext = new ContextThemeWrapper(context, R.style.FastTrack);
-        mPackageManager = context.getPackageManager();
         mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
 
@@ -231,7 +232,7 @@
      * Start showing a fast-track window for the given {@link Contacts#_ID}
      * pointing towards the given location.
      */
-    public void show(Uri aggUri, Rect anchor, int mode) {
+    public void show(Uri aggUri, Rect anchor, int mode, String[] excludeMimes) {
         if (mShowing || mQuerying) {
             Log.w(TAG, "already in process of showing");
             return;
@@ -239,6 +240,7 @@
 
         // Prepare header view for requested mode
         mHeader = getHeaderView(mode);
+        mExcludeMimes = excludeMimes;
 
         setHeaderText(R.id.name, R.string.fasttrack_missing_name);
         setHeaderText(R.id.status, R.string.fasttrack_missing_status);
@@ -552,6 +554,7 @@
         public CharSequence getHeader();
         public CharSequence getBody();
         public Drawable getIcon();
+        public boolean isValid();
 
         /**
          * Build an {@link Intent} that will perform this action.
@@ -573,11 +576,13 @@
         private Intent mIntent;
 
         private boolean mAlternate;
+        private boolean mValidAction;
 
         /**
          * Create an action from common {@link Data} elements.
          */
-        public DataAction(Context context, ContactsSource source, String mimeType, DataKind kind, Cursor cursor) {
+        public DataAction(Context context, ContactsSource source, String mimeType, DataKind kind,
+                Cursor cursor) {
             mContext = context;
             mSource = source;
             mKind = kind;
@@ -597,18 +602,24 @@
             // Handle well-known MIME-types with special care
             if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
                 final String number = getAsString(cursor, Phone.NUMBER);
-                final Uri callUri = Uri.fromParts(SCHEME_TEL, number, null);
-                mIntent = new Intent(Intent.ACTION_DIAL, callUri);
+                if (!TextUtils.isEmpty(number)) {
+                    final Uri callUri = Uri.fromParts(SCHEME_TEL, number, null);
+                    mIntent = new Intent(Intent.ACTION_DIAL, callUri);
+                }
 
             } else if (MIME_SMS_ADDRESS.equals(mimeType)) {
                 final String number = getAsString(cursor, Phone.NUMBER);
-                final Uri smsUri = Uri.fromParts(SCHEME_SMSTO, number, null);
-                mIntent = new Intent(Intent.ACTION_SENDTO, smsUri);
+                if (!TextUtils.isEmpty(number)) {
+                    final Uri smsUri = Uri.fromParts(SCHEME_SMSTO, number, null);
+                    mIntent = new Intent(Intent.ACTION_SENDTO, smsUri);
+                }
 
             } else if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
                 final String address = getAsString(cursor, Email.DATA);
-                final Uri mailUri = Uri.fromParts(SCHEME_MAILTO, address, null);
-                mIntent = new Intent(Intent.ACTION_SENDTO, mailUri);
+                if (!TextUtils.isEmpty(address)) {
+                    final Uri mailUri = Uri.fromParts(SCHEME_MAILTO, address, null);
+                    mIntent = new Intent(Intent.ACTION_SENDTO, mailUri);
+                }
 
             } else {
                 // Otherwise fall back to default VIEW action
@@ -616,6 +627,10 @@
                 final Uri dataUri = ContentUris.withAppendedId(Data.CONTENT_URI, dataId);
                 mIntent = new Intent(Intent.ACTION_VIEW, dataUri);
             }
+
+            // TODO: resolve our created intent to pull correct icon
+            final PackageManager pm = context.getPackageManager();
+            mValidAction = pm.queryIntentActivities(mIntent, 0).size() > 0;
         }
 
         /** {@inheritDoc} */
@@ -633,6 +648,8 @@
             // Bail early if no valid resources
             if (mSource.resPackageName == null) return null;
 
+            // TODO: switch to using ResolveInfo icon instead
+
             final PackageManager pm = mContext.getPackageManager();
             if (mAlternate && mKind.iconAltRes > 0) {
                 return pm.getDrawable(mSource.resPackageName, mKind.iconAltRes, null);
@@ -644,6 +661,11 @@
         }
 
         /** {@inheritDoc} */
+        public boolean isValid() {
+            return mValidAction;
+        }
+
+        /** {@inheritDoc} */
         public Intent getIntent() {
             return mIntent;
         }
@@ -674,6 +696,11 @@
         }
 
         /** {@inheritDoc} */
+        public boolean isValid() {
+            return true;
+        }
+
+        /** {@inheritDoc} */
         public Intent getIntent() {
             final Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, mId);
             return new Intent(Intent.ACTION_VIEW, contactUri);
@@ -704,20 +731,32 @@
     }
 
     /**
+     * Check if the given MIME-type appears in the list of excluded MIME-types
+     * that the most-recent caller requested.
+     */
+    private boolean isMimeExcluded(String mimeType) {
+        if (mExcludeMimes == null) return false;
+        for (String excludedMime : mExcludeMimes) {
+            if (TextUtils.equals(excludedMime, mimeType)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
      * Handle the result from the {@link #TOKEN_DATA} query.
      */
     private void handleData(Cursor cursor) {
         if (cursor == null) return;
 
-        // TODO: turn this into background async instead of blocking ui
-        final Sources sources = Sources.getInstance(mContext);
-
-        {
+        if (!isMimeExcluded(Contacts.CONTENT_ITEM_TYPE)) {
             // Add the profile shortcut action
             final Action action = new ProfileAction(mContext, mAggId);
             mActions.collect(Contacts.CONTENT_ITEM_TYPE, action);
         }
 
+        final Sources sources = Sources.getInstance(mContext);
         final ImageView photoView = (ImageView)mHeader.findViewById(R.id.photo);
 
         while (cursor.moveToNext()) {
@@ -725,6 +764,9 @@
             final String resPackage = getAsString(cursor, Data.RES_PACKAGE);
             final String mimeType = getAsString(cursor, Data.MIMETYPE);
 
+            // Skip this data item if MIME-type excluded
+            if (isMimeExcluded(mimeType)) continue;
+
             // Handle when a photo appears in the various data items
             // TODO: accept a photo only if its marked as primary
             // TODO: move to using photo thumbnail columns, when they exist
@@ -740,7 +782,6 @@
             // TODO: find the ContactsSource for this, either from accountType,
             // or through lazy-loading when resPackage is set, or default.
 
-            // TODO: move source inflation to background thread so we don't block UI
             final ContactsSource source = sources.getInflatedSource(accountType,
                     ContactsSource.LEVEL_MIMETYPES);
             final DataKind kind = source.getKindForMimetype(mimeType);
@@ -786,9 +827,7 @@
      * {@link Action#getIntent()}.
      */
     private void considerAdd(Action action, String mimeType) {
-        final Intent intent = action.getIntent();
-        final boolean intentHandled = mPackageManager.queryIntentActivities(intent, 0).size() > 0;
-        if (intentHandled) {
+        if (action.isValid()) {
             mActions.collect(mimeType, action);
         }
     }
@@ -1002,26 +1041,11 @@
     }
 
     /** {@inheritDoc} */
-    public void onDeleteComplete(int token, Object cookie, int result) {
-        // No actions
-    }
-
-    /** {@inheritDoc} */
-    public void onInsertComplete(int token, Object cookie, Uri uri) {
-        // No actions
-    }
-
-    /** {@inheritDoc} */
     public void onQueryEntitiesComplete(int token, Object cookie, EntityIterator iterator) {
         // No actions
     }
 
     /** {@inheritDoc} */
-    public void onUpdateComplete(int token, Object cookie, int result) {
-        // No actions
-    }
-
-    /** {@inheritDoc} */
     public void onAttachedToWindow() {
         // No actions
     }