Add SelectAccountActivity and make vCard importer use it.

Change-Id: Id7b39c82b506e90775bd4e0fada0045c11fccfd1
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0994728..23e7cb0 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -495,6 +495,9 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".SelectAccountActivity"
+            android:theme="@style/BackgroundOnly" />
+
         <service
             android:name=".ImportVCardService"
             android:exported="false" />
diff --git a/src/com/android/contacts/ImportVCardActivity.java b/src/com/android/contacts/ImportVCardActivity.java
index 2346467..7ad9228 100644
--- a/src/com/android/contacts/ImportVCardActivity.java
+++ b/src/com/android/contacts/ImportVCardActivity.java
@@ -21,19 +21,15 @@
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.ProgressDialog;
-import android.app.Service;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.ServiceConnection;
 import android.content.DialogInterface.OnCancelListener;
 import android.content.DialogInterface.OnClickListener;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.PowerManager;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
@@ -55,33 +51,11 @@
 import java.util.Set;
 import java.util.Vector;
 
-class VCardFile {
-    private String mName;
-    private String mCanonicalPath;
-    private long mLastModified;
 
-    public VCardFile(String name, String canonicalPath, long lastModified) {
-        mName = name;
-        mCanonicalPath = canonicalPath;
-        mLastModified = lastModified;
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public String getCanonicalPath() {
-        return mCanonicalPath;
-    }
-
-    public long getLastModified() {
-        return mLastModified;
-    }
-}
 
 /**
- * Class for importing vCard. Several user interaction will be required while reading
- * (selecting a file, waiting a moment, etc.)
+ * The class letting users to import vCard. This includes the UI part for letting them select
+ * an Account and posssibly a file if there's no Uri is given from its caller Activity.
  *
  * Note that this Activity assumes that the instance is a "one-shot Activity", which will be
  * finished (with the method {@link Activity#finish()}) after the import and never reuse
@@ -91,6 +65,8 @@
 public class ImportVCardActivity extends Activity {
     private static final String LOG_TAG = "ImportVCardActivity";
 
+    private static final int SELECT_ACCOUNT = 0;
+
     /* package */ static final String VCARD_URI_ARRAY = "vcard_uri_array";
 
     // Run on the UI thread. Must not be null except after onDestroy().
@@ -100,6 +76,9 @@
     private String mAccountName;
     private String mAccountType;
 
+    private String mAction;
+    private Uri mUri;
+
     private ProgressDialog mProgressDialogForScanVCard;
 
     private List<VCardFile> mAllVCardFileList;
@@ -107,6 +86,30 @@
 
     private String mErrorMessage;
 
+    private static class VCardFile {
+        private final String mName;
+        private final String mCanonicalPath;
+        private final long mLastModified;
+
+        public VCardFile(String name, String canonicalPath, long lastModified) {
+            mName = name;
+            mCanonicalPath = canonicalPath;
+            mLastModified = lastModified;
+        }
+
+        public String getName() {
+            return mName;
+        }
+
+        public String getCanonicalPath() {
+            return mCanonicalPath;
+        }
+
+        public long getLastModified() {
+            return mLastModified;
+        }
+    }
+
     // Runs on the UI thread.
     private class DialogDisplayer implements Runnable {
         private final int mResId;
@@ -365,8 +368,8 @@
     private void importVCard(final String[] uriStrings) {
         final Intent intent = new Intent(this, ImportVCardService.class);
         intent.putExtra(VCARD_URI_ARRAY, uriStrings);
-        intent.putExtra("account_name", mAccountName);
-        intent.putExtra("account_type", mAccountType);
+        intent.putExtra(SelectAccountActivity.ACCOUNT_NAME, mAccountName);
+        intent.putExtra(SelectAccountActivity.ACCOUNT_TYPE, mAccountType);
 
         // TODO: permission is not migrated to ImportVCardService, so some exception is
         // thrown when reading some Uri, permission of which is temporarily guaranteed
@@ -436,56 +439,52 @@
 
         final Intent intent = getIntent();
         if (intent != null) {
-            mAccountName = intent.getStringExtra("account_name");
-            mAccountType = intent.getStringExtra("account_type");
+            mAccountName = intent.getStringExtra(SelectAccountActivity.ACCOUNT_NAME);
+            mAccountType = intent.getStringExtra(SelectAccountActivity.ACCOUNT_TYPE);
+            mAction = intent.getAction();
+            mUri = intent.getData();
         } else {
             Log.e(LOG_TAG, "intent does not exist");
         }
 
-        // The caller often does not know account information at all, so we show the UI instead.
+        // The caller may not know account information at all, so we show the UI instead.
         if (TextUtils.isEmpty(mAccountName) || TextUtils.isEmpty(mAccountType)) {
-            // There's three possibilities:
-            // - more than one accounts -> ask the user
-            // - just one account -> use the account without asking the user
-            // - no account -> use phone-local storage without asking the user
             final Sources sources = Sources.getInstance(this);
             final List<Account> accountList = sources.getAccounts(true);
-            final int size = accountList.size();
-            if (size > 1) {
-                final int resId = R.string.import_from_sdcard;
-                mAccountSelectionListener =
-                    new AccountSelectionUtil.AccountSelectedListener(
-                            this, accountList, resId) {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                        dialog.dismiss();
-                        final Account account = mAccountList.get(which);
-                        mAccountName = account.name;
-                        mAccountType = account.type;
-                        // Instead of using Intent mechanism, call the relevant private method,
-                        // to avoid throwing an Intent to itself again.
-                        startImport();
-                    }
-                };
-                showDialog(resId);
-                return;
+            if (accountList.size() == 0) {
+                mAccountName = null;
+                mAccountType = null;
+            } else if (accountList.size() == 1) {
+                final Account account = accountList.get(0);
+                mAccountName = account.name;
+                mAccountType = account.type;
             } else {
-                final Account account = ((size > 0) ? accountList.get(0) : null);
-                if (account != null) {
-                    mAccountName = account.name;
-                    mAccountType = account.type;
-                }
+                startActivityForResult(new Intent(this, SelectAccountActivity.class),
+                        SELECT_ACCOUNT);
+                return;
             }
         }
-
-        startImport();
+        startImport(mAction, mUri);
     }
 
-    private void startImport() {
-        Intent intent = getIntent();
-        final String action = intent.getAction();
-        final Uri uri = intent.getData();
-        Log.v(LOG_TAG, "action = " + action + " ; path = " + uri);
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+        if (requestCode == SELECT_ACCOUNT) {
+            if (resultCode == RESULT_OK) {
+                mAccountName = intent.getStringExtra(SelectAccountActivity.ACCOUNT_NAME);
+                mAccountType = intent.getStringExtra(SelectAccountActivity.ACCOUNT_TYPE);
+                startImport(mAction, mUri);
+            } else {
+                if (resultCode != RESULT_CANCELED) {
+                    Log.w(LOG_TAG, "Result code was not OK nor CANCELED: " + resultCode);
+                }
+                finish();
+            }
+        }
+    }
+
+    private void startImport(String action, Uri uri) {
+        Log.d(LOG_TAG, "action = " + action + " ; path = " + uri);
 
         if (uri != null) {
             importVCard(uri.toString());
@@ -495,7 +494,7 @@
     }
 
     @Override
-    protected Dialog onCreateDialog(int resId) {
+    protected Dialog onCreateDialog(int resId, Bundle bundle) {
         switch (resId) {
             case R.string.import_from_sdcard: {
                 if (mAccountSelectionListener == null) {
@@ -503,8 +502,7 @@
                             "mAccountSelectionListener must not be null.");
                 }
                 return AccountSelectionUtil.getSelectAccountDialog(this, resId,
-                        mAccountSelectionListener,
-                        new CancelListener());
+                        mAccountSelectionListener, mCancelListener);
             }
             case R.id.dialog_searching_vcard: {
                 if (mProgressDialogForScanVCard == null) {
@@ -572,7 +570,7 @@
             }
         }
 
-        return super.onCreateDialog(resId);
+        return super.onCreateDialog(resId, bundle);
     }
 
     @Override
diff --git a/src/com/android/contacts/SelectAccountActivity.java b/src/com/android/contacts/SelectAccountActivity.java
new file mode 100644
index 0000000..cef00e0
--- /dev/null
+++ b/src/com/android/contacts/SelectAccountActivity.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.contacts;
+
+import android.accounts.Account;
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.contacts.model.Sources;
+import com.android.contacts.util.AccountSelectionUtil;
+
+import java.util.List;
+
+public class SelectAccountActivity extends Activity {
+    private static final String LOG_TAG = "SelectAccountActivity";
+
+    /* package */ static final String ACCOUNT_NAME = "account_name";
+    /* package */ static final String ACCOUNT_TYPE = "account_type";
+
+    private class CancelListener
+            implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
+        public void onClick(DialogInterface dialog, int which) {
+            finish();
+        }
+        public void onCancel(DialogInterface dialog) {
+            finish();
+        }
+    }
+
+    private AccountSelectionUtil.AccountSelectedListener mAccountSelectionListener;
+
+    @Override
+    protected void onCreate(Bundle bundle) {
+        super.onCreate(bundle);
+
+        // There's three possibilities:
+        // - more than one accounts -> ask the user
+        // - just one account -> use the account without asking the user
+        // - no account -> use phone-local storage without asking the user
+        final int resId = R.string.import_from_sdcard;
+        final Sources sources = Sources.getInstance(this);
+        final List<Account> accountList = sources.getAccounts(true);
+        if (accountList.size() == 0) {
+            Log.w(LOG_TAG, "Account does not exist");
+            finish();
+        } else if (accountList.size() == 1) {
+            final Account account = accountList.get(0);
+            final Intent intent = new Intent();
+            intent.putExtra(ACCOUNT_NAME, account.name);
+            intent.putExtra(ACCOUNT_TYPE, account.type);
+            setResult(RESULT_OK, intent);
+            finish();
+        }
+
+        // Multiple accounts. Let users to select one.
+        mAccountSelectionListener =
+                new AccountSelectionUtil.AccountSelectedListener(
+                        this, accountList, resId) {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        dialog.dismiss();
+                        final Account account = mAccountList.get(which);
+                        final Intent intent = new Intent();
+                        intent.putExtra(ACCOUNT_NAME, account.name);
+                        intent.putExtra(ACCOUNT_TYPE, account.type);
+                        setResult(RESULT_OK, intent);
+                        finish();
+                    }
+                };
+        showDialog(resId);
+        return;
+    }
+
+    @Override
+    protected Dialog onCreateDialog(int resId, Bundle bundle) {
+        switch (resId) {
+            case R.string.import_from_sdcard: {
+                if (mAccountSelectionListener == null) {
+                    throw new NullPointerException(
+                            "mAccountSelectionListener must not be null.");
+                }
+                return AccountSelectionUtil.getSelectAccountDialog(this, resId,
+                        mAccountSelectionListener,
+                        new CancelListener());
+            }
+        }
+        return super.onCreateDialog(resId, bundle);
+    }
+}