1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.contacts.editor; 18 19 import android.accounts.Account; 20 import android.accounts.AccountManager; 21 import android.app.Activity; 22 import android.content.ContentUris; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.net.Uri; 26 import android.os.Bundle; 27 import android.provider.ContactsContract; 28 import android.text.TextUtils; 29 30 import com.android.contacts.model.account.AccountWithDataSet; 31 import com.android.contacts.preference.ContactsPreferences; 32 33 import java.util.List; 34 35 /** 36 * Utility methods for the "account changed" notification in the new contact creation flow. 37 */ 38 public class ContactEditorUtils { 39 private static final String TAG = "ContactEditorUtils"; 40 41 private final Context mContext; 42 private final ContactsPreferences mContactsPrefs; 43 ContactEditorUtils(Context context)44 private ContactEditorUtils(Context context) { 45 mContext = context; 46 mContactsPrefs = new ContactsPreferences(context); 47 } 48 create(Context context)49 public static ContactEditorUtils create(Context context) { 50 return new ContactEditorUtils(context.getApplicationContext()); 51 } 52 53 /** 54 * Returns a legacy version of the given contactLookupUri if a legacy Uri was originally 55 * passed to the contact editor. 56 * 57 * @param contactLookupUri The Uri to possibly convert to legacy format. 58 * @param requestLookupUri The lookup Uri originally passed to the contact editor 59 * (via Intent data), may be null. 60 */ maybeConvertToLegacyLookupUri(Context context, Uri contactLookupUri, Uri requestLookupUri)61 static Uri maybeConvertToLegacyLookupUri(Context context, Uri contactLookupUri, 62 Uri requestLookupUri) { 63 final String legacyAuthority = "contacts"; 64 final String requestAuthority = requestLookupUri == null 65 ? null : requestLookupUri.getAuthority(); 66 if (legacyAuthority.equals(requestAuthority)) { 67 // Build a legacy Uri if that is what was requested by caller 68 final long contactId = ContentUris.parseId(ContactsContract.Contacts.lookupContact( 69 context.getContentResolver(), contactLookupUri)); 70 final Uri legacyContentUri = Uri.parse("content://contacts/people"); 71 return ContentUris.withAppendedId(legacyContentUri, contactId); 72 } 73 // Otherwise pass back a lookup-style Uri 74 return contactLookupUri; 75 } 76 cleanupForTest()77 void cleanupForTest() { 78 mContactsPrefs.clearDefaultAccount(); 79 } 80 removeDefaultAccountForTest()81 void removeDefaultAccountForTest() { 82 mContactsPrefs.clearDefaultAccount(); 83 } 84 85 /** 86 * Saves the default account, which can later be obtained with {@link #getOnlyOrDefaultAccount}. 87 * 88 * This should be called when saving a newly created contact. 89 * 90 * @param defaultAccount the account used to save a newly created contact. 91 */ saveDefaultAccount(AccountWithDataSet defaultAccount)92 public void saveDefaultAccount(AccountWithDataSet defaultAccount) { 93 if (defaultAccount == null) { 94 mContactsPrefs.clearDefaultAccount(); 95 } else { 96 mContactsPrefs.setDefaultAccount(defaultAccount); 97 } 98 } 99 100 /** 101 * @return the first account if there is only a single account or the default account saved 102 * with {@link #saveDefaultAccount}. 103 * 104 * A null return value indicates that there is multiple accounts and a default hasn't been set 105 * 106 * Also note that the returned account may have been removed already. 107 */ getOnlyOrDefaultAccount( List<AccountWithDataSet> currentWritableAccounts)108 public AccountWithDataSet getOnlyOrDefaultAccount( 109 List<AccountWithDataSet> currentWritableAccounts) { 110 if (currentWritableAccounts.size() == 1) { 111 return currentWritableAccounts.get(0); 112 } 113 114 return mContactsPrefs.getDefaultAccount(); 115 } 116 shouldShowAccountChangedNotification(List<AccountWithDataSet> writableAccounts)117 public boolean shouldShowAccountChangedNotification(List<AccountWithDataSet> writableAccounts) { 118 return mContactsPrefs.shouldShowAccountChangedNotification(writableAccounts); 119 } 120 121 /** 122 * Sets the only non-device account to be default if it is not already. 123 */ maybeUpdateDefaultAccount(List<AccountWithDataSet> currentWritableAccounts)124 public void maybeUpdateDefaultAccount(List<AccountWithDataSet> currentWritableAccounts) { 125 if (currentWritableAccounts.size() == 1) { 126 final AccountWithDataSet onlyAccount = currentWritableAccounts.get(0); 127 if (!onlyAccount.equals(AccountWithDataSet.getLocalAccount(mContext)) 128 && !onlyAccount.equals(mContactsPrefs.getDefaultAccount())) { 129 mContactsPrefs.setDefaultAccount(onlyAccount); 130 } 131 } 132 } 133 134 /** 135 * Parses a result from {@link AccountManager#newChooseAccountIntent(Account, List, String[], 136 * String, String, String[], Bundle)} and returns the created {@link Account}, or null if 137 * the user has canceled the wizard. 138 * 139 * <p>Pass the {@code resultCode} and {@code data} parameters passed to 140 * {@link Activity#onActivityResult} or {@link android.app.Fragment#onActivityResult}. 141 * </p> 142 * 143 * <p> 144 * Note although the return type is {@link AccountWithDataSet}, return values from this method 145 * will never have {@link AccountWithDataSet#dataSet} set, as there's no way to create an 146 * extension package account from setup wizard. 147 * </p> 148 */ getCreatedAccount(int resultCode, Intent resultData)149 public AccountWithDataSet getCreatedAccount(int resultCode, Intent resultData) { 150 // Javadoc doesn't say anything about resultCode but that the data intent will be non null 151 // on success. 152 if (resultData == null) return null; 153 154 final String accountType = resultData.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE); 155 final String accountName = resultData.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); 156 157 // Just in case 158 if (TextUtils.isEmpty(accountType) || TextUtils.isEmpty(accountName)) return null; 159 160 return new AccountWithDataSet(accountName, accountType, null); 161 } 162 } 163