Moving contact starring to the service.

Also, cleaning up some internal API.

Change-Id: I5bd2c5e24413f4e9ea538757ab05c85885f8533e
diff --git a/src/com/android/contacts/activities/ContactBrowserActivity.java b/src/com/android/contacts/activities/ContactBrowserActivity.java
index 95bf872..8491e35 100644
--- a/src/com/android/contacts/activities/ContactBrowserActivity.java
+++ b/src/com/android/contacts/activities/ContactBrowserActivity.java
@@ -626,7 +626,8 @@
             Toast.makeText(ContactBrowserActivity.this, R.string.toast_making_personal_copy,
                     Toast.LENGTH_LONG).show();
             Intent serviceIntent = ContactSaveService.createNewRawContactIntent(
-                    ContactBrowserActivity.this, values, account);
+                    ContactBrowserActivity.this, values, account,
+                    ContactBrowserActivity.class, Intent.ACTION_VIEW);
             startService(serviceIntent);
         }
     }
diff --git a/src/com/android/contacts/activities/ContactDetailActivity.java b/src/com/android/contacts/activities/ContactDetailActivity.java
index f593a0d..b86eae4 100644
--- a/src/com/android/contacts/activities/ContactDetailActivity.java
+++ b/src/com/android/contacts/activities/ContactDetailActivity.java
@@ -130,7 +130,8 @@
             Toast.makeText(ContactDetailActivity.this, R.string.toast_making_personal_copy,
                     Toast.LENGTH_LONG).show();
             Intent serviceIntent = ContactSaveService.createNewRawContactIntent(
-                    ContactDetailActivity.this, values, account);
+                    ContactDetailActivity.this, values, account,
+                    ContactDetailActivity.class, Intent.ACTION_VIEW);
             startService(serviceIntent);
 
         }
diff --git a/src/com/android/contacts/interactions/GroupCreationDialogFragment.java b/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
index 9f1ad15..70ba04f 100644
--- a/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
+++ b/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
@@ -19,7 +19,9 @@
 import com.android.contacts.views.ContactSaveService;
 
 import android.accounts.Account;
+import android.app.Activity;
 import android.app.FragmentManager;
+import android.content.Intent;
 import android.os.Bundle;
 import android.widget.EditText;
 
@@ -55,7 +57,9 @@
         String accountType = arguments.getString(ARG_ACCOUNT_TYPE);
         String accountName = arguments.getString(ARG_ACCOUNT_NAME);
 
-        getActivity().startService(ContactSaveService.createNewGroupIntent(
-                getActivity(), new Account(accountName, accountType), groupLabel));
+        Activity activity = getActivity();
+        activity.startService(ContactSaveService.createNewGroupIntent(activity,
+                new Account(accountName, accountType), groupLabel,
+                activity.getClass(), Intent.ACTION_EDIT));
     }
 }
diff --git a/src/com/android/contacts/views/ContactSaveService.java b/src/com/android/contacts/views/ContactSaveService.java
index 4083a4e..16daaed 100644
--- a/src/com/android/contacts/views/ContactSaveService.java
+++ b/src/com/android/contacts/views/ContactSaveService.java
@@ -20,20 +20,18 @@
 import com.google.android.collect.Sets;
 
 import android.accounts.Account;
-import android.app.Activity;
 import android.app.IntentService;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
+import android.content.Context;
 import android.content.Intent;
-import android.content.OperationApplicationException;
 import android.net.Uri;
-import android.os.Parcelable;
-import android.os.RemoteException;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.Groups;
 import android.provider.ContactsContract.RawContacts;
@@ -61,6 +59,10 @@
     public static final String EXTRA_GROUP_ID = "groupId";
     public static final String EXTRA_GROUP_LABEL = "groupLabel";
 
+    public static final String ACTION_SET_STARRED = "setStarred";
+    public static final String EXTRA_CONTACT_URI = "contactUri";
+    public static final String EXTRA_STARRED_FLAG = "starred";
+
     private static final HashSet<String> ALLOWED_DATA_COLUMNS = Sets.newHashSet(
         Data.MIMETYPE,
         Data.IS_PRIMARY,
@@ -97,11 +99,39 @@
             renameGroup(intent);
         } else if (ACTION_DELETE_GROUP.equals(action)) {
             deleteGroup(intent);
-        } else {
-            performContentProviderOperations(intent);
+        } else if (ACTION_SET_STARRED.equals(action)) {
+            setStarred(intent);
         }
     }
 
+    /**
+     * Creates an intent that can be sent to this service to create a new raw contact
+     * using data presented as a set of ContentValues.
+     */
+    public static Intent createNewRawContactIntent(Context context,
+            ArrayList<ContentValues> values, Account account, Class<?> callbackActivity,
+            String callbackAction) {
+        Intent serviceIntent = new Intent(
+                context, ContactSaveService.class);
+        serviceIntent.setAction(ContactSaveService.ACTION_NEW_RAW_CONTACT);
+        if (account != null) {
+            serviceIntent.putExtra(ContactSaveService.EXTRA_ACCOUNT_NAME, account.name);
+            serviceIntent.putExtra(ContactSaveService.EXTRA_ACCOUNT_TYPE, account.type);
+        }
+        serviceIntent.putParcelableArrayListExtra(
+                ContactSaveService.EXTRA_CONTENT_VALUES, values);
+
+        // Callback intent will be invoked by the service once the new contact is
+        // created.  The service will put the URI of the new contact as "data" on
+        // the callback intent.
+        Intent callbackIntent = new Intent(context, callbackActivity);
+        callbackIntent.setAction(callbackAction);
+        callbackIntent.setFlags(
+                Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+        serviceIntent.putExtra(ContactSaveService.EXTRA_CALLBACK_INTENT, callbackIntent);
+        return serviceIntent;
+    }
+
     private void createRawContact(Intent intent) {
         String accountName = intent.getStringExtra(EXTRA_ACCOUNT_NAME);
         String accountType = intent.getStringExtra(EXTRA_ACCOUNT_TYPE);
@@ -138,49 +168,26 @@
         startActivity(callbackIntent);
     }
 
-    private void performContentProviderOperations(Intent intent) {
-        final Parcelable[] operationsArray = intent.getParcelableArrayExtra(EXTRA_OPERATIONS);
-
-        // We have to cast each item individually here
-        final ArrayList<ContentProviderOperation> operations =
-                new ArrayList<ContentProviderOperation>(operationsArray.length);
-        for (Parcelable p : operationsArray) {
-            operations.add((ContentProviderOperation) p);
-        }
-
-        try {
-            getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error saving", e);
-        } catch (OperationApplicationException e) {
-            Log.e(TAG, "Error saving", e);
-        }
-    }
-
     /**
-     * Creates an intent that can be sent to this service to create a new raw contact
-     * using data presented as a set of ContentValues.
+     * Creates an intent that can be sent to this service to create a new group.
      */
-    public static Intent createNewRawContactIntent(
-            Activity activity, ArrayList<ContentValues> values, Account account) {
-        Intent serviceIntent = new Intent(
-                activity, ContactSaveService.class);
-        serviceIntent.setAction(ContactSaveService.ACTION_NEW_RAW_CONTACT);
-        if (account != null) {
-            serviceIntent.putExtra(ContactSaveService.EXTRA_ACCOUNT_NAME, account.name);
-            serviceIntent.putExtra(ContactSaveService.EXTRA_ACCOUNT_TYPE, account.type);
-        }
-        serviceIntent.putParcelableArrayListExtra(
-                ContactSaveService.EXTRA_CONTENT_VALUES, values);
+    public static Intent createNewGroupIntent(Context context, Account account, String label,
+            Class<?> callbackActivity, String callbackAction) {
+        Intent serviceIntent = new Intent(context, ContactSaveService.class);
+        serviceIntent.setAction(ContactSaveService.ACTION_CREATE_GROUP);
+        serviceIntent.putExtra(ContactSaveService.EXTRA_ACCOUNT_TYPE, account.type);
+        serviceIntent.putExtra(ContactSaveService.EXTRA_ACCOUNT_NAME, account.name);
+        serviceIntent.putExtra(ContactSaveService.EXTRA_GROUP_LABEL, label);
 
-        // Callback intent will be invoked by the service once the new contact is
-        // created.  The service will put the URI of the new contact as "data" on
-        // the callback intent.
-        Intent callbackIntent = new Intent(activity, activity.getClass());
-        callbackIntent.setAction(Intent.ACTION_VIEW);
+        // Callback intent will be invoked by the service once the new group is
+        // created.  The service will put a group membership row in the extras
+        // of the callback intent.
+        Intent callbackIntent = new Intent(context, callbackActivity);
+        callbackIntent.setAction(callbackAction);
         callbackIntent.setFlags(
                 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
         serviceIntent.putExtra(ContactSaveService.EXTRA_CALLBACK_INTENT, callbackIntent);
+
         return serviceIntent;
     }
 
@@ -210,23 +217,13 @@
     }
 
     /**
-     * Creates an intent that can be sent to this service to create a new group.
+     * Creates an intent that can be sent to this service to rename a group.
      */
-    public static Intent createNewGroupIntent(Activity activity, Account account, String label) {
-        Intent serviceIntent = new Intent(activity, ContactSaveService.class);
-        serviceIntent.setAction(ContactSaveService.ACTION_CREATE_GROUP);
-        serviceIntent.putExtra(ContactSaveService.EXTRA_ACCOUNT_TYPE, account.type);
-        serviceIntent.putExtra(ContactSaveService.EXTRA_ACCOUNT_NAME, account.name);
-        serviceIntent.putExtra(ContactSaveService.EXTRA_GROUP_LABEL, label);
-
-        // Callback intent will be invoked by the service once the new group is
-        // created.  The service will put a group membership row in the extras
-        // of the callback intent.
-        Intent callbackIntent = new Intent(activity, activity.getClass());
-        callbackIntent.setAction(Intent.ACTION_EDIT);
-        callbackIntent.setFlags(
-                Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
-        serviceIntent.putExtra(ContactSaveService.EXTRA_CALLBACK_INTENT, callbackIntent);
+    public static Intent createGroupRenameIntent(Context context, long groupId, String newLabel) {
+        Intent serviceIntent = new Intent(context, ContactSaveService.class);
+        serviceIntent.setAction(ContactSaveService.ACTION_RENAME_GROUP);
+        serviceIntent.putExtra(ContactSaveService.EXTRA_GROUP_ID, groupId);
+        serviceIntent.putExtra(ContactSaveService.EXTRA_GROUP_LABEL, newLabel);
         return serviceIntent;
     }
 
@@ -246,13 +243,12 @@
     }
 
     /**
-     * Creates an intent that can be sent to this service to rename a group.
+     * Creates an intent that can be sent to this service to delete a group.
      */
-    public static Intent createGroupRenameIntent(Activity activity, long groupId, String newLabel) {
-        Intent serviceIntent = new Intent(activity, ContactSaveService.class);
-        serviceIntent.setAction(ContactSaveService.ACTION_RENAME_GROUP);
+    public static Intent createGroupDeletionIntent(Context context, long groupId) {
+        Intent serviceIntent = new Intent(context, ContactSaveService.class);
+        serviceIntent.setAction(ContactSaveService.ACTION_DELETE_GROUP);
         serviceIntent.putExtra(ContactSaveService.EXTRA_GROUP_ID, groupId);
-        serviceIntent.putExtra(ContactSaveService.EXTRA_GROUP_LABEL, newLabel);
         return serviceIntent;
     }
 
@@ -268,12 +264,28 @@
     }
 
     /**
-     * Creates an intent that can be sent to this service to delete a group.
+     * Creates an intent that can be sent to this service to star or un-star a contact.
      */
-    public static Intent createGroupDeletionIntent(Activity activity, long groupId) {
-        Intent serviceIntent = new Intent(activity, ContactSaveService.class);
-        serviceIntent.setAction(ContactSaveService.ACTION_DELETE_GROUP);
-        serviceIntent.putExtra(ContactSaveService.EXTRA_GROUP_ID, groupId);
+    public static Intent createSetStarredIntent(Context context, Uri contactUri, boolean value) {
+        Intent serviceIntent = new Intent(context, ContactSaveService.class);
+        serviceIntent.setAction(ContactSaveService.ACTION_SET_STARRED);
+        serviceIntent.putExtra(ContactSaveService.EXTRA_CONTACT_URI, contactUri);
+        serviceIntent.putExtra(ContactSaveService.EXTRA_STARRED_FLAG, value);
+
         return serviceIntent;
     }
+
+    private void setStarred(Intent intent) {
+        Uri contactUri = intent.getParcelableExtra(EXTRA_CONTACT_URI);
+        boolean value = intent.getBooleanExtra(EXTRA_STARRED_FLAG, false);
+        if (contactUri == null) {
+            Log.e(TAG, "Invalid arguments for setStarred request");
+            return;
+        }
+
+        final ContentValues values = new ContentValues(1);
+        values.put(Contacts.STARRED, value);
+        getContentResolver().update(contactUri, values, null, null);
+
+    }
 }
diff --git a/src/com/android/contacts/views/detail/ContactDetailHeaderView.java b/src/com/android/contacts/views/detail/ContactDetailHeaderView.java
index 71d0962..4a00f3a 100644
--- a/src/com/android/contacts/views/detail/ContactDetailHeaderView.java
+++ b/src/com/android/contacts/views/detail/ContactDetailHeaderView.java
@@ -20,16 +20,17 @@
 import com.android.contacts.util.ContactBadgeUtil;
 import com.android.contacts.views.ContactLoader;
 import com.android.contacts.views.ContactLoader.Result;
+import com.android.contacts.views.ContactSaveService;
 
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Entity;
 import android.content.Entity.NamedContentValues;
+import android.content.Intent;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.net.Uri;
 import android.provider.ContactsContract.CommonDataKinds.Organization;
-import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.DisplayNameSources;
 import android.text.TextUtils;
@@ -296,10 +297,9 @@
                 // Toggle "starred" state
                 // Make sure there is a contact
                 if (mContactUri != null) {
-                    // TODO: This should be done in the background
-                    final ContentValues values = new ContentValues(1);
-                    values.put(Contacts.STARRED, mStarredView.isChecked());
-                    mContext.getContentResolver().update(mContactUri, values, null, null);
+                    Intent intent = ContactSaveService.createSetStarredIntent(
+                            getContext(), mContactUri, mStarredView.isChecked());
+                    getContext().startService(intent);
                 }
                 break;
             }