Split Import and Export Dialogs

Bug: 28942286
Test: manually entering the settings with 0 and non-zero numbers of
contacts checking that export option appears only with non-zero contacts

Change-Id: I4a5b2714081fab1f6ed387a821e3df59d4b36eee
diff --git a/src/com/android/contacts/common/interactions/ImportDialogFragment.java b/src/com/android/contacts/common/interactions/ImportDialogFragment.java
new file mode 100644
index 0000000..0c0ce73
--- /dev/null
+++ b/src/com/android/contacts/common/interactions/ImportDialogFragment.java
@@ -0,0 +1,258 @@
+/*
+ * 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.common.interactions;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.provider.ContactsContract.Contacts;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import com.android.contacts.common.R;
+import com.android.contacts.common.compat.CompatUtils;
+import com.android.contacts.common.compat.PhoneNumberUtilsCompat;
+import com.android.contacts.common.model.AccountTypeManager;
+import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.util.AccountSelectionUtil;
+import com.android.contacts.common.util.AccountsListAdapter.AccountListFilter;
+import com.android.contacts.common.vcard.VCardCommonArguments;
+import com.android.contacts.editor.SelectAccountDialogFragment;
+
+import java.util.List;
+
+/**
+ * An dialog invoked to import/export contacts.
+ */
+public class ImportDialogFragment extends DialogFragment
+        implements SelectAccountDialogFragment.Listener {
+    public static final String TAG = "ImportDialogFragment";
+
+    private static final String KEY_RES_ID = "resourceId";
+    private static final String KEY_SUBSCRIPTION_ID = "subscriptionId";
+
+
+    private final String[] LOOKUP_PROJECTION = new String[] {
+            Contacts.LOOKUP_KEY
+    };
+
+    private SubscriptionManager mSubscriptionManager;
+
+    /** Preferred way to show this dialog */
+    public static void show(FragmentManager fragmentManager, Class callingActivity) {
+        final ImportDialogFragment fragment = new ImportDialogFragment();
+        Bundle args = new Bundle();
+        args.putString(VCardCommonArguments.ARG_CALLING_ACTIVITY, callingActivity.getName());
+        fragment.setArguments(args);
+        fragment.show(fragmentManager, TAG);
+    }
+
+    @Override
+    public Context getContext() {
+        return getActivity();
+    }
+
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        // Wrap our context to inflate list items using the correct theme
+        final Resources res = getActivity().getResources();
+        final LayoutInflater dialogInflater = (LayoutInflater)getActivity()
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        final String callingActivity = getArguments().getString(
+                VCardCommonArguments.ARG_CALLING_ACTIVITY);
+
+        // Adapter that shows a list of string resources
+        final ArrayAdapter<AdapterEntry> adapter = new ArrayAdapter<AdapterEntry>(getActivity(),
+                R.layout.select_dialog_item) {
+            @Override
+            public View getView(int position, View convertView, ViewGroup parent) {
+                final TextView result = (TextView)(convertView != null ? convertView :
+                        dialogInflater.inflate(R.layout.select_dialog_item, parent, false));
+
+                result.setText(getItem(position).mLabel);
+                return result;
+            }
+        };
+
+        final TelephonyManager manager =
+                (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
+        if (res.getBoolean(R.bool.config_allow_import_from_vcf_file)) {
+            adapter.add(new AdapterEntry(getString(R.string.import_from_vcf_file),
+                    R.string.import_from_vcf_file));
+        }
+
+        if (CompatUtils.isMSIMCompatible()) {
+            mSubscriptionManager = SubscriptionManager.from(getActivity());
+            if (manager != null && res.getBoolean(R.bool.config_allow_sim_import)) {
+                List<SubscriptionInfo> subInfoRecords = null;
+                try {
+                    subInfoRecords =  mSubscriptionManager.getActiveSubscriptionInfoList();
+                } catch (SecurityException e) {
+                    Log.w(TAG, "SecurityException thrown, lack permission for"
+                            + " getActiveSubscriptionInfoList", e);
+                }
+                if (subInfoRecords != null) {
+                    if (subInfoRecords.size() == 1) {
+                        adapter.add(new AdapterEntry(getString(R.string.import_from_sim),
+                                R.string.import_from_sim, subInfoRecords.get(0).getSubscriptionId()));
+                    } else {
+                        for (SubscriptionInfo record : subInfoRecords) {
+                            adapter.add(new AdapterEntry(getSubDescription(record),
+                                    R.string.import_from_sim, record.getSubscriptionId()));
+                        }
+                    }
+                }
+            }
+        } else {
+            if (manager != null && manager.hasIccCard()
+                    && res.getBoolean(R.bool.config_allow_sim_import)) {
+                adapter.add(new AdapterEntry(getString(R.string.import_from_sim),
+                        R.string.import_from_sim, -1));
+            }
+        }
+
+
+        final DialogInterface.OnClickListener clickListener =
+                new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                boolean dismissDialog;
+                final int resId = adapter.getItem(which).mChoiceResourceId;
+                if (resId == R.string.import_from_sim || resId == R.string.import_from_vcf_file) {
+                        dismissDialog = handleImportRequest(resId,
+                                adapter.getItem(which).mSubscriptionId);
+                } else {
+                    dismissDialog = true;
+                    Log.e(TAG, "Unexpected resource: "
+                            + getActivity().getResources().getResourceEntryName(resId));
+                }
+                if (dismissDialog) {
+                    dialog.dismiss();
+                }
+            }
+        };
+        final TextView title = (TextView) View.inflate(getActivity(), R.layout.dialog_title, null);
+        title.setText(R.string.dialog_import);
+        return new AlertDialog.Builder(getActivity())
+                .setCustomTitle(title)
+                .setSingleChoiceItems(adapter, -1, clickListener)
+                .create();
+    }
+
+    /**
+     * Handle "import from SIM" and "import from SD".
+     *
+     * @return {@code true} if the dialog show be closed.  {@code false} otherwise.
+     */
+    private boolean handleImportRequest(int resId, int subscriptionId) {
+        // There are 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 AccountTypeManager accountTypes = AccountTypeManager.getInstance(getActivity());
+        final List<AccountWithDataSet> accountList = accountTypes.getAccounts(true);
+        final int size = accountList.size();
+        if (size > 1) {
+            // Send over to the account selector
+            final Bundle args = new Bundle();
+            args.putInt(KEY_RES_ID, resId);
+            args.putInt(KEY_SUBSCRIPTION_ID, subscriptionId);
+            SelectAccountDialogFragment.show(
+                    getFragmentManager(), this,
+                    R.string.dialog_new_contact_account,
+                    AccountListFilter.ACCOUNTS_CONTACT_WRITABLE, args);
+
+            // In this case, because this DialogFragment is used as a target fragment to
+            // SelectAccountDialogFragment, we can't close it yet.  We close the dialog when
+            // we get a callback from it.
+            return false;
+        }
+
+        AccountSelectionUtil.doImport(getActivity(), resId,
+                (size == 1 ? accountList.get(0) : null),
+                (CompatUtils.isMSIMCompatible() ? subscriptionId : -1));
+        return true; // Close the dialog.
+    }
+
+    /**
+     * Called when an account is selected on {@link SelectAccountDialogFragment}.
+     */
+    @Override
+    public void onAccountChosen(AccountWithDataSet account, Bundle extraArgs) {
+        AccountSelectionUtil.doImport(getActivity(), extraArgs.getInt(KEY_RES_ID),
+                account, extraArgs.getInt(KEY_SUBSCRIPTION_ID));
+
+        // At this point the dialog is still showing (which is why we can use getActivity() above)
+        // So close it.
+        dismiss();
+    }
+
+    @Override
+    public void onAccountSelectorCancelled() {
+        // See onAccountChosen() -- at this point the dialog is still showing.  Close it.
+        dismiss();
+    }
+
+    private CharSequence getSubDescription(SubscriptionInfo record) {
+        CharSequence name = record.getDisplayName();
+        if (TextUtils.isEmpty(record.getNumber())) {
+            // Don't include the phone number in the description, since we don't know the number.
+            return getString(R.string.import_from_sim_summary_no_number, name);
+        }
+        return TextUtils.expandTemplate(
+                getString(R.string.import_from_sim_summary),
+                name,
+                PhoneNumberUtilsCompat.createTtsSpannable(record.getNumber()));
+    }
+
+    private static class AdapterEntry {
+        public final CharSequence mLabel;
+        public final int mChoiceResourceId;
+        public final int mSubscriptionId;
+
+        public AdapterEntry(CharSequence label, int resId, int subId) {
+            mLabel = label;
+            mChoiceResourceId = resId;
+            mSubscriptionId = subId;
+        }
+
+        public AdapterEntry(String label, int resId) {
+            // Store a nonsense value for mSubscriptionId. If this constructor is used,
+            // the mSubscriptionId value should not be read later.
+            this(label, resId, /* subId = */ -1);
+        }
+    }
+}