Allow EditContactActivity to use a picker

Few fixes... when creating a contact, it returns to the List.  The list converts
the raw_contact into a contact and returns that (same as if you selected a contact).

Then changed AttachImage to use the new style of contacts.

Bug: 2092559
diff --git a/src/com/android/contacts/AttachImage.java b/src/com/android/contacts/AttachImage.java
index 8c91722..fd820e2 100644
--- a/src/com/android/contacts/AttachImage.java
+++ b/src/com/android/contacts/AttachImage.java
@@ -17,12 +17,16 @@
 package com.android.contacts;
 
 import android.app.Activity;
+import android.content.ContentUris;
+import android.content.ContentValues;
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Bundle;
-import android.provider.Contacts;
-import android.provider.Contacts.People;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.widget.Toast;
 
 import java.io.ByteArrayOutputStream;
 
@@ -42,6 +46,9 @@
 
     }
 
+    /**
+     * Is the raw_contact uri for the contact the user selected
+     */
     Uri mContactUri;
 
     @Override
@@ -52,7 +59,7 @@
             mContactUri = icicle.getParcelable(CONTACT_URI_KEY);
         } else {
             Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
-            intent.setType(People.CONTENT_ITEM_TYPE);
+            intent.setType(Contacts.CONTENT_ITEM_TYPE);
             startActivityForResult(intent, REQUEST_PICK_CONTACT);
         }
     }
@@ -74,7 +81,6 @@
         }
 
         if (requestCode == REQUEST_PICK_CONTACT) {
-            mContactUri = result.getData();
             // A contact was picked. Launch the cropper to get face detection, the right size, etc.
             // TODO: get these values from constants somewhere
             Intent myIntent = getIntent();
@@ -89,6 +95,20 @@
             intent.putExtra("outputY", 96);
             intent.putExtra("return-data", true);
             startActivityForResult(intent, REQUEST_CROP_PHOTO);
+
+            // while they're cropping, convert the contact into a raw_contact
+            final long contactId = ContentUris.parseId(result.getData());
+            final long rawContactId = ContactsUtils.queryForRawContactId(getContentResolver(),
+                    contactId);
+
+            if (rawContactId == -1) {
+                Toast.makeText(this, R.string.contactSavedErrorToast, Toast.LENGTH_LONG).show();
+            }
+
+            mContactUri = Uri.withAppendedPath(
+                    ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
+                    RawContacts.Data.CONTENT_DIRECTORY);
+
         } else if (requestCode == REQUEST_CROP_PHOTO) {
             final Bundle extras = result.getExtras();
             if (extras != null) {
@@ -96,8 +116,12 @@
                 if (photo != null) {
                     ByteArrayOutputStream stream = new ByteArrayOutputStream();
                     photo.compress(Bitmap.CompressFormat.JPEG, 75, stream);
-                    Contacts.People.setPhotoData(getContentResolver(), mContactUri,
-                            stream.toByteArray());
+
+                    final ContentValues imageValues = new ContentValues();
+                    imageValues.put(Photo.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
+                    imageValues.put(Photo.PHOTO, stream.toByteArray());
+                    imageValues.put(RawContacts.Data.IS_SUPER_PRIMARY, 1);
+                    getContentResolver().insert(mContactUri, imageValues);
                 }
             }
             finish();
diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index 5e8519e..52470a3 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -294,6 +294,8 @@
 
     private static final int QUERY_TOKEN = 42;
 
+    static final String KEY_PICKER_MODE = "picker_mode";
+
     private ContactItemListAdapter mAdapter;
 
     int mMode = MODE_DEFAULT;
@@ -878,7 +880,6 @@
         switch (requestCode) {
             case SUBACTIVITY_NEW_CONTACT:
                 if (resultCode == RESULT_OK) {
-                    // Contact was created, pass it back
                     returnPickerResult(null, data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME),
                             data.getData(), 0);
                 }
@@ -1040,7 +1041,6 @@
         if (mMode == MODE_INSERT_OR_EDIT_CONTACT) {
             Intent intent;
             if (position == 0) {
-                // Insert
                 intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
             } else {
                 // Edit
@@ -1048,10 +1048,14 @@
                 intent = new Intent(Intent.ACTION_EDIT, uri);
             }
             intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
-            final Bundle extras = getIntent().getExtras();
-            if (extras != null) {
-                intent.putExtras(extras);
+            Bundle extras = getIntent().getExtras();
+
+            if (extras == null) {
+                extras = new Bundle();
             }
+            intent.putExtras(extras);
+            extras.putBoolean(KEY_PICKER_MODE, (mMode & MODE_MASK_PICKER) == MODE_MASK_PICKER);
+
             startActivity(intent);
             finish();
         } else if (id != -1) {
@@ -1094,9 +1098,8 @@
             }
         } else if ((mMode & MODE_MASK_CREATE_NEW) == MODE_MASK_CREATE_NEW
                 && position == 0) {
-            // TODO: Hook this up to new edit contact activity (bug 2092559)
-            /*Intent newContact = new Intent(Intents.Insert.ACTION, People.CONTENT_URI);
-            startActivityForResult(newContact, SUBACTIVITY_NEW_CONTACT);*/
+            Intent newContact = new Intent(Intents.Insert.ACTION, Contacts.CONTENT_URI);
+            startActivityForResult(newContact, SUBACTIVITY_NEW_CONTACT);
         } else {
             signalError();
         }
diff --git a/src/com/android/contacts/model/EntitySet.java b/src/com/android/contacts/model/EntitySet.java
index 18afd2b..75c9dc3 100644
--- a/src/com/android/contacts/model/EntitySet.java
+++ b/src/com/android/contacts/model/EntitySet.java
@@ -160,7 +160,7 @@
      * existing {@link RawContacts#_ID} value. Usually used when creating
      * {@link AggregationExceptions} during an update.
      */
-    protected long findRawContactId() {
+    public long findRawContactId() {
         for (EntityDelta delta : this) {
             final Long rawContactId = delta.getValues().getAsLong(RawContacts._ID);
             if (rawContactId != null && rawContactId >= 0) {
diff --git a/src/com/android/contacts/ui/EditContactActivity.java b/src/com/android/contacts/ui/EditContactActivity.java
index d9ae717..843615a 100644
--- a/src/com/android/contacts/ui/EditContactActivity.java
+++ b/src/com/android/contacts/ui/EditContactActivity.java
@@ -16,31 +16,14 @@
 
 package com.android.contacts.ui;
 
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.ScrollingTabWidget;
-import com.android.contacts.ViewContactActivity;
-import com.android.contacts.model.ContactsSource;
-import com.android.contacts.model.Editor;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityModifier;
-import com.android.contacts.model.EntitySet;
-import com.android.contacts.model.HardCodedSources;
-import com.android.contacts.model.Sources;
-import com.android.contacts.model.Editor.EditorListener;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.ui.widget.ContactEditorView;
-import com.android.contacts.util.EmptyService;
-import com.android.contacts.util.WeakAsyncTask;
-import com.android.internal.widget.ContactHeaderWidget;
-import com.google.android.collect.Lists;
-
 import android.accounts.Account;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
+import android.app.ProgressDialog;
 import android.content.ActivityNotFoundException;
 import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
@@ -74,10 +57,27 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
+import com.google.android.collect.Lists;
+
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+import com.android.contacts.ScrollingTabWidget;
+import com.android.contacts.model.ContactsSource;
+import com.android.contacts.model.Editor;
+import com.android.contacts.model.EntityDelta;
+import com.android.contacts.model.EntityModifier;
+import com.android.contacts.model.EntitySet;
+import com.android.contacts.model.HardCodedSources;
+import com.android.contacts.model.Sources;
+import com.android.contacts.model.Editor.EditorListener;
+import com.android.contacts.model.EntityDelta.ValuesDelta;
+import com.android.contacts.ui.widget.ContactEditorView;
+import com.android.contacts.util.EmptyService;
+import com.android.contacts.util.WeakAsyncTask;
+import com.android.internal.widget.ContactHeaderWidget;
+
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
 
 /**
  * Activity for editing or inserting a contact.
@@ -493,19 +493,6 @@
         return false;
     }
 
-
-
-
-
-
-
-
-
-
-
-
-
-
     /**
      * Background task for persisting edited contact data, using the changes
      * defined by a set of {@link EntityDelta}. This task starts
@@ -520,6 +507,10 @@
         private static final int RESULT_SUCCESS = 1;
         private static final int RESULT_FAILURE = 2;
 
+        private long mSavedId;
+
+        private WeakReference<ProgressDialog> progress;
+
         public PersistTask(EditContactActivity target) {
             super(target);
         }
@@ -527,6 +518,9 @@
         /** {@inheritDoc} */
         @Override
         protected void onPreExecute(EditContactActivity target) {
+            this.progress = new WeakReference<ProgressDialog>(ProgressDialog.show(target, null,
+                    target.getText(R.string.savingContact)));
+
             // Before starting this task, start an empty service to protect our
             // process from being reclaimed by the system.
             final Context context = target;
@@ -552,7 +546,21 @@
                 try {
                     // Build operations and try applying
                     final ArrayList<ContentProviderOperation> diff = state.buildDiff();
-                    resolver.applyBatch(ContactsContract.AUTHORITY, diff);
+                    ContentProviderResult[] results;
+                    if (!diff.isEmpty()) {
+                         results = resolver.applyBatch(ContactsContract.AUTHORITY, diff);
+                         Intent intent = new Intent();
+                         final long rawContactId = getRawContactId(state, diff, results);
+                         final Uri rawContactUri = ContentUris.withAppendedId(
+                                 RawContacts.CONTENT_URI, rawContactId);
+
+                         // convert the raw contact URI to a contact URI
+                         final Uri contactLookupUri = RawContacts.getContactLookupUri(resolver,
+                                 rawContactUri);
+                         intent.setData(contactLookupUri);
+                         target.setResult(RESULT_OK, intent);
+                         target.finish();
+                    }
                     result = (diff.size() > 0) ? RESULT_SUCCESS : RESULT_UNCHANGED;
                     break;
 
@@ -574,6 +582,27 @@
             return result;
         }
 
+        private long getRawContactId(EntitySet state,
+                final ArrayList<ContentProviderOperation> diff,
+                final ContentProviderResult[] results) {
+            long rawContactId = state.findRawContactId();
+            if (rawContactId != -1) {
+                return rawContactId;
+            }
+
+            // we gotta do some searching for the id
+            final int diffSize = diff.size();
+            for (int i = 0; i < diffSize; i++) {
+                ContentProviderOperation operation = diff.get(i);
+                if (operation.getType() == ContentProviderOperation.TYPE_INSERT
+                        && operation.getUri().getEncodedPath().contains(
+                                RawContacts.CONTENT_URI.getEncodedPath())) {
+                    return ContentUris.parseId(results[i].uri);
+                }
+            }
+            return -1;
+        }
+
         /** {@inheritDoc} */
         @Override
         protected void onPostExecute(EditContactActivity target, Integer result) {
@@ -585,48 +614,23 @@
                 Toast.makeText(context, R.string.contactSavedErrorToast, Toast.LENGTH_LONG).show();
             }
 
+            progress.get().dismiss();
+            target.finish();
             // Stop the service that was protecting us
             context.stopService(new Intent(context, EmptyService.class));
         }
     }
 
     /**
-     * Timeout for a {@link PersistTask} running on a background thread. This is
-     * just shorter than the ANR timeout, so that we hold off user interaction
-     * as long as possible.
-     */
-    private static final long TIMEOUT_PERSIST = 4000;
-
-    /**
      * Saves or creates the contact based on the mode, and if successful
      * finishes the activity.
      */
     private boolean doSaveAction() {
         if (!hasValidState()) return false;
 
-        // Pass back last-selected contact
-        final Long rawContactId = this.getSelectedRawContactId();
-        if (rawContactId != null) {
-            final Intent intent = new Intent();
-            intent.putExtra(ViewContactActivity.RAW_CONTACT_ID_EXTRA, (long)rawContactId);
-            setResult(RESULT_OK, intent);
-        }
+        final PersistTask task = new PersistTask(this);
+        task.execute(mState);
 
-        try {
-            final PersistTask task = new PersistTask(this);
-            task.execute(mState);
-            task.get(TIMEOUT_PERSIST, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            // Ignore when someone cancels the operation
-        } catch (TimeoutException e) {
-            // Ignore when task is taking too long
-        } catch (ExecutionException e) {
-            // Important exceptions are handled on remote thread
-        }
-
-        // Persisting finished, or we timed out waiting on it. Either way,
-        // finish this activity, the background task will keep running.
-        this.finish();
         return true;
     }