blob: 4bb075cc6332e7157a2de14756cbfca7c2df5cb1 [file] [log] [blame]
Makoto Onuki558669d2011-09-22 18:09:28 -07001/*
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
17package com.android.contacts.editor;
18
Makoto Onuki558669d2011-09-22 18:09:28 -070019import android.accounts.Account;
20import android.accounts.AccountManager;
21import android.app.Activity;
Walter Jang7b0970f2016-09-01 10:40:19 -070022import android.content.ContentUris;
Makoto Onuki558669d2011-09-22 18:09:28 -070023import android.content.Context;
24import android.content.Intent;
Walter Jang7b0970f2016-09-01 10:40:19 -070025import android.net.Uri;
Marcus Hagerottf0e140a2016-12-05 16:59:48 -080026import android.os.Bundle;
Walter Jang7b0970f2016-09-01 10:40:19 -070027import android.provider.ContactsContract;
Makoto Onuki558669d2011-09-22 18:09:28 -070028import android.text.TextUtils;
29
Gary Mai69c182a2016-12-05 13:07:03 -080030import com.android.contacts.model.AccountTypeManager;
31import com.android.contacts.model.account.AccountType;
32import com.android.contacts.model.account.AccountWithDataSet;
33import com.android.contacts.preference.ContactsPreferences;
Gary Mai0a49afa2016-12-05 15:53:58 -080034
Chiao Chenge0b2f1e2012-06-12 13:07:56 -070035import com.google.common.annotations.VisibleForTesting;
Chiao Chenge0b2f1e2012-06-12 13:07:56 -070036import com.google.common.collect.Sets;
37
Makoto Onuki558669d2011-09-22 18:09:28 -070038import java.util.ArrayList;
39import java.util.List;
40import java.util.Set;
41
42/**
43 * Utility methods for the "account changed" notification in the new contact creation flow.
Makoto Onuki558669d2011-09-22 18:09:28 -070044 */
45public class ContactEditorUtils {
46 private static final String TAG = "ContactEditorUtils";
47
Marcus Hagerott949d4e82016-09-20 13:23:05 -070048 private final ContactsPreferences mContactsPrefs;
Makoto Onuki558669d2011-09-22 18:09:28 -070049 private final AccountTypeManager mAccountTypes;
50
51 private ContactEditorUtils(Context context) {
52 this(context, AccountTypeManager.getInstance(context));
53 }
54
55 @VisibleForTesting
56 ContactEditorUtils(Context context, AccountTypeManager accountTypes) {
Marcus Hagerott949d4e82016-09-20 13:23:05 -070057 mContactsPrefs = new ContactsPreferences(context);
Makoto Onuki558669d2011-09-22 18:09:28 -070058 mAccountTypes = accountTypes;
59 }
60
Marcus Hagerott949d4e82016-09-20 13:23:05 -070061 public static ContactEditorUtils create(Context context) {
62 return new ContactEditorUtils(context.getApplicationContext());
Makoto Onuki558669d2011-09-22 18:09:28 -070063 }
64
Walter Jang7b0970f2016-09-01 10:40:19 -070065 /**
66 * Returns a legacy version of the given contactLookupUri if a legacy Uri was originally
67 * passed to the contact editor.
68 *
69 * @param contactLookupUri The Uri to possibly convert to legacy format.
70 * @param requestLookupUri The lookup Uri originally passed to the contact editor
71 * (via Intent data), may be null.
72 */
73 static Uri maybeConvertToLegacyLookupUri(Context context, Uri contactLookupUri,
74 Uri requestLookupUri) {
75 final String legacyAuthority = "contacts";
76 final String requestAuthority = requestLookupUri == null
77 ? null : requestLookupUri.getAuthority();
78 if (legacyAuthority.equals(requestAuthority)) {
79 // Build a legacy Uri if that is what was requested by caller
80 final long contactId = ContentUris.parseId(ContactsContract.Contacts.lookupContact(
81 context.getContentResolver(), contactLookupUri));
82 final Uri legacyContentUri = Uri.parse("content://contacts/people");
83 return ContentUris.withAppendedId(legacyContentUri, contactId);
84 }
85 // Otherwise pass back a lookup-style Uri
86 return contactLookupUri;
87 }
88
Makoto Onuki558669d2011-09-22 18:09:28 -070089 void cleanupForTest() {
Marcus Hagerott949d4e82016-09-20 13:23:05 -070090 mContactsPrefs.clearDefaultAccount();
Makoto Onuki558669d2011-09-22 18:09:28 -070091 }
92
Makoto Onuki131e6ac2011-10-04 19:09:54 -070093 void removeDefaultAccountForTest() {
Marcus Hagerott949d4e82016-09-20 13:23:05 -070094 mContactsPrefs.clearDefaultAccount();
Makoto Onuki131e6ac2011-10-04 19:09:54 -070095 }
96
Makoto Onuki558669d2011-09-22 18:09:28 -070097 private List<AccountWithDataSet> getWritableAccounts() {
98 return mAccountTypes.getAccounts(true);
99 }
100
101 /**
Marcus Hagerott949d4e82016-09-20 13:23:05 -0700102 * Saves the default account, which can later be obtained with {@link #getOnlyOrDefaultAccount}.
Makoto Onuki558669d2011-09-22 18:09:28 -0700103 *
104 * This should be called when saving a newly created contact.
105 *
Marcus Hagerottfac695a2016-08-24 17:02:40 -0700106 * @param defaultAccount the account used to save a newly created contact.
Makoto Onuki558669d2011-09-22 18:09:28 -0700107 */
Marcus Hagerott949d4e82016-09-20 13:23:05 -0700108 public void saveDefaultAccount(AccountWithDataSet defaultAccount) {
Marcus Hagerottfac695a2016-08-24 17:02:40 -0700109 if (defaultAccount == null) {
Marcus Hagerott949d4e82016-09-20 13:23:05 -0700110 mContactsPrefs.clearDefaultAccount();
Makoto Onuki131e6ac2011-10-04 19:09:54 -0700111 } else {
Marcus Hagerott949d4e82016-09-20 13:23:05 -0700112 mContactsPrefs.setDefaultAccount(defaultAccount);
Makoto Onuki131e6ac2011-10-04 19:09:54 -0700113 }
Makoto Onuki558669d2011-09-22 18:09:28 -0700114 }
115
116 /**
Marcus Hagerott949d4e82016-09-20 13:23:05 -0700117 * @return the first account if there is only a single account or the default account saved
118 * with {@link #saveDefaultAccount}.
Makoto Onuki558669d2011-09-22 18:09:28 -0700119 *
Marcus Hagerott949d4e82016-09-20 13:23:05 -0700120 * A null return value indicates that there is multiple accounts and a default hasn't been set
Makoto Onuki558669d2011-09-22 18:09:28 -0700121 *
122 * Also note that the returned account may have been removed already.
123 */
Marcus Hagerott949d4e82016-09-20 13:23:05 -0700124 public AccountWithDataSet getOnlyOrDefaultAccount() {
Tingting Wang4abdee92015-11-24 11:50:21 -0800125 final List<AccountWithDataSet> currentWritableAccounts = getWritableAccounts();
126 if (currentWritableAccounts.size() == 1) {
127 return currentWritableAccounts.get(0);
128 }
129
Marcus Hagerott949d4e82016-09-20 13:23:05 -0700130 return mContactsPrefs.getDefaultAccount();
Makoto Onuki558669d2011-09-22 18:09:28 -0700131 }
132
Makoto Onuki558669d2011-09-22 18:09:28 -0700133 public boolean shouldShowAccountChangedNotification() {
Marcus Hagerott949d4e82016-09-20 13:23:05 -0700134 return mContactsPrefs.shouldShowAccountChangedNotification(getWritableAccounts());
Makoto Onuki558669d2011-09-22 18:09:28 -0700135 }
136
Gary Mai3107b252016-11-02 18:26:07 -0700137 /**
138 * Sets the only non-device account to be default if it is not already.
139 */
140 public void maybeUpdateDefaultAccount() {
141 final List<AccountWithDataSet> currentWritableAccounts = getWritableAccounts();
142 if (currentWritableAccounts.size() == 1) {
143 final AccountWithDataSet onlyAccount = currentWritableAccounts.get(0);
144 if (!onlyAccount.isNullAccount()
145 && !onlyAccount.equals(mContactsPrefs.getDefaultAccount())) {
146 mContactsPrefs.setDefaultAccount(onlyAccount);
147 }
148 }
149 }
150
Makoto Onuki558669d2011-09-22 18:09:28 -0700151 /**
Marcus Hagerottf0e140a2016-12-05 16:59:48 -0800152 * Parses a result from {@link AccountManager#newChooseAccountIntent(Account, List, String[],
153 * String, String, String[], Bundle)} and returns the created {@link Account}, or null if
154 * the user has canceled the wizard.
Makoto Onuki558669d2011-09-22 18:09:28 -0700155 *
Marcus Hagerottf0e140a2016-12-05 16:59:48 -0800156 * <p>Pass the {@code resultCode} and {@code data} parameters passed to
157 * {@link Activity#onActivityResult} or {@link android.app.Fragment#onActivityResult}.
158 * </p>
Makoto Onuki558669d2011-09-22 18:09:28 -0700159 *
Marcus Hagerottf0e140a2016-12-05 16:59:48 -0800160 * <p>
Makoto Onuki558669d2011-09-22 18:09:28 -0700161 * Note although the return type is {@link AccountWithDataSet}, return values from this method
162 * will never have {@link AccountWithDataSet#dataSet} set, as there's no way to create an
163 * extension package account from setup wizard.
Marcus Hagerottf0e140a2016-12-05 16:59:48 -0800164 * </p>
Makoto Onuki558669d2011-09-22 18:09:28 -0700165 */
Makoto Onuki558669d2011-09-22 18:09:28 -0700166 public AccountWithDataSet getCreatedAccount(int resultCode, Intent resultData) {
167 // Javadoc doesn't say anything about resultCode but that the data intent will be non null
168 // on success.
169 if (resultData == null) return null;
170
171 final String accountType = resultData.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
172 final String accountName = resultData.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
173
174 // Just in case
175 if (TextUtils.isEmpty(accountType) || TextUtils.isEmpty(accountName)) return null;
176
177 return new AccountWithDataSet(accountName, accountType, null);
178 }
179}