1 package com.android.contacts.editor; 2 3 import android.app.AlertDialog; 4 import android.app.Dialog; 5 import android.app.DialogFragment; 6 import android.content.Context; 7 import android.content.DialogInterface; 8 import android.content.Intent; 9 import android.os.Bundle; 10 import android.text.TextUtils; 11 import android.view.LayoutInflater; 12 import android.view.View; 13 import android.view.ViewGroup; 14 import android.widget.BaseAdapter; 15 import android.widget.ImageView; 16 import android.widget.ListAdapter; 17 import android.widget.TextView; 18 19 import com.android.contacts.ContactPhotoManager; 20 import com.android.contacts.R; 21 import com.android.contacts.activities.ContactSelectionActivity; 22 import com.android.contacts.editor.PickRawContactLoader.RawContact; 23 import com.android.contacts.editor.PickRawContactLoader.RawContactsMetadata; 24 import com.android.contacts.list.UiIntentActions; 25 import com.android.contacts.logging.EditorEvent; 26 import com.android.contacts.logging.Logger; 27 import com.android.contacts.model.AccountTypeManager; 28 import com.android.contacts.model.account.AccountDisplayInfo; 29 import com.android.contacts.model.account.AccountDisplayInfoFactory; 30 import com.android.contacts.model.account.AccountInfo; 31 import com.android.contacts.model.account.AccountType; 32 import com.android.contacts.model.account.AccountWithDataSet; 33 import com.android.contacts.model.account.GoogleAccountType; 34 import com.android.contacts.preference.ContactsPreferences; 35 36 /** 37 * Should only be started from an activity that implements {@link PickRawContactListener}. 38 * Dialog containing the raw contacts that make up a contact. On selection the editor is loaded 39 * for the chosen raw contact. 40 */ 41 public class PickRawContactDialogFragment extends DialogFragment { 42 private static final String ARGS_RAW_CONTACTS_METADATA = "rawContactsMetadata"; 43 private static final int REQUEST_CODE_JOIN = 3; 44 45 public interface PickRawContactListener { onPickRawContact(long rawContactId)46 void onPickRawContact(long rawContactId); 47 } 48 49 /** 50 * Used to list the account info for the given raw contacts list. 51 */ 52 private final class RawContactAccountListAdapter extends BaseAdapter { 53 private final LayoutInflater mInflater; 54 private final Context mContext; 55 private final RawContactsMetadata mRawContactsMetadata; 56 private final AccountTypeManager mAccountTypeManager; 57 private final ContactsPreferences mPreferences; 58 RawContactAccountListAdapter(Context context, RawContactsMetadata rawContactsMetadata)59 public RawContactAccountListAdapter(Context context, 60 RawContactsMetadata rawContactsMetadata) { 61 mContext = context; 62 mInflater = LayoutInflater.from(context); 63 mAccountTypeManager = AccountTypeManager.getInstance(context); 64 mPreferences = new ContactsPreferences(context); 65 mRawContactsMetadata = rawContactsMetadata; 66 } 67 68 @Override getCount()69 public int getCount() { 70 return mRawContactsMetadata.rawContacts.size(); 71 } 72 73 @Override getItem(int position)74 public Object getItem(int position) { 75 return mRawContactsMetadata.rawContacts.get(position); 76 } 77 78 @Override getItemId(int position)79 public long getItemId(int position) { 80 return mRawContactsMetadata.rawContacts.get(position).id; 81 } 82 83 @Override getView(int position, View convertView, ViewGroup parent)84 public View getView(int position, View convertView, ViewGroup parent) { 85 final View view; 86 final RawContactViewHolder holder; 87 if (convertView == null) { 88 view = mInflater.inflate(R.layout.raw_contact_list_item, parent, false); 89 holder = new RawContactViewHolder(); 90 holder.displayName = (TextView) view.findViewById(R.id.display_name); 91 holder.accountName = (TextView) view.findViewById(R.id.account_name); 92 holder.accountIcon = (ImageView) view.findViewById(R.id.account_icon); 93 holder.photo = (ImageView) view.findViewById(R.id.photo); 94 view.setTag(holder); 95 } else { 96 view = convertView; 97 holder = (RawContactViewHolder) view.getTag(); 98 } 99 final RawContact rawContact = mRawContactsMetadata.rawContacts.get(position); 100 final AccountType account = mAccountTypeManager.getAccountType(rawContact.accountType, 101 rawContact.accountDataSet); 102 103 String displayName = 104 mPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY 105 ? rawContact.displayName : rawContact.displayNameAlt; 106 107 if (TextUtils.isEmpty(displayName)) { 108 displayName = mContext.getString(R.string.missing_name); 109 } 110 holder.displayName.setText(displayName); 111 112 final String accountDisplayLabel; 113 114 // Use the same string as editor if it's an editable user profile raw contact. 115 if (mRawContactsMetadata.isUserProfile && account.areContactsWritable()) { 116 final AccountInfo accountInfo = 117 AccountTypeManager.getInstance(getContext()).getAccountInfoForAccount( 118 new AccountWithDataSet(rawContact.accountName, 119 rawContact.accountType, rawContact.accountDataSet)); 120 accountDisplayLabel = EditorUiUtils.getAccountHeaderLabelForMyProfile(mContext, 121 accountInfo); 122 } else if (GoogleAccountType.ACCOUNT_TYPE.equals(rawContact.accountType) 123 && account.dataSet == null) { 124 // Focus Google accounts have the account name shown 125 accountDisplayLabel = rawContact.accountName; 126 } else { 127 accountDisplayLabel = account.getDisplayLabel(mContext).toString(); 128 } 129 130 holder.accountName.setText(accountDisplayLabel); 131 holder.accountIcon.setImageDrawable(account.getDisplayIcon(mContext)); 132 final ContactPhotoManager.DefaultImageRequest 133 request = new ContactPhotoManager.DefaultImageRequest( 134 displayName, String.valueOf(rawContact.id), /* isCircular = */ true); 135 136 ContactPhotoManager.getInstance(mContext).loadThumbnail(holder.photo, 137 rawContact.photoId, 138 /* darkTheme = */ false, 139 /* isCircular = */ true, 140 request); 141 return view; 142 } 143 144 class RawContactViewHolder { 145 TextView displayName; 146 TextView accountName; 147 ImageView accountIcon; 148 ImageView photo; 149 } 150 } 151 152 private ListAdapter mAdapter; 153 private boolean mShouldFinishActivity = true; 154 getInstance(RawContactsMetadata metadata)155 public static PickRawContactDialogFragment getInstance(RawContactsMetadata metadata) { 156 final PickRawContactDialogFragment fragment = new PickRawContactDialogFragment(); 157 final Bundle args = new Bundle(); 158 args.putParcelable(ARGS_RAW_CONTACTS_METADATA, metadata); 159 fragment.setArguments(args); 160 return fragment; 161 } 162 163 @Override onCreateDialog(Bundle savedInstanceState)164 public Dialog onCreateDialog(Bundle savedInstanceState) { 165 if (!(getActivity() instanceof PickRawContactListener)) { 166 throw new IllegalArgumentException( 167 "Host activity doesn't implement PickRawContactListener"); 168 } 169 final Bundle args = getArguments(); 170 if (args == null) { 171 throw new IllegalArgumentException("Dialog created with no arguments"); 172 } 173 174 final RawContactsMetadata metadata = args.getParcelable(ARGS_RAW_CONTACTS_METADATA); 175 if (metadata == null) { 176 throw new IllegalArgumentException("Dialog created with null RawContactsMetadata"); 177 } 178 179 final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 180 mAdapter = new RawContactAccountListAdapter(getContext(), metadata); 181 if (metadata.showReadOnly) { 182 builder.setTitle(R.string.contact_editor_pick_linked_contact_dialog_title); 183 // Only provide link editing options for non-user profile contacts. 184 if (!metadata.isUserProfile) { 185 builder.setPositiveButton(R.string.contact_editor_add_linked_contact, 186 new DialogInterface.OnClickListener() { 187 @Override 188 public void onClick(DialogInterface dialog, int which) { 189 mShouldFinishActivity = false; 190 final Intent intent = new Intent(getActivity(), 191 ContactSelectionActivity.class); 192 intent.setAction(UiIntentActions.PICK_JOIN_CONTACT_ACTION); 193 intent.putExtra(UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY, 194 metadata.contactId); 195 getActivity().startActivityForResult(intent, REQUEST_CODE_JOIN); 196 } 197 }); 198 builder.setNegativeButton(R.string.contact_editor_unlink_contacts, 199 new DialogInterface.OnClickListener() { 200 @Override 201 public void onClick(DialogInterface dialog, int which) { 202 mShouldFinishActivity = false; 203 final SplitContactConfirmationDialogFragment splitDialog = new 204 SplitContactConfirmationDialogFragment(); 205 splitDialog.show(getActivity().getFragmentManager(), 206 SplitContactConfirmationDialogFragment.TAG); 207 } 208 }); 209 } 210 } else { 211 builder.setTitle(R.string.contact_editor_pick_raw_contact_to_edit_dialog_title); 212 } 213 builder.setAdapter(mAdapter, new DialogInterface.OnClickListener() { 214 @Override 215 public void onClick(DialogInterface dialog, int which) { 216 final long rawContactId = mAdapter.getItemId(which); 217 ((PickRawContactListener) getActivity()).onPickRawContact(rawContactId); 218 } 219 }); 220 builder.setCancelable(true); 221 if (savedInstanceState == null) { 222 Logger.logEditorEvent(EditorEvent.EventType.SHOW_RAW_CONTACT_PICKER, 223 /* numberRawContacts */ mAdapter.getCount()); 224 } 225 return builder.create(); 226 } 227 228 @Override onDismiss(DialogInterface dialog)229 public void onDismiss(DialogInterface dialog) { 230 super.onDismiss(dialog); 231 if (mShouldFinishActivity) { 232 finishActivity(); 233 } 234 } 235 236 @Override getContext()237 public Context getContext() { 238 return getActivity(); 239 } 240 finishActivity()241 private void finishActivity() { 242 if (getActivity() != null && !getActivity().isFinishing()) { 243 getActivity().finish(); 244 } 245 } 246 } 247