am faed3374: Switch from CALL -> CALL_PRIVILEGED
* commit 'faed337493039d8b149aace3816000cd396c99fe':
Switch from CALL -> CALL_PRIVILEGED
diff --git a/src/com/android/contacts/common/CallUtil.java b/src/com/android/contacts/common/CallUtil.java
index 32bd9e1..3a932ab 100644
--- a/src/com/android/contacts/common/CallUtil.java
+++ b/src/com/android/contacts/common/CallUtil.java
@@ -116,6 +116,13 @@
}
/**
+ * A variant of {@link #getCallIntent(android.net.Uri)} for calling Voicemail.
+ */
+ public static Intent getVoicemailIntent() {
+ return getCallIntent(Uri.fromParts(PhoneAccount.SCHEME_VOICEMAIL, "", null));
+ }
+
+ /**
* A variant of {@link #getCallIntent(android.net.Uri)} but also accept a call
* origin and {@code Account} and {@code VideoCallProfile} state.
* For more information about call origin, see comments in Phone package (PhoneApp).
diff --git a/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java b/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java
index 8d87714..99b8df5 100644
--- a/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java
+++ b/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java
@@ -28,7 +28,10 @@
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
+import android.telephony.SubInfoRecord;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -47,6 +50,7 @@
import com.android.contacts.common.vcard.VCardCommonArguments;
import com.android.dialerbind.analytics.AnalyticsDialogFragment;
+import java.util.Collections;
import java.util.List;
/**
@@ -57,6 +61,7 @@
public static final String TAG = "ImportExportDialogFragment";
private static final String KEY_RES_ID = "resourceId";
+ private static final String KEY_SUBSCRIPTION_ID = "subscriptionId";
private static final String ARG_CONTACTS_ARE_AVAILABLE = "CONTACTS_ARE_AVAILABLE";
private final String[] LOOKUP_PROJECTION = new String[] {
@@ -91,15 +96,14 @@
VCardCommonArguments.ARG_CALLING_ACTIVITY);
// Adapter that shows a list of string resources
- final ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(getActivity(),
+ 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));
- final int resId = getItem(position);
- result.setText(resId);
+ result.setText(getItem(position).mLabel);
return result;
}
};
@@ -107,21 +111,32 @@
final TelephonyManager manager =
(TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
- if (manager != null && manager.hasIccCard()
- && res.getBoolean(R.bool.config_allow_sim_import)) {
- adapter.add(R.string.import_from_sim);
- }
if (res.getBoolean(R.bool.config_allow_import_from_sdcard)) {
- adapter.add(R.string.import_from_sdcard);
+ adapter.add(new AdapterEntry(getString(R.string.import_from_sdcard),
+ R.string.import_from_sdcard));
+ }
+ if (manager != null && res.getBoolean(R.bool.config_allow_sim_import)) {
+ final List<SubInfoRecord> subInfoRecords = getAllSubInfoList();
+ if (subInfoRecords.size() == 1) {
+ adapter.add(new AdapterEntry(getString(R.string.import_from_sim),
+ R.string.import_from_sim, subInfoRecords.get(0).subId));
+ } else {
+ for (SubInfoRecord record : subInfoRecords) {
+ adapter.add(new AdapterEntry(getSubDescription(record),
+ R.string.import_from_sim, record.subId));
+ }
+ }
}
if (res.getBoolean(R.bool.config_allow_export_to_sdcard)) {
if (contactsAreAvailable) {
- adapter.add(R.string.export_to_sdcard);
+ adapter.add(new AdapterEntry(getString(R.string.export_to_sdcard),
+ R.string.export_to_sdcard));
}
}
if (res.getBoolean(R.bool.config_allow_share_visible_contacts)) {
if (contactsAreAvailable) {
- adapter.add(R.string.share_visible_contacts);
+ adapter.add(new AdapterEntry(getString(R.string.share_visible_contacts),
+ R.string.share_visible_contacts));
}
}
@@ -130,11 +145,12 @@
@Override
public void onClick(DialogInterface dialog, int which) {
boolean dismissDialog;
- final int resId = adapter.getItem(which);
+ final int resId = adapter.getItem(which).mChoiceResourceId;
switch (resId) {
case R.string.import_from_sim:
case R.string.import_from_sdcard: {
- dismissDialog = handleImportRequest(resId);
+ dismissDialog = handleImportRequest(resId,
+ adapter.getItem(which).mSubscriptionId);
break;
}
case R.string.export_to_sdcard: {
@@ -207,7 +223,7 @@
*
* @return {@code true} if the dialog show be closed. {@code false} otherwise.
*/
- private boolean handleImportRequest(int resId) {
+ private boolean handleImportRequest(int resId, long subscriptionId) {
// There are three possibilities:
// - more than one accounts -> ask the user
// - just one account -> use the account without asking the user
@@ -219,6 +235,7 @@
// Send over to the account selector
final Bundle args = new Bundle();
args.putInt(KEY_RES_ID, resId);
+ args.putLong(KEY_SUBSCRIPTION_ID, subscriptionId);
SelectAccountDialogFragment.show(
getFragmentManager(), this,
R.string.dialog_new_contact_account,
@@ -231,7 +248,7 @@
}
AccountSelectionUtil.doImport(getActivity(), resId,
- (size == 1 ? accountList.get(0) : null));
+ (size == 1 ? accountList.get(0) : null), subscriptionId);
return true; // Close the dialog.
}
@@ -240,7 +257,8 @@
*/
@Override
public void onAccountChosen(AccountWithDataSet account, Bundle extraArgs) {
- AccountSelectionUtil.doImport(getActivity(), extraArgs.getInt(KEY_RES_ID), account);
+ AccountSelectionUtil.doImport(getActivity(), extraArgs.getInt(KEY_RES_ID),
+ account, extraArgs.getLong(KEY_SUBSCRIPTION_ID));
// At this point the dialog is still showing (which is why we can use getActivity() above)
// So close it.
@@ -252,4 +270,49 @@
// See onAccountChosen() -- at this point the dialog is still showing. Close it.
dismiss();
}
+
+ /**
+ * Return the same values as {@link SubscriptionManager#getAllSubInfoList()} without relying
+ * on any hidden methods.
+ */
+ // TODO: replace with a method that doesn't make assumptions about the number of SIM slots
+ private static List<SubInfoRecord> getAllSubInfoList() {
+ final List<SubInfoRecord> subInfoRecords0 = SubscriptionManager.getSubInfoUsingSlotId(0);
+ final List<SubInfoRecord> subInfoRecords1 = SubscriptionManager.getSubInfoUsingSlotId(1);
+ if (subInfoRecords0 == null && subInfoRecords1 != null) {
+ return subInfoRecords1;
+ }
+ if (subInfoRecords0 != null && subInfoRecords1 == null) {
+ return subInfoRecords0;
+ }
+ if (subInfoRecords0 == null && subInfoRecords1 == null) {
+ return Collections.EMPTY_LIST;
+ }
+ subInfoRecords0.addAll(subInfoRecords1);
+ return subInfoRecords0;
+ }
+
+ private String getSubDescription(SubInfoRecord record) {
+ if (TextUtils.isEmpty(record.number)) {
+ // 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, record.displayName);
+ }
+ return getString(R.string.import_from_sim_summary, record.displayName, record.number);
+ }
+
+ private static class AdapterEntry {
+ public final String mLabel;
+ public final int mChoiceResourceId;
+ public final long mSubscriptionId;
+
+ public AdapterEntry(String label, int resId, long subscriptionId) {
+ mLabel = label;
+ mChoiceResourceId = resId;
+ mSubscriptionId = subscriptionId;
+ }
+
+ public AdapterEntry(String label, int resId) {
+ this(label, resId, SubscriptionManager.INVALID_SUB_ID);
+ }
+ }
}
diff --git a/src/com/android/contacts/common/util/AccountSelectionUtil.java b/src/com/android/contacts/common/util/AccountSelectionUtil.java
index ab32736..68217b9 100644
--- a/src/com/android/contacts/common/util/AccountSelectionUtil.java
+++ b/src/com/android/contacts/common/util/AccountSelectionUtil.java
@@ -22,6 +22,7 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
+import android.telephony.SubscriptionManager;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
@@ -54,22 +55,31 @@
final private Context mContext;
final private int mResId;
+ final private long mSubscriptionId;
final protected List<AccountWithDataSet> mAccountList;
public AccountSelectedListener(Context context, List<AccountWithDataSet> accountList,
- int resId) {
+ int resId, long subscriptionId) {
if (accountList == null || accountList.size() == 0) {
Log.e(LOG_TAG, "The size of Account list is 0.");
}
mContext = context;
mAccountList = accountList;
mResId = resId;
+ mSubscriptionId = subscriptionId;
+ }
+
+ public AccountSelectedListener(Context context, List<AccountWithDataSet> accountList,
+ int resId) {
+ // Subscription id is only needed for importing from SIM card. We can safely ignore
+ // its value for SD card importing.
+ this(context, accountList, resId, SubscriptionManager.INVALID_SUB_ID);
}
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
- doImport(mContext, mResId, mAccountList.get(which));
+ doImport(mContext, mResId, mAccountList.get(which), mSubscriptionId);
}
}
@@ -150,10 +160,11 @@
.create();
}
- public static void doImport(Context context, int resId, AccountWithDataSet account) {
+ public static void doImport(Context context, int resId, AccountWithDataSet account,
+ long subscriptionId) {
switch (resId) {
case R.string.import_from_sim: {
- doImportFromSim(context, account);
+ doImportFromSim(context, account, subscriptionId);
break;
}
case R.string.import_from_sdcard: {
@@ -163,7 +174,8 @@
}
}
- public static void doImportFromSim(Context context, AccountWithDataSet account) {
+ public static void doImportFromSim(Context context, AccountWithDataSet account,
+ long subscriptionId) {
Intent importIntent = new Intent(Intent.ACTION_VIEW);
importIntent.setType("vnd.android.cursor.item/sim-contact");
if (account != null) {
@@ -171,6 +183,7 @@
importIntent.putExtra("account_type", account.type);
importIntent.putExtra("data_set", account.dataSet);
}
+ importIntent.putExtra("subscription_id", subscriptionId);
importIntent.setClassName("com.android.phone", "com.android.phone.SimContacts");
context.startActivity(importIntent);
}
diff --git a/src/com/android/contacts/common/vcard/ImportVCardActivity.java b/src/com/android/contacts/common/vcard/ImportVCardActivity.java
index 70c9821..62e8431 100644
--- a/src/com/android/contacts/common/vcard/ImportVCardActivity.java
+++ b/src/com/android/contacts/common/vcard/ImportVCardActivity.java
@@ -109,8 +109,6 @@
final static String CACHED_URIS = "cached_uris";
- private AccountSelectionUtil.AccountSelectedListener mAccountSelectionListener;
-
private AccountWithDataSet mAccount;
private ProgressDialog mProgressDialogForScanVCard;
@@ -891,14 +889,6 @@
@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, mCancelListener);
- }
case R.id.dialog_searching_vcard: {
if (mProgressDialogForScanVCard == null) {
String message = getString(R.string.searching_vcard_message);
diff --git a/src/com/android/contacts/common/widget/SelectPhoneAccountDialogFragment.java b/src/com/android/contacts/common/widget/SelectPhoneAccountDialogFragment.java
new file mode 100644
index 0000000..0dbe70a
--- /dev/null
+++ b/src/com/android/contacts/common/widget/SelectPhoneAccountDialogFragment.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2014 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.widget;
+
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+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.os.Bundle;
+import android.telecom.TelecomManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ListAdapter;
+import android.widget.TextView;
+
+import com.android.contacts.common.R;
+
+import java.util.List;
+
+/**
+ * Dialog that allows the user to select a phone accounts for a given action. Optionally provides
+ * the choice to set the phone account as default.
+ */
+public class SelectPhoneAccountDialogFragment extends DialogFragment {
+ private boolean mCanSetDefault;
+ private List<PhoneAccountHandle> mAccountHandles;
+ private boolean mIsSelected;
+ private boolean mIsDefaultChecked;
+ private TelecomManager mTelecomManager;
+ private SelectPhoneAccountListener mListener;
+
+ /**
+ * Shows the account selection dialog.
+ * This is the preferred way to show this dialog.
+ *
+ * @param fragmentManager The fragment manager.
+ * @param accountHandles The {@code PhoneAccountHandle}s available to select from.
+ */
+ public static void showAccountDialog(FragmentManager fragmentManager, boolean canSetDefault,
+ List<PhoneAccountHandle> accountHandles, SelectPhoneAccountListener listener) {
+ SelectPhoneAccountDialogFragment fragment =
+ new SelectPhoneAccountDialogFragment(canSetDefault, accountHandles, listener);
+ fragment.show(fragmentManager, "selectAccount");
+ }
+
+ public SelectPhoneAccountDialogFragment(boolean canSetDefault,
+ List<PhoneAccountHandle> accountHandles, SelectPhoneAccountListener listener) {
+ super();
+ mCanSetDefault = canSetDefault;
+ mAccountHandles = accountHandles;
+ mListener = listener;
+ }
+
+ public interface SelectPhoneAccountListener {
+ void onPhoneAccountSelected(PhoneAccountHandle selectedAccountHandle, boolean setDefault);
+ void onDialogDismissed();
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ mIsSelected = false;
+ mIsDefaultChecked = false;
+ mTelecomManager =
+ (TelecomManager) getActivity().getSystemService(Context.TELECOM_SERVICE);
+
+ final DialogInterface.OnClickListener selectionListener =
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mIsSelected = true;
+ PhoneAccountHandle selectedAccountHandle = mAccountHandles.get(which);
+ mListener.onPhoneAccountSelected(selectedAccountHandle, mIsDefaultChecked);
+ }
+ };
+
+ final CompoundButton.OnCheckedChangeListener checkListener =
+ new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton check, boolean isChecked) {
+ mIsDefaultChecked = isChecked;
+ }
+ };
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ ListAdapter selectAccountListAdapter = new SelectAccountListAdapter(
+ builder.getContext(),
+ R.layout.select_account_list_item,
+ mAccountHandles);
+
+ AlertDialog dialog = builder.setTitle(R.string.select_account_dialog_title)
+ .setAdapter(selectAccountListAdapter, selectionListener)
+ .create();
+
+ if (mCanSetDefault) {
+ // Generate custom checkbox view
+ LinearLayout checkboxLayout = (LinearLayout) getActivity()
+ .getLayoutInflater()
+ .inflate(R.layout.default_account_checkbox, null);
+
+ CheckBox cb =
+ (CheckBox) checkboxLayout.findViewById(R.id.default_account_checkbox_view);
+ cb.setOnCheckedChangeListener(checkListener);
+
+ dialog.getListView().addFooterView(checkboxLayout);
+ }
+
+ return dialog;
+ }
+
+ private class SelectAccountListAdapter extends ArrayAdapter<PhoneAccountHandle> {
+ private Context mContext;
+ private int mResId;
+
+ public SelectAccountListAdapter(
+ Context context, int resource, List<PhoneAccountHandle> accountHandles) {
+ super(context, resource, accountHandles);
+ mContext = context;
+ mResId = resource;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LayoutInflater inflater = (LayoutInflater)
+ mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ View rowView;
+ final ViewHolder holder;
+
+ if (convertView == null) {
+ // Cache views for faster scrolling
+ rowView = inflater.inflate(mResId, null);
+ holder = new ViewHolder();
+ holder.textView = (TextView) rowView.findViewById(R.id.text);
+ holder.imageView = (ImageView) rowView.findViewById(R.id.icon);
+ rowView.setTag(holder);
+ }
+ else {
+ rowView = convertView;
+ holder = (ViewHolder) rowView.getTag();
+ }
+
+ PhoneAccountHandle accountHandle = getItem(position);
+ PhoneAccount account = mTelecomManager.getPhoneAccount(accountHandle);
+ holder.textView.setText(account.getLabel());
+ holder.imageView.setImageDrawable(account.getIcon(mContext));
+ return rowView;
+ }
+
+ private class ViewHolder {
+ TextView textView;
+ ImageView imageView;
+ }
+ }
+
+ @Override
+ public void onPause() {
+ if (!mIsSelected) {
+ mListener.onDialogDismissed();
+ }
+ super.onPause();
+ }
+}
\ No newline at end of file