13f990ba4e35a99078d831c041290e574a320caa5Walter Jang/* 23f990ba4e35a99078d831c041290e574a320caa5Walter Jang * Copyright (C) 2015 The Android Open Source Project 33f990ba4e35a99078d831c041290e574a320caa5Walter Jang * 43f990ba4e35a99078d831c041290e574a320caa5Walter Jang * Licensed under the Apache License, Version 2.0 (the "License"); 53f990ba4e35a99078d831c041290e574a320caa5Walter Jang * you may not use this file except in compliance with the License. 63f990ba4e35a99078d831c041290e574a320caa5Walter Jang * You may obtain a copy of the License at 73f990ba4e35a99078d831c041290e574a320caa5Walter Jang * 83f990ba4e35a99078d831c041290e574a320caa5Walter Jang * http://www.apache.org/licenses/LICENSE-2.0 93f990ba4e35a99078d831c041290e574a320caa5Walter Jang * 103f990ba4e35a99078d831c041290e574a320caa5Walter Jang * Unless required by applicable law or agreed to in writing, software 113f990ba4e35a99078d831c041290e574a320caa5Walter Jang * distributed under the License is distributed on an "AS IS" BASIS, 123f990ba4e35a99078d831c041290e574a320caa5Walter Jang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133f990ba4e35a99078d831c041290e574a320caa5Walter Jang * See the License for the specific language governing permissions and 143f990ba4e35a99078d831c041290e574a320caa5Walter Jang * limitations under the License 153f990ba4e35a99078d831c041290e574a320caa5Walter Jang */ 163f990ba4e35a99078d831c041290e574a320caa5Walter Jang 173f990ba4e35a99078d831c041290e574a320caa5Walter Jangpackage com.android.contacts.editor; 183f990ba4e35a99078d831c041290e574a320caa5Walter Jang 197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.accounts.Account; 2049ed2033f83005f92c30068ae33c3138d75e1825Walter Jangimport android.app.Activity; 217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.app.Fragment; 227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.app.LoaderManager; 23e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskeyimport android.content.ContentResolver; 247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.content.ContentUris; 257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.content.ContentValues; 267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.content.Context; 277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.content.CursorLoader; 283f990ba4e35a99078d831c041290e574a320caa5Walter Jangimport android.content.Intent; 297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.content.Loader; 307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.database.Cursor; 313efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jangimport android.graphics.Bitmap; 323efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jangimport android.net.Uri; 333f990ba4e35a99078d831c041290e574a320caa5Walter Jangimport android.os.Bundle; 347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.os.SystemClock; 357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.provider.ContactsContract; 367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.provider.ContactsContract.CommonDataKinds.Email; 377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.provider.ContactsContract.CommonDataKinds.Event; 387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.provider.ContactsContract.CommonDataKinds.Organization; 397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.provider.ContactsContract.CommonDataKinds.Phone; 407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal; 427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.provider.ContactsContract.Intents; 437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.provider.ContactsContract.RawContacts; 44c40f3e945c43ff1ff90abb7fb2daf56aba315e10Gary Maiimport android.support.v7.widget.Toolbar; 45e394595987e288807b8c02c78d7d33e854f152b1Walter Jangimport android.text.TextUtils; 46cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jangimport android.util.Log; 473f990ba4e35a99078d831c041290e574a320caa5Walter Jangimport android.view.LayoutInflater; 487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.view.Menu; 497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.view.MenuInflater; 50c90cc15b804fb00339a3b98e5c951549f9b03599Walter Jangimport android.view.MenuItem; 513f990ba4e35a99078d831c041290e574a320caa5Walter Jangimport android.view.View; 523f990ba4e35a99078d831c041290e574a320caa5Walter Jangimport android.view.ViewGroup; 537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.widget.AdapterView; 547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.widget.BaseAdapter; 553f990ba4e35a99078d831c041290e574a320caa5Walter Jangimport android.widget.LinearLayout; 567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport android.widget.ListPopupWindow; 5779658e14360a4ec75530a9dcae338f48c9d5f043Walter Jangimport android.widget.Toast; 583f990ba4e35a99078d831c041290e574a320caa5Walter Jang 597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport com.android.contacts.ContactSaveService; 607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport com.android.contacts.GroupMetaDataLoader; 617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport com.android.contacts.R; 62a4adae163d83db9226b831f8c9705914e68b5cd1Gary Maiimport com.android.contacts.activities.ContactEditorAccountsChangedActivity; 63363af60ea23e5a3b945005712a16564ab69db18bGary Maiimport com.android.contacts.activities.ContactEditorActivity; 64363af60ea23e5a3b945005712a16564ab69db18bGary Maiimport com.android.contacts.activities.ContactEditorActivity.ContactEditor; 657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport com.android.contacts.activities.ContactSelectionActivity; 661e899dc127a212bfd2198fe7adba5c33eb4cd751Gary Maiimport com.android.contacts.activities.RequestPermissionsActivity; 670a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.editor.AggregationSuggestionEngine.Suggestion; 680a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.group.GroupUtil; 690a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.list.UiIntentActions; 7069c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.logging.ScreenEvent.ScreenType; 7169c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.AccountTypeManager; 7269c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.Contact; 7369c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.ContactLoader; 7469c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.RawContact; 7569c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.RawContactDelta; 7669c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.RawContactDeltaList; 7769c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.RawContactModifier; 7869c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.ValuesDelta; 794bd50d69d2b8934dbd4cbd634ad83807d9b02735Marcus Hagerottimport com.android.contacts.model.account.AccountInfo; 8069c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.account.AccountType; 8169c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.account.AccountWithDataSet; 824bd50d69d2b8934dbd4cbd634ad83807d9b02735Marcus Hagerottimport com.android.contacts.model.account.AccountsLoader; 8369c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.preference.ContactsPreferences; 84e48746654178e9448819f86b3129fd32f539b3c9Gary Maiimport com.android.contacts.quickcontact.InvisibleContactUtil; 857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport com.android.contacts.quickcontact.QuickContactActivity; 860a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.util.ContactDisplayUtils; 877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport com.android.contacts.util.ContactPhotoUtils; 880a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.util.ImplicitIntentsUtil; 890a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.util.MaterialColorMapUtils; 907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport com.android.contacts.util.UiClosables; 91a4adae163d83db9226b831f8c9705914e68b5cd1Gary Maiimport com.android.contactsbind.HelpUtils; 928d26c0a7214cf6520a4def851afa138a133a68a2Walter Jang 93807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerottimport com.google.common.base.Preconditions; 947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport com.google.common.collect.ImmutableList; 957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport com.google.common.collect.Lists; 967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 973efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jangimport java.io.FileNotFoundException; 9831a74ad969b650eb733e536569254ed3978c4f54Walter Jangimport java.util.ArrayList; 994bd50d69d2b8934dbd4cbd634ad83807d9b02735Marcus Hagerottimport java.util.Collections; 1007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport java.util.HashSet; 1017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport java.util.Iterator; 1027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport java.util.List; 1037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport java.util.Set; 1043efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang 1053f990ba4e35a99078d831c041290e574a320caa5Walter Jang/** 1063f990ba4e35a99078d831c041290e574a320caa5Walter Jang * Contact editor with only the most important fields displayed initially. 1073f990ba4e35a99078d831c041290e574a320caa5Walter Jang */ 108363af60ea23e5a3b945005712a16564ab69db18bGary Maipublic class ContactEditorFragment extends Fragment implements 1097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang ContactEditor, SplitContactConfirmationDialogFragment.Listener, 1107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang JoinContactConfirmationDialogFragment.Listener, 1117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang AggregationSuggestionEngine.Listener, AggregationSuggestionView.Listener, 1127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang CancelEditDialogFragment.Listener, 1138c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott RawContactEditorView.Listener, PhotoEditorView.Listener, 1148c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott AccountsLoader.AccountsListener { 1153f990ba4e35a99078d831c041290e574a320caa5Walter Jang 1167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang static final String TAG = "ContactEditor"; 1177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final int LOADER_CONTACT = 1; 1197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final int LOADER_GROUPS = 2; 1204bd50d69d2b8934dbd4cbd634ad83807d9b02735Marcus Hagerott private static final int LOADER_ACCOUNTS = 3; 1217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1223efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang private static final String KEY_PHOTO_RAW_CONTACT_ID = "photo_raw_contact_id"; 12328a27279554af7b1e5ff664d3da97954c462a797Walter Jang private static final String KEY_UPDATED_PHOTOS = "updated_photos"; 1243efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang 1257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final List<String> VALID_INTENT_ACTIONS = new ArrayList<String>() {{ 1267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang add(Intent.ACTION_EDIT); 1277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang add(Intent.ACTION_INSERT); 128363af60ea23e5a3b945005712a16564ab69db18bGary Mai add(ContactEditorActivity.ACTION_SAVE_COMPLETED); 1297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang }}; 1307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_ACTION = "action"; 1327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_URI = "uri"; 1337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_AUTO_ADD_TO_DEFAULT_GROUP = "autoAddToDefaultGroup"; 1347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_DISABLE_DELETE_MENU_OPTION = "disableDeleteMenuOption"; 1357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_NEW_LOCAL_PROFILE = "newLocalProfile"; 1367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_MATERIAL_PALETTE = "materialPalette"; 137c135a5d502130aee06ffcc11170513053396e9b0Gary Mai private static final String KEY_ACCOUNT = "saveToAccount"; 1387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_VIEW_ID_GENERATOR = "viewidgenerator"; 1397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_RAW_CONTACTS = "rawContacts"; 1417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_EDIT_STATE = "state"; 1437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_STATUS = "status"; 1447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_HAS_NEW_CONTACT = "hasNewContact"; 1467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_NEW_CONTACT_READY = "newContactDataReady"; 1477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_IS_EDIT = "isEdit"; 1497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_EXISTING_CONTACT_READY = "existingContactDataReady"; 1507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_IS_USER_PROFILE = "isUserProfile"; 1527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_ENABLED = "enabled"; 1547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Aggregation PopupWindow 1567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_AGGREGATION_SUGGESTIONS_RAW_CONTACT_ID = 1577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang "aggregationSuggestionsRawContactId"; 1587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Join Activity 1607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_CONTACT_ID_FOR_JOIN = "contactidforjoin"; 1617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 162698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai private static final String KEY_READ_ONLY_DISPLAY_NAME_ID = "readOnlyDisplayNameId"; 163698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai private static final String KEY_COPY_READ_ONLY_DISPLAY_NAME = "copyReadOnlyDisplayName"; 1647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected static final int REQUEST_CODE_JOIN = 0; 1667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected static final int REQUEST_CODE_ACCOUNTS_CHANGED = 1; 1677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 1697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * An intent extra that forces the editor to add the edited contact 1707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * to the default group (e.g. "My Contacts"). 1717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String INTENT_EXTRA_ADD_TO_DEFAULT_DIRECTORY = "addToDefaultDirectory"; 1737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String INTENT_EXTRA_NEW_LOCAL_PROFILE = "newLocalProfile"; 1757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String INTENT_EXTRA_DISABLE_DELETE_MENU_OPTION = 1777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang "disableDeleteMenuOption"; 1787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 1807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Intent key to pass the photo palette primary color calculated by 181363af60ea23e5a3b945005712a16564ab69db18bGary Mai * {@link com.android.contacts.quickcontact.QuickContactActivity} to the editor. 1827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String INTENT_EXTRA_MATERIAL_PALETTE_PRIMARY_COLOR = 1847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang "material_palette_primary_color"; 1857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 1877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Intent key to pass the photo palette secondary color calculated by 188363af60ea23e5a3b945005712a16564ab69db18bGary Mai * {@link com.android.contacts.quickcontact.QuickContactActivity} to the editor. 1897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String INTENT_EXTRA_MATERIAL_PALETTE_SECONDARY_COLOR = 1917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang "material_palette_secondary_color"; 1927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 1947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Intent key to pass the ID of the photo to display on the editor. 1957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 196da20b47c2b85390a2c3772379e71203c5aab513cGary Mai // TODO: This can be cleaned up if we decide to not pass the photo id through 197da20b47c2b85390a2c3772379e71203c5aab513cGary Mai // QuickContactActivity. 1987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String INTENT_EXTRA_PHOTO_ID = "photo_id"; 1997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 201a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai * Intent key to pass the ID of the raw contact id that should be displayed in the full editor 202a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai * by itself. 203a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai */ 204a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai public static final String INTENT_EXTRA_RAW_CONTACT_ID_TO_DISPLAY_ALONE = 205a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai "raw_contact_id_to_display_alone"; 206a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai 207a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai /** 2087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Intent extra to specify a {@link ContactEditor.SaveMode}. 2097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String SAVE_MODE_EXTRA_KEY = "saveMode"; 2117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Intent extra key for the contact ID to join the current contact to after saving. 2147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String JOIN_CONTACT_ID_EXTRA_KEY = "joinContactId"; 2167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Callbacks for Activities that host contact editors Fragments. 2197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public interface Listener { 2217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Contact was not found, so somehow close this fragment. This is raised after a contact 2247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * is removed via Menu/Delete 2257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang void onContactNotFound(); 2277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Contact was split, so we can close now. 2307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * 2317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param newLookupUri The lookup uri of the new contact that should be shown to the user. 2327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * The editor tries best to chose the most natural contact here. 2337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang void onContactSplit(Uri newLookupUri); 2357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * User has tapped Revert, close the fragment now. 2387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang void onReverted(); 2407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Contact was saved and the Fragment can now be closed safely. 2437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang void onSaveFinished(Intent resultIntent); 2457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 247678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai * User switched to editing a different raw contact (a suggestion from the 2487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * aggregation engine). 2497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 250678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai void onEditOtherRawContactRequested(Uri contactLookupUri, long rawContactId, 2517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang ArrayList<ContentValues> contentValues); 2527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * User has requested that contact be deleted. 2557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang void onDeleteRequested(Uri contactUri); 2577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 2587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Adapter for aggregation suggestions displayed in a PopupWindow when 2617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * editor fields change. 2627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final class AggregationSuggestionAdapter extends BaseAdapter { 2647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private final LayoutInflater mLayoutInflater; 2657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private final AggregationSuggestionView.Listener mListener; 2667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private final List<AggregationSuggestionEngine.Suggestion> mSuggestions; 2677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 268678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai public AggregationSuggestionAdapter(Activity activity, 2697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang AggregationSuggestionView.Listener listener, List<Suggestion> suggestions) { 2707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mLayoutInflater = activity.getLayoutInflater(); 2717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mListener = listener; 2727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mSuggestions = suggestions; 2737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 2747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 2767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public View getView(int position, View convertView, ViewGroup parent) { 2777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Suggestion suggestion = (Suggestion) getItem(position); 2787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final AggregationSuggestionView suggestionView = 2797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang (AggregationSuggestionView) mLayoutInflater.inflate( 2807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang R.layout.aggregation_suggestions_item, null); 2817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang suggestionView.setListener(mListener); 2827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang suggestionView.bindSuggestion(suggestion); 2837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return suggestionView; 2847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 2857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 2877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public long getItemId(int position) { 2887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return position; 2897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 2907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 2927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public Object getItem(int position) { 2937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return mSuggestions.get(position); 2947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 2957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 2977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public int getCount() { 2987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return mSuggestions.size(); 2997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 3007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 3017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected Context mContext; 3037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected Listener mListener; 3047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Views 3077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected LinearLayout mContent; 3097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected ListPopupWindow mAggregationSuggestionPopup; 3107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Parameters passed in on {@link #load} 3137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected String mAction; 3157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected Uri mLookupUri; 3167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected Bundle mIntentExtras; 3177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mAutoAddToDefaultGroup; 3187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mDisableDeleteMenuOption; 3197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mNewLocalProfile; 3207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected MaterialColorMapUtils.MaterialPalette mMaterialPalette; 3217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Helpers 3247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected ContactEditorUtils mEditorUtils; 3267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected RawContactDeltaComparator mComparator; 3277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected ViewIdGenerator mViewIdGenerator; 3287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private AggregationSuggestionEngine mAggregationSuggestionEngine; 3297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Loaded data 3327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Used to store existing contact data so it can be re-applied during a rebind call, 3347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // i.e. account switch. 3357b75145e9b4fcd46c3cbb5678f8842934467b3aaGary Mai protected Contact mContact; 3367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected ImmutableList<RawContact> mRawContacts; 3377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected Cursor mGroupMetaData; 3387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Editor state 3417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected RawContactDeltaList mState; 3437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected int mStatus; 3447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected long mRawContactIdToDisplayAlone = -1; 3457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Whether to show the new contact blank form and if it's corresponding delta is ready. 3477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mHasNewContact; 3487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected AccountWithDataSet mAccountWithDataSet; 3494bd50d69d2b8934dbd4cbd634ad83807d9b02735Marcus Hagerott protected List<AccountInfo> mWritableAccounts = Collections.emptyList(); 3507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mNewContactDataReady; 3517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mNewContactAccountChanged; 3527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Whether it's an edit of existing contact and if it's corresponding delta is ready. 3547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mIsEdit; 3557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mExistingContactDataReady; 3567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Whether we are editing the "me" profile 3587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mIsUserProfile; 3597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Whether editor views and options menu items should be enabled 3617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean mEnabled = true; 3627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Aggregation PopupWindow 3647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private long mAggregationSuggestionsRawContactId; 3657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Join Activity 3677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected long mContactIdForJoin; 3687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Used to pre-populate the editor with a display name when a user edits a read-only contact. 370698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai protected long mReadOnlyDisplayNameId; 371698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai protected boolean mCopyReadOnlyName; 3727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 3747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * The contact data loader listener. 3757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 3767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected final LoaderManager.LoaderCallbacks<Contact> mContactLoaderListener = 3777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang new LoaderManager.LoaderCallbacks<Contact>() { 3787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected long mLoaderStartTime; 3807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 3827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public Loader<Contact> onCreateLoader(int id, Bundle args) { 3837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mLoaderStartTime = SystemClock.elapsedRealtime(); 384e48746654178e9448819f86b3129fd32f539b3c9Gary Mai return new ContactLoader(mContext, mLookupUri, 385e48746654178e9448819f86b3129fd32f539b3c9Gary Mai /* postViewNotification */ true, 386e48746654178e9448819f86b3129fd32f539b3c9Gary Mai /* loadGroupMetaData */ true); 3877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 3887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 3907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onLoadFinished(Loader<Contact> loader, Contact contact) { 3917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final long loaderCurrentTime = SystemClock.elapsedRealtime(); 39257a0e98eed836b72dd3dc3540b9cac029266ed7cWenyi Wang if (Log.isLoggable(TAG, Log.VERBOSE)) { 39357a0e98eed836b72dd3dc3540b9cac029266ed7cWenyi Wang Log.v(TAG, 39457a0e98eed836b72dd3dc3540b9cac029266ed7cWenyi Wang "Time needed for loading: " + (loaderCurrentTime-mLoaderStartTime)); 39557a0e98eed836b72dd3dc3540b9cac029266ed7cWenyi Wang } 3967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!contact.isLoaded()) { 3977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Item has been deleted. Close activity without saving again. 3987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Log.i(TAG, "No contact found. Closing activity"); 3997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.CLOSING; 4007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mListener != null) mListener.onContactNotFound(); 4017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 4027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.EDITING; 4057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mLookupUri = contact.getLookupUri(); 4067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final long setDataStartTime = SystemClock.elapsedRealtime(); 4077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang setState(contact); 4087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final long setDataEndTime = SystemClock.elapsedRealtime(); 40957a0e98eed836b72dd3dc3540b9cac029266ed7cWenyi Wang if (Log.isLoggable(TAG, Log.VERBOSE)) { 41057a0e98eed836b72dd3dc3540b9cac029266ed7cWenyi Wang Log.v(TAG, "Time needed for setting UI: " 41157a0e98eed836b72dd3dc3540b9cac029266ed7cWenyi Wang + (setDataEndTime - setDataStartTime)); 41257a0e98eed836b72dd3dc3540b9cac029266ed7cWenyi Wang } 4137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 4167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onLoaderReset(Loader<Contact> loader) { 4177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang }; 4197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 4217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * The groups meta data loader listener. 4227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 4237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected final LoaderManager.LoaderCallbacks<Cursor> mGroupsLoaderListener = 4247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang new LoaderManager.LoaderCallbacks<Cursor>() { 4257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 4277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public CursorLoader onCreateLoader(int id, Bundle args) { 4285c1bff2efa542ea112c3f2a1d1ed1e271c7691a7Gary Mai return new GroupMetaDataLoader(mContext, ContactsContract.Groups.CONTENT_URI, 4295c1bff2efa542ea112c3f2a1d1ed1e271c7691a7Gary Mai GroupUtil.ALL_GROUPS_SELECTION); 4307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 4337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 4347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mGroupMetaData = data; 4357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang setGroupMetaData(); 4367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 4397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onLoaderReset(Loader<Cursor> loader) { 4407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang }; 4427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4433efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang private long mPhotoRawContactId; 44428a27279554af7b1e5ff664d3da97954c462a797Walter Jang private Bundle mUpdatedPhotos = new Bundle(); 4453efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang 4463efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang @Override 4477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public Context getContext() { 4487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return getActivity(); 4497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 4527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onAttach(Activity activity) { 4537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang super.onAttach(activity); 4547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mContext = activity; 455a7978d5bc3fcbe62a40e59e29aebea668385a98aMarcus Hagerott mEditorUtils = ContactEditorUtils.create(mContext); 4567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mComparator = new RawContactDeltaComparator(mContext); 4577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 4603efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang public void onCreate(Bundle savedState) { 4617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (savedState != null) { 4627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Restore mUri before calling super.onCreate so that onInitializeLoaders 4637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // would already have a uri and an action to work with 4647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAction = savedState.getString(KEY_ACTION); 4657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mLookupUri = savedState.getParcelable(KEY_URI); 4667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4683efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang super.onCreate(savedState); 4693efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang 4707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (savedState == null) { 4717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mViewIdGenerator = new ViewIdGenerator(); 4727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // mState can still be null because it may not have have finished loading before 4747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // onSaveInstanceState was called. 4757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState = new RawContactDeltaList(); 4767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 4777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mViewIdGenerator = savedState.getParcelable(KEY_VIEW_ID_GENERATOR); 4787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAutoAddToDefaultGroup = savedState.getBoolean(KEY_AUTO_ADD_TO_DEFAULT_GROUP); 4807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mDisableDeleteMenuOption = savedState.getBoolean(KEY_DISABLE_DELETE_MENU_OPTION); 4817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mNewLocalProfile = savedState.getBoolean(KEY_NEW_LOCAL_PROFILE); 4827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mMaterialPalette = savedState.getParcelable(KEY_MATERIAL_PALETTE); 483c135a5d502130aee06ffcc11170513053396e9b0Gary Mai mAccountWithDataSet = savedState.getParcelable(KEY_ACCOUNT); 4847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mRawContacts = ImmutableList.copyOf(savedState.<RawContact>getParcelableArrayList( 4857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang KEY_RAW_CONTACTS)); 4867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // NOTE: mGroupMetaData is not saved/restored 4877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Read state from savedState. No loading involved here 4897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState = savedState.<RawContactDeltaList> getParcelable(KEY_EDIT_STATE); 4907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = savedState.getInt(KEY_STATUS); 4917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mHasNewContact = savedState.getBoolean(KEY_HAS_NEW_CONTACT); 4937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mNewContactDataReady = savedState.getBoolean(KEY_NEW_CONTACT_READY); 4947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIsEdit = savedState.getBoolean(KEY_IS_EDIT); 4967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mExistingContactDataReady = savedState.getBoolean(KEY_EXISTING_CONTACT_READY); 4977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIsUserProfile = savedState.getBoolean(KEY_IS_USER_PROFILE); 4997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mEnabled = savedState.getBoolean(KEY_ENABLED); 5017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Aggregation PopupWindow 5037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionsRawContactId = savedState.getLong( 5047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang KEY_AGGREGATION_SUGGESTIONS_RAW_CONTACT_ID); 5057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Join Activity 5077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mContactIdForJoin = savedState.getLong(KEY_CONTACT_ID_FOR_JOIN); 5087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 509698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai mReadOnlyDisplayNameId = savedState.getLong(KEY_READ_ONLY_DISPLAY_NAME_ID); 510698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai mCopyReadOnlyName = savedState.getBoolean(KEY_COPY_READ_ONLY_DISPLAY_NAME, false); 5117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5123efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang mPhotoRawContactId = savedState.getLong(KEY_PHOTO_RAW_CONTACT_ID); 51328a27279554af7b1e5ff664d3da97954c462a797Walter Jang mUpdatedPhotos = savedState.getParcelable(KEY_UPDATED_PHOTOS); 5143efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang } 5153efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang } 5163efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang 5173f990ba4e35a99078d831c041290e574a320caa5Walter Jang @Override 5183f990ba4e35a99078d831c041290e574a320caa5Walter Jang public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) { 519ed8f6c9744dd38e089598acfba6fb90446954e6eWalter Jang setHasOptionsMenu(true); 520ed8f6c9744dd38e089598acfba6fb90446954e6eWalter Jang 5213f990ba4e35a99078d831c041290e574a320caa5Walter Jang final View view = inflater.inflate( 522363af60ea23e5a3b945005712a16564ab69db18bGary Mai R.layout.contact_editor_fragment, container, false); 523f5dfea4a5c94382a632eae5c538881f7da726a50Walter Jang mContent = (LinearLayout) view.findViewById(R.id.raw_contacts_editor_view); 5243f990ba4e35a99078d831c041290e574a320caa5Walter Jang return view; 5253f990ba4e35a99078d831c041290e574a320caa5Walter Jang } 5263f990ba4e35a99078d831c041290e574a320caa5Walter Jang 527ed8f6c9744dd38e089598acfba6fb90446954e6eWalter Jang @Override 5287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onActivityCreated(Bundle savedInstanceState) { 5297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang super.onActivityCreated(savedInstanceState); 5307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang validateAction(mAction); 5327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mState.isEmpty()) { 5347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // The delta list may not have finished loading before orientation change happens. 5357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // In this case, there will be a saved state but deltas will be missing. Reload from 5367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // database. 5377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (Intent.ACTION_EDIT.equals(mAction)) { 5387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Either 5397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 1) orientation change but load never finished. 5407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 2) not an orientation change so data needs to be loaded for first time. 5417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang getLoaderManager().initLoader(LOADER_CONTACT, null, mContactLoaderListener); 5427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang getLoaderManager().initLoader(LOADER_GROUPS, null, mGroupsLoaderListener); 5437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 5457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Orientation change, we already have mState, it was loaded by onCreate 5467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang bindEditors(); 5477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Handle initial actions only when existing state missing 5507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (savedInstanceState == null) { 551807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott if (mIntentExtras != null) { 552807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott final Account account = mIntentExtras == null ? null : 553807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott (Account) mIntentExtras.getParcelable(Intents.Insert.EXTRA_ACCOUNT); 554807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott final String dataSet = mIntentExtras == null ? null : 555807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott mIntentExtras.getString(Intents.Insert.EXTRA_DATA_SET); 556807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott mAccountWithDataSet = account != null 557807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott ? new AccountWithDataSet(account.name, account.type, dataSet) 558807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott : mIntentExtras.<AccountWithDataSet>getParcelable( 559807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott ContactEditorActivity.EXTRA_ACCOUNT_WITH_DATA_SET); 5607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (Intent.ACTION_EDIT.equals(mAction)) { 5637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIsEdit = true; 5647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else if (Intent.ACTION_INSERT.equals(mAction)) { 5657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mHasNewContact = true; 5667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mAccountWithDataSet != null) { 5677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang createContact(mAccountWithDataSet); 568807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott } // else wait for accounts to be loaded 5697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 571807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott 572807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott if (mHasNewContact) { 5738c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott AccountsLoader.loadAccounts(this, LOADER_ACCOUNTS, AccountTypeManager.writableFilter()); 574807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott } 5757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 5787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Checks if the requested action is valid. 5797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * 5807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param action The action to test. 5817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @throws IllegalArgumentException when the action is invalid. 5827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 5837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static void validateAction(String action) { 5847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (VALID_INTENT_ACTIONS.contains(action)) { 5857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 5867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang throw new IllegalArgumentException( 5887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang "Unknown action " + action + "; Supported actions: " + VALID_INTENT_ACTIONS); 5897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 5923efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang public void onSaveInstanceState(Bundle outState) { 5937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putString(KEY_ACTION, mAction); 5947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putParcelable(KEY_URI, mLookupUri); 5957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_AUTO_ADD_TO_DEFAULT_GROUP, mAutoAddToDefaultGroup); 5967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_DISABLE_DELETE_MENU_OPTION, mDisableDeleteMenuOption); 5977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_NEW_LOCAL_PROFILE, mNewLocalProfile); 5987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mMaterialPalette != null) { 5997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putParcelable(KEY_MATERIAL_PALETTE, mMaterialPalette); 6007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putParcelable(KEY_VIEW_ID_GENERATOR, mViewIdGenerator); 6027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putParcelableArrayList(KEY_RAW_CONTACTS, mRawContacts == null ? 6047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Lists.<RawContact>newArrayList() : Lists.newArrayList(mRawContacts)); 6057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // NOTE: mGroupMetaData is not saved 6067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 60736ceb4235ed685a222af86076dcf160ba124a583Gary Mai outState.putParcelable(KEY_EDIT_STATE, mState); 6087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putInt(KEY_STATUS, mStatus); 6097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_HAS_NEW_CONTACT, mHasNewContact); 6107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_NEW_CONTACT_READY, mNewContactDataReady); 6117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_IS_EDIT, mIsEdit); 6127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_EXISTING_CONTACT_READY, mExistingContactDataReady); 613c135a5d502130aee06ffcc11170513053396e9b0Gary Mai outState.putParcelable(KEY_ACCOUNT, mAccountWithDataSet); 6147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_IS_USER_PROFILE, mIsUserProfile); 6157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_ENABLED, mEnabled); 6177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Aggregation PopupWindow 6197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putLong(KEY_AGGREGATION_SUGGESTIONS_RAW_CONTACT_ID, 6207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionsRawContactId); 6217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Join Activity 6237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putLong(KEY_CONTACT_ID_FOR_JOIN, mContactIdForJoin); 6247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 625698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai outState.putLong(KEY_READ_ONLY_DISPLAY_NAME_ID, mReadOnlyDisplayNameId); 626698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai outState.putBoolean(KEY_COPY_READ_ONLY_DISPLAY_NAME, mCopyReadOnlyName); 6277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6283efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang outState.putLong(KEY_PHOTO_RAW_CONTACT_ID, mPhotoRawContactId); 62928a27279554af7b1e5ff664d3da97954c462a797Walter Jang outState.putParcelable(KEY_UPDATED_PHOTOS, mUpdatedPhotos); 6303efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang super.onSaveInstanceState(outState); 6313efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang } 6323efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang 6333efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang @Override 6347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onStop() { 6357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang super.onStop(); 6367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang UiClosables.closeQuietly(mAggregationSuggestionPopup); 6377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 6407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onDestroy() { 6417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang super.onDestroy(); 6427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mAggregationSuggestionEngine != null) { 6437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionEngine.quit(); 6447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 6487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onActivityResult(int requestCode, int resultCode, Intent data) { 6497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang switch (requestCode) { 6507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case REQUEST_CODE_JOIN: { 6517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Ignore failed requests 6527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (resultCode != Activity.RESULT_OK) return; 6537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (data != null) { 6547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final long contactId = ContentUris.parseId(data.getData()); 6557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (hasPendingChanges()) { 6567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Ask the user if they want to save changes before doing the join 6577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang JoinContactConfirmationDialogFragment.show(this, contactId); 6587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 6597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Do the join immediately 6607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang joinAggregate(contactId); 6617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 6647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case REQUEST_CODE_ACCOUNTS_CHANGED: { 6667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Bail if the account selector was not successful. 667807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott if (resultCode != Activity.RESULT_OK || data == null || 668807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott !data.hasExtra(Intents.Insert.EXTRA_ACCOUNT)) { 6697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mListener != null) { 6707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mListener.onReverted(); 6717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 6737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 674807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott AccountWithDataSet account = data.getParcelableExtra( 675807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott Intents.Insert.EXTRA_ACCOUNT); 676807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott createContact(account); 6777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 6787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6828c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott @Override 6838c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott public void onAccountsLoaded(List<AccountInfo> data) { 6848c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott mWritableAccounts = data; 6858c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott // The user may need to select a new account to save to 6868c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott if (mAccountWithDataSet == null && mHasNewContact) { 6878c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott selectAccountAndCreateContact(); 6888c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott } 6898c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott 6908c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott final RawContactEditorView view = getContent(); 6918c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott if (view == null) { 6928c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott return; 6938c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott } 6948c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott view.setAccounts(data); 6958c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott if (mAccountWithDataSet == null && view.getCurrentRawContactDelta() == null) { 6968c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott return; 6978c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott } 6988c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott 6998c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott final AccountWithDataSet account = mAccountWithDataSet != null 7008c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott ? mAccountWithDataSet 7018c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott : view.getCurrentRawContactDelta().getAccountWithDataSet(); 7028c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott 7038c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott // The current account was removed 7048c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott if (!AccountInfo.contains(data, account) && !data.isEmpty()) { 7058c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott if (isReadyToBindEditors()) { 7068c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott onRebindEditorsForNewContact(getContent().getCurrentRawContactDelta(), 7078c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott account, data.get(0).getAccount()); 7088c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott } else { 7098c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott mAccountWithDataSet = data.get(0).getAccount(); 7108c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott } 7118c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott } 7128c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott } 7138c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott 7147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 7157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Options menu 7167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 7177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 7197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onCreateOptionsMenu(Menu menu, final MenuInflater inflater) { 7207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang inflater.inflate(R.menu.edit_contact, menu); 7217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 7247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onPrepareOptionsMenu(Menu menu) { 7257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // This supports the keyboard shortcut to save changes to a contact but shouldn't be visible 7267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // because the custom action bar contains the "save" button now (not the overflow menu). 7277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // TODO: Find a better way to handle shortcuts, i.e. onKeyDown()? 7287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final MenuItem saveMenu = menu.findItem(R.id.menu_save); 7297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final MenuItem splitMenu = menu.findItem(R.id.menu_split); 7307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final MenuItem joinMenu = menu.findItem(R.id.menu_join); 7317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final MenuItem deleteMenu = menu.findItem(R.id.menu_delete); 7327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7335eda257528e45fe6ae59cca3f1178590b53662f8Gary Mai // TODO: b/30771904, b/31827701, temporarily disable these items until we get them to work 7345eda257528e45fe6ae59cca3f1178590b53662f8Gary Mai // on a raw contact level. 7355eda257528e45fe6ae59cca3f1178590b53662f8Gary Mai joinMenu.setVisible(false); 7365eda257528e45fe6ae59cca3f1178590b53662f8Gary Mai splitMenu.setVisible(false); 7375eda257528e45fe6ae59cca3f1178590b53662f8Gary Mai deleteMenu.setVisible(false); 7387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Save menu is invisible when there's only one read only contact in the editor. 739d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai saveMenu.setVisible(!isEditingReadOnlyRawContact()); 7407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (saveMenu.isVisible()) { 7417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Since we're using a custom action layout we have to manually hook up the handler. 7427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang saveMenu.getActionView().setOnClickListener(new View.OnClickListener() { 7437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 7447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onClick(View v) { 7457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang onOptionsItemSelected(saveMenu); 7467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang }); 7487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang int size = menu.size(); 7517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang for (int i = 0; i < size; i++) { 7527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang menu.getItem(i).setEnabled(mEnabled); 7537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 757c90cc15b804fb00339a3b98e5c951549f9b03599Walter Jang public boolean onOptionsItemSelected(MenuItem item) { 758c90cc15b804fb00339a3b98e5c951549f9b03599Walter Jang if (item.getItemId() == android.R.id.home) { 759c90cc15b804fb00339a3b98e5c951549f9b03599Walter Jang return revert(); 760c90cc15b804fb00339a3b98e5c951549f9b03599Walter Jang } 7617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Activity activity = getActivity(); 7637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (activity == null || activity.isFinishing() || activity.isDestroyed()) { 7647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If we no longer are attached to a running activity want to 7657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // drain this event. 7667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 7677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 769b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott final int id = item.getItemId(); 770b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott if (id == R.id.menu_save) { 771b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott return save(SaveMode.CLOSE); 772b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott } else if (id == R.id.menu_delete) { 773b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott if (mListener != null) mListener.onDeleteRequested(mLookupUri); 774b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott return true; 775b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott } else if (id == R.id.menu_split) { 776b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott return doSplitContactAction(); 777b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott } else if (id == R.id.menu_join) { 778b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott return doJoinContactAction(); 779b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott } else if (id == R.id.menu_help) { 780b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott HelpUtils.launchHelpAndFeedbackForContactScreen(getActivity()); 781b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott return true; 7827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return false; 7857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 7887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public boolean revert() { 7897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mState.isEmpty() || !hasPendingChanges()) { 7907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang onCancelEditConfirmed(); 7917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 7927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang CancelEditDialogFragment.show(this); 7937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 7957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 7987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onCancelEditConfirmed() { 7997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // When this Fragment is closed we don't want it to auto-save 8007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.CLOSING; 8017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mListener != null) { 8027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mListener.onReverted(); 8037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 8077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onSplitContactConfirmed(boolean hasPendingChanges) { 8087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mState.isEmpty()) { 8097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // This may happen when this Fragment is recreated by the system during users 8107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // confirming the split action (and thus this method is called just before onCreate()), 8117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // for example. 8127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Log.e(TAG, "mState became null during the user's confirming split action. " + 8137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang "Cannot perform the save action."); 8147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 8157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!hasPendingChanges && mHasNewContact) { 8187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If the user didn't add anything new, we don't want to split out the newly created 8197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // raw contact into a name-only contact so remove them. 8207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Iterator<RawContactDelta> iterator = mState.iterator(); 8217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang while (iterator.hasNext()) { 8227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final RawContactDelta rawContactDelta = iterator.next(); 8237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (rawContactDelta.getRawContactId() < 0) { 8247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang iterator.remove(); 8257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState.markRawContactsForSplitting(); 8297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang save(SaveMode.SPLIT); 8307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 832b9065ddb28a2040cabda251891be2062b5260217Gary Mai @Override 833b9065ddb28a2040cabda251891be2062b5260217Gary Mai public void onSplitContactCanceled() {} 834b9065ddb28a2040cabda251891be2062b5260217Gary Mai 8357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean doSplitContactAction() { 8367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!hasValidState()) return false; 8377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang SplitContactConfirmationDialogFragment.show(this, hasPendingChanges()); 8397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 8407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean doJoinContactAction() { 8437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!hasValidState() || mLookupUri == null) { 8447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return false; 8457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If we just started creating a new contact and haven't added any data, it's too 8487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // early to do a join 8497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mState.size() == 1 && mState.get(0).isContactInsert() 8507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang && !hasPendingChanges()) { 8517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Toast.makeText(mContext, R.string.toast_join_with_empty_contact, 8527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Toast.LENGTH_LONG).show(); 8537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 8547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang showJoinAggregateActivity(mLookupUri); 8577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 8587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 8617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onJoinContactConfirmed(long joinContactId) { 8627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang doSaveAction(SaveMode.JOIN, joinContactId); 8637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 865c90cc15b804fb00339a3b98e5c951549f9b03599Walter Jang @Override 8667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public boolean save(int saveMode) { 8677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!hasValidState() || mStatus != Status.EDITING) { 8687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return false; 8697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If we are about to close the editor - there is no need to refresh the data 872363af60ea23e5a3b945005712a16564ab69db18bGary Mai if (saveMode == SaveMode.CLOSE || saveMode == SaveMode.EDITOR 8737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang || saveMode == SaveMode.SPLIT) { 8747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang getLoaderManager().destroyLoader(LOADER_CONTACT); 8757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.SAVING; 8787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!hasPendingChanges()) { 8807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mLookupUri == null && saveMode == SaveMode.RELOAD) { 8817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // We don't have anything to save and there isn't even an existing contact yet. 8827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Nothing to do, simply go back to editing mode 8837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.EDITING; 8847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 8857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang onSaveCompleted(/* hadChanges =*/ false, saveMode, 8877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /* saveSucceeded =*/ mLookupUri != null, mLookupUri, /* joinContactId =*/ null); 8887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 8897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang setEnabled(false); 8927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return doSaveAction(saveMode, /* joinContactId */ null); 8947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 8977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // State accessor methods 8987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 8997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 9007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 9017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Check if our internal {@link #mState} is valid, usually checked before 9027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * performing user actions. 9037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 9047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean hasValidState() { 9057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return mState.size() > 0; 9067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 9077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 9087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean isEditingUserProfile() { 9097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return mNewLocalProfile || mIsUserProfile; 9107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 9117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 9127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 9135a00de39004d298de4daee3e183add5eff17102cGary Mai * Whether the contact being edited is composed of read-only raw contacts 9147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * aggregated with a newly created writable raw contact. 9157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 9167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean isEditingReadOnlyRawContactWithNewContact() { 9175a00de39004d298de4daee3e183add5eff17102cGary Mai return mHasNewContact && mState.size() > 1; 9187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 9197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 9207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 921d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai * @return true if the single raw contact we're looking at is read-only. 922d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai */ 923d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai private boolean isEditingReadOnlyRawContact() { 924d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai return hasValidState() && mRawContactIdToDisplayAlone > 0 925d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai && !mState.getByRawContactId(mRawContactIdToDisplayAlone) 926d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai .getAccountType(AccountTypeManager.getInstance(mContext)) 927d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai .areContactsWritable(); 928d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai } 929d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai 930d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai /** 9317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Return true if there are any edits to the current contact which need to 9327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * be saved. 9337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 9347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean hasPendingRawContactChanges(Set<String> excludedMimeTypes) { 9357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 9367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return RawContactModifier.hasChanges(mState, accountTypes, excludedMimeTypes); 9377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 9387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 9397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 9407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Determines if changes were made in the editor that need to be saved, while taking into 9417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * account that name changes are not real for read-only contacts. 9427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * See go/editing-read-only-contacts 9437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 9447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean hasPendingChanges() { 945698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (isEditingReadOnlyRawContactWithNewContact()) { 9467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // We created a new raw contact delta with a default display name. 9477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // We must test for pending changes while ignoring the default display name. 948698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final ValuesDelta beforeDelta = mState.getByRawContactId(mReadOnlyDisplayNameId) 949698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai .getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE); 950698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final ValuesDelta pendingDelta = mState 951698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai .getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE); 952698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (structuredNamesAreEqual(beforeDelta, pendingDelta)) { 9537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Set<String> excludedMimeTypes = new HashSet<>(); 9547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang excludedMimeTypes.add(StructuredName.CONTENT_ITEM_TYPE); 9557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return hasPendingRawContactChanges(excludedMimeTypes); 9567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 9577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 9587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 9597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return hasPendingRawContactChanges(/* excludedMimeTypes =*/ null); 9607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 9617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 9627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 963698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai * Compares the two {@link ValuesDelta} to see if the structured name is changed. We made a copy 964698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai * of a read only delta and now we want to check if the copied delta has changes. 965698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai * 966698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai * @param before original {@link ValuesDelta} 967698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai * @param after copied {@link ValuesDelta} 968698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai * @return true if the copied {@link ValuesDelta} has all the same values in the structured 969698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai * name fields as the original. 970698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai */ 971698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai private boolean structuredNamesAreEqual(ValuesDelta before, ValuesDelta after) { 9725a00de39004d298de4daee3e183add5eff17102cGary Mai if (before == after) return true; 973698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (before == null || after == null) return false; 974698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final ContentValues original = before.getBefore(); 975698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final ContentValues pending = after.getAfter(); 976698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (original != null && pending != null) { 977a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai final String beforeDisplayName = original.getAsString(StructuredName.DISPLAY_NAME); 978698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String afterDisplayName = pending.getAsString(StructuredName.DISPLAY_NAME); 979698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (!TextUtils.equals(beforeDisplayName, afterDisplayName)) return false; 980698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai 981698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String beforePrefix = original.getAsString(StructuredName.PREFIX); 982698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String afterPrefix = pending.getAsString(StructuredName.PREFIX); 983698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (!TextUtils.equals(beforePrefix, afterPrefix)) return false; 984698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai 985698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String beforeFirstName = original.getAsString(StructuredName.GIVEN_NAME); 986698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String afterFirstName = pending.getAsString(StructuredName.GIVEN_NAME); 987698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (!TextUtils.equals(beforeFirstName, afterFirstName)) return false; 988698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai 989698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String beforeMiddleName = original.getAsString(StructuredName.MIDDLE_NAME); 990698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String afterMiddleName = pending.getAsString(StructuredName.MIDDLE_NAME); 991698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (!TextUtils.equals(beforeMiddleName, afterMiddleName)) return false; 992698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai 993698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String beforeLastName = original.getAsString(StructuredName.FAMILY_NAME); 994698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String afterLastName = pending.getAsString(StructuredName.FAMILY_NAME); 995698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (!TextUtils.equals(beforeLastName, afterLastName)) return false; 996698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai 997698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String beforeSuffix = original.getAsString(StructuredName.SUFFIX); 998698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String afterSuffix = pending.getAsString(StructuredName.SUFFIX); 999698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai return TextUtils.equals(beforeSuffix, afterSuffix); 1000698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai } 1001698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai return false; 1002698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai } 1003698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai 10047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 10057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Account creation 10067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 10077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void selectAccountAndCreateContact() { 1009807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott Preconditions.checkNotNull(mWritableAccounts, "Accounts must be loaded first"); 10107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If this is a local profile, then skip the logic about showing the accounts changed 10117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // activity and create a phone-local contact. 10127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mNewLocalProfile) { 10137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang createContact(null); 10147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 10157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1017807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott final List<AccountWithDataSet> accounts = AccountInfo.extractAccounts(mWritableAccounts); 10187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If there is no default account or the accounts have changed such that we need to 10197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // prompt the user again, then launch the account prompt. 1020807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott if (mEditorUtils.shouldShowAccountChangedNotification(accounts)) { 10217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Intent intent = new Intent(mContext, ContactEditorAccountsChangedActivity.class); 10227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Prevent a second instance from being started on rotates 102380ab7ea6a518410594058c74f32c4b551097edbdMarcus Hagerott intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 10247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.SUB_ACTIVITY; 10257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang startActivityForResult(intent, REQUEST_CODE_ACCOUNTS_CHANGED); 10267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 10273107b25dcaea54943c58f984084fa9b348ea1885Gary Mai // Make sure the default account is automatically set if there is only one non-device 10283107b25dcaea54943c58f984084fa9b348ea1885Gary Mai // account. 1029807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott mEditorUtils.maybeUpdateDefaultAccount(accounts); 10307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Otherwise, there should be a default account. Then either create a local contact 10317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // (if default account is null) or create a contact with the specified account. 1032807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott AccountWithDataSet defaultAccount = mEditorUtils.getOnlyOrDefaultAccount(accounts); 10337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang createContact(defaultAccount); 10347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 10387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Shows account creation screen associated with a given account. 10397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * 10407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param account may be null to signal a device-local contact should be created. 10417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 10427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void createContact(AccountWithDataSet account) { 10437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 10447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final AccountType accountType = accountTypes.getAccountTypeForAccount(account); 10457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1046aebf3206766a05cce290245f09506adb789b6e37Gary Mai setStateForNewContact(account, accountType, isEditingUserProfile()); 10477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 10507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Data binding 10517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 10527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void setState(Contact contact) { 10547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If we have already loaded data, we do not want to change it here to not confuse the user 10557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!mState.isEmpty()) { 105657a0e98eed836b72dd3dc3540b9cac029266ed7cWenyi Wang if (Log.isLoggable(TAG, Log.VERBOSE)) { 105757a0e98eed836b72dd3dc3540b9cac029266ed7cWenyi Wang Log.v(TAG, "Ignoring background change. This will have to be rebased later"); 105857a0e98eed836b72dd3dc3540b9cac029266ed7cWenyi Wang } 10597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 10607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10617b75145e9b4fcd46c3cbb5678f8842934467b3aaGary Mai mContact = contact; 10624ceabed629c43cb247fd4a0faa36c09bd5ec999aGary Mai mRawContacts = contact.getRawContacts(); 10637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Check for writable raw contacts. If there are none, then we need to create one so user 10657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // can edit. For the user profile case, there is already an editable contact. 10667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!contact.isUserProfile() && !contact.isWritableContact(mContext)) { 10677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mHasNewContact = true; 1068698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai mReadOnlyDisplayNameId = contact.getNameRawContactId(); 1069698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai mCopyReadOnlyName = true; 10707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // This is potentially an asynchronous call and will add deltas to list. 10717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang selectAccountAndCreateContact(); 10727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 10737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mHasNewContact = false; 10747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1076698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai setStateForExistingContact(contact.isUserProfile(), mRawContacts); 1077e48746654178e9448819f86b3129fd32f539b3c9Gary Mai if (mAutoAddToDefaultGroup 1078e48746654178e9448819f86b3129fd32f539b3c9Gary Mai && InvisibleContactUtil.isInvisibleAndAddable(contact, getContext())) { 1079e48746654178e9448819f86b3129fd32f539b3c9Gary Mai InvisibleContactUtil.markAddToDefaultGroup(contact, mState, getContext()); 1080e48746654178e9448819f86b3129fd32f539b3c9Gary Mai } 10817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 10847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Prepare {@link #mState} for a newly created phone-local contact. 10857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 10867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void setStateForNewContact(AccountWithDataSet account, AccountType accountType, 10877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang boolean isUserProfile) { 10887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang setStateForNewContact(account, accountType, /* oldState =*/ null, 10897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /* oldAccountType =*/ null, isUserProfile); 10907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 10937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Prepare {@link #mState} for a newly created phone-local contact, migrating the state 10947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * specified by oldState and oldAccountType. 10957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 10967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void setStateForNewContact(AccountWithDataSet account, AccountType accountType, 10977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactDelta oldState, AccountType oldAccountType, boolean isUserProfile) { 10987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.EDITING; 10999f691e8b1c30dcdae230daebd26da0f225f74008Gary Mai mAccountWithDataSet = account; 11007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState.add(createNewRawContactDelta(account, accountType, oldState, oldAccountType)); 11017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIsUserProfile = isUserProfile; 11027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mNewContactDataReady = true; 11037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang bindEditors(); 11047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 11077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Returns a {@link RawContactDelta} for a new contact suitable for addition into 11087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * {@link #mState}. 11097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * 11107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * If oldState and oldAccountType are specified, the state specified by those parameters 11117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * is migrated to the result {@link RawContactDelta}. 11127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 11137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private RawContactDelta createNewRawContactDelta(AccountWithDataSet account, 11147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang AccountType accountType, RawContactDelta oldState, AccountType oldAccountType) { 11157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final RawContact rawContact = new RawContact(); 11167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (account != null) { 11177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang rawContact.setAccount(account); 11187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 11197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang rawContact.setAccountToLocal(); 11207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final RawContactDelta result = new RawContactDelta( 11237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang ValuesDelta.fromAfter(rawContact.getValues())); 11247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (oldState == null) { 11257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Parse any values from incoming intent 11267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactModifier.parseExtras(mContext, accountType, result, mIntentExtras); 11277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 11287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactModifier.migrateStateForNewContact( 11297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mContext, oldState, result, oldAccountType, accountType); 11307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Ensure we have some default fields (if the account type does not support a field, 11337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // ensureKind will not add it, so it is safe to add e.g. Event) 113462ec0b10c0ddc00053df39aeaed1f3316116e849Gary Mai RawContactModifier.ensureKindExists(result, accountType, StructuredName.CONTENT_ITEM_TYPE); 11357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactModifier.ensureKindExists(result, accountType, Phone.CONTENT_ITEM_TYPE); 11367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactModifier.ensureKindExists(result, accountType, Email.CONTENT_ITEM_TYPE); 11377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactModifier.ensureKindExists(result, accountType, Organization.CONTENT_ITEM_TYPE); 11387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactModifier.ensureKindExists(result, accountType, Event.CONTENT_ITEM_TYPE); 11397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactModifier.ensureKindExists(result, accountType, 11407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang StructuredPostal.CONTENT_ITEM_TYPE); 11417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Set the correct URI for saving the contact as a profile 11437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mNewLocalProfile) { 11447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang result.setProfileQueryUri(); 11457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return result; 11487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 11517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Prepare {@link #mState} for an existing contact. 11527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1153698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai private void setStateForExistingContact(boolean isUserProfile, 11547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang ImmutableList<RawContact> rawContacts) { 11557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang setEnabled(true); 11567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState.addAll(rawContacts.iterator()); 11587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang setIntentExtras(mIntentExtras); 11597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIntentExtras = null; 11607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // For user profile, change the contacts query URI 11627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIsUserProfile = isUserProfile; 11637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang boolean localProfileExists = false; 11647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mIsUserProfile) { 11667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang for (RawContactDelta rawContactDelta : mState) { 11677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // For profile contacts, we need a different query URI 11687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang rawContactDelta.setProfileQueryUri(); 11697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Try to find a local profile contact 11707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (rawContactDelta.getValues().getAsString(RawContacts.ACCOUNT_TYPE) == null) { 11717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang localProfileExists = true; 11727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Editor should always present a local profile for editing 11757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // TODO(wjang): Need to figure out when this case comes up. We can't do this if we're 11767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // going to prune all but the one raw contact that we're trying to display by itself. 11777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!localProfileExists && mRawContactIdToDisplayAlone <= 0) { 11787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState.add(createLocalRawContactDelta()); 11797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mExistingContactDataReady = true; 11827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang bindEditors(); 11837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 11867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Set the enabled state of editors. 11877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 11887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void setEnabled(boolean enabled) { 11897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mEnabled != enabled) { 11907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mEnabled = enabled; 11917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Enable/disable editors 11937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mContent != null) { 11947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang int count = mContent.getChildCount(); 11957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang for (int i = 0; i < count; i++) { 11967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mContent.getChildAt(i).setEnabled(enabled); 11977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 12007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Maybe invalidate the options menu 12017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Activity activity = getActivity(); 12027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (activity != null) activity.invalidateOptionsMenu(); 12037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 12047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 12057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 12067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 12077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Returns a {@link RawContactDelta} for a local contact suitable for addition into 12087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * {@link #mState}. 12097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 12107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static RawContactDelta createLocalRawContactDelta() { 12117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final RawContact rawContact = new RawContact(); 12127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang rawContact.setAccountToLocal(); 12137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 12147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final RawContactDelta result = new RawContactDelta( 12157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang ValuesDelta.fromAfter(rawContact.getValues())); 12167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang result.setProfileQueryUri(); 12177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 12187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return result; 12197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 12207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1221698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai private void copyReadOnlyName() { 1222698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai // We should only ever be doing this if we're creating a new writable contact to attach to 1223698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai // a read only contact. 1224698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (!isEditingReadOnlyRawContactWithNewContact()) { 1225698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai return; 1226698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai } 1227698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final int writableIndex = mState.indexOfFirstWritableRawContact(getContext()); 1228698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final RawContactDelta writable = mState.get(writableIndex); 12297b75145e9b4fcd46c3cbb5678f8842934467b3aaGary Mai final RawContactDelta readOnly = mState.getByRawContactId(mContact.getNameRawContactId()); 1230698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final ValuesDelta writeNameDelta = writable 1231698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai .getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE); 1232698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final ValuesDelta readNameDelta = readOnly 1233698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai .getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE); 1234698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai mCopyReadOnlyName = false; 1235860698b8d4542a55da5ec40032a361433b525aadGary Mai if (writeNameDelta == null || readNameDelta == null) { 1236860698b8d4542a55da5ec40032a361433b525aadGary Mai return; 1237860698b8d4542a55da5ec40032a361433b525aadGary Mai } 1238860698b8d4542a55da5ec40032a361433b525aadGary Mai writeNameDelta.copyStructuredNameFieldsFrom(readNameDelta); 1239698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai } 1240698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai 12417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 12427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Bind editors using {@link #mState} and other members initialized from the loaded (or new) 12437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Contact. 12447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1245ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang protected void bindEditors() { 1246cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang if (!isReadyToBindEditors()) { 1247cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang return; 1248cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1249cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang 1250d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang // Add input fields for the loaded Contact 1251363af60ea23e5a3b945005712a16564ab69db18bGary Mai final RawContactEditorView editorView = getContent(); 1252b6ca272f26b47ecef8fafe94326c4d553576c521Walter Jang editorView.setListener(this); 1253698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (mCopyReadOnlyName) { 1254698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai copyReadOnlyName(); 1255698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai } 1256678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai editorView.setState(mState, mMaterialPalette, mViewIdGenerator, 12579a55237f705453caae1f8aa3576a9acd7596d5ecWalter Jang mHasNewContact, mIsUserProfile, mAccountWithDataSet, 12585a00de39004d298de4daee3e183add5eff17102cGary Mai mRawContactIdToDisplayAlone); 1259079598fa2e09c22bb672715a9559b9d8973044d5Gary Mai if (isEditingReadOnlyRawContact()) { 126015646ce3e2e7a7f889976dc5684ecbc3029230c2Gary Mai final Toolbar toolbar = getEditorActivity().getToolbar(); 126115646ce3e2e7a7f889976dc5684ecbc3029230c2Gary Mai if (toolbar != null) { 126215646ce3e2e7a7f889976dc5684ecbc3029230c2Gary Mai toolbar.setTitle(R.string.contact_editor_title_read_only_contact); 1263d8f3da6a4ea4054bd47959db85657a7e01d28358Gary Mai // Set activity title for Talkback 1264d8f3da6a4ea4054bd47959db85657a7e01d28358Gary Mai getEditorActivity().setTitle(R.string.contact_editor_title_read_only_contact); 1265bd9ef3c60669d71543b3506d4959c1fe4be409dcJohn Shao toolbar.setNavigationIcon(R.drawable.quantum_ic_arrow_back_vd_theme_24); 126615646ce3e2e7a7f889976dc5684ecbc3029230c2Gary Mai toolbar.setNavigationContentDescription(R.string.back_arrow_content_description); 1267bd9ef3c60669d71543b3506d4959c1fe4be409dcJohn Shao toolbar.getNavigationIcon().setAutoMirrored(true); 1268079598fa2e09c22bb672715a9559b9d8973044d5Gary Mai } 1269079598fa2e09c22bb672715a9559b9d8973044d5Gary Mai } 1270cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang 1271d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang // Set up the photo widget 127231a74ad969b650eb733e536569254ed3978c4f54Walter Jang editorView.setPhotoListener(this); 12733efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang mPhotoRawContactId = editorView.getPhotoRawContactId(); 127431a74ad969b650eb733e536569254ed3978c4f54Walter Jang // If there is an updated full resolution photo apply it now, this will be the case if 127531a74ad969b650eb733e536569254ed3978c4f54Walter Jang // the user selects or takes a new photo, then rotates the device. 127631a74ad969b650eb733e536569254ed3978c4f54Walter Jang final Uri uri = (Uri) mUpdatedPhotos.get(String.valueOf(mPhotoRawContactId)); 127731a74ad969b650eb733e536569254ed3978c4f54Walter Jang if (uri != null) { 127831a74ad969b650eb733e536569254ed3978c4f54Walter Jang editorView.setFullSizePhoto(uri); 127941b3ea1c712f01164feb55455f1391564cb76deeWalter Jang } 12803efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang 1281d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang // The editor is ready now so make it visible 1282678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai editorView.setEnabled(mEnabled); 1283d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang editorView.setVisibility(View.VISIBLE); 1284d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang 1285d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang // Refresh the ActionBar as the visibility of the join command 1286d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang // Activity can be null if we have been detached from the Activity. 1287cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang invalidateOptionsMenu(); 1288cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1289cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang 12907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 12917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Invalidates the options menu if we are still associated with an Activity. 12927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 12937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void invalidateOptionsMenu() { 12947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Activity activity = getActivity(); 12957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (activity != null) { 12967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang activity.invalidateOptionsMenu(); 12977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 12987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 12997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1300cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang private boolean isReadyToBindEditors() { 1301cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang if (mState.isEmpty()) { 1302cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang if (Log.isLoggable(TAG, Log.VERBOSE)) { 1303cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang Log.v(TAG, "No data to bind editors"); 1304cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1305cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang return false; 1306cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1307cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang if (mIsEdit && !mExistingContactDataReady) { 1308cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang if (Log.isLoggable(TAG, Log.VERBOSE)) { 1309cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang Log.v(TAG, "Existing contact data is not ready to bind editors."); 1310cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1311cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang return false; 1312cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1313cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang if (mHasNewContact && !mNewContactDataReady) { 1314cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang if (Log.isLoggable(TAG, Log.VERBOSE)) { 1315cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang Log.v(TAG, "New contact data is not ready to bind editors."); 1316cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1317cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang return false; 1318cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 13191e899dc127a212bfd2198fe7adba5c33eb4cd751Gary Mai // Don't attempt to bind anything if we have no permissions. 13201e899dc127a212bfd2198fe7adba5c33eb4cd751Gary Mai return RequestPermissionsActivity.hasRequiredPermissions(mContext); 1321ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang } 1322ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang 13237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 13247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Removes a current editor ({@link #mState}) and rebinds new editor for a new account. 13257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Some of old data are reused with new restriction enforced by the new account. 13267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * 13277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param oldState Old data being edited. 13287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param oldAccount Old account associated with oldState. 13297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param newAccount New account to be used. 13307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 13317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void rebindEditorsForNewContact( 13327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactDelta oldState, AccountWithDataSet oldAccount, 13337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang AccountWithDataSet newAccount) { 13347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 13357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang AccountType oldAccountType = accountTypes.getAccountTypeForAccount(oldAccount); 13367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang AccountType newAccountType = accountTypes.getAccountTypeForAccount(newAccount); 13377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1338aebf3206766a05cce290245f09506adb789b6e37Gary Mai mExistingContactDataReady = false; 1339aebf3206766a05cce290245f09506adb789b6e37Gary Mai mNewContactDataReady = false; 1340aebf3206766a05cce290245f09506adb789b6e37Gary Mai mState = new RawContactDeltaList(); 1341aebf3206766a05cce290245f09506adb789b6e37Gary Mai setStateForNewContact(newAccount, newAccountType, oldState, oldAccountType, 1342aebf3206766a05cce290245f09506adb789b6e37Gary Mai isEditingUserProfile()); 1343aebf3206766a05cce290245f09506adb789b6e37Gary Mai if (mIsEdit) { 1344698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai setStateForExistingContact(isEditingUserProfile(), mRawContacts); 13457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 13467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 13477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 13487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 13497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // ContactEditor 13507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 13517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 13527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 13537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void setListener(Listener listener) { 13547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mListener = listener; 13557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 13567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 13577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 13587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void load(String action, Uri lookupUri, Bundle intentExtras) { 13597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAction = action; 13607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mLookupUri = lookupUri; 13617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIntentExtras = intentExtras; 13627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 13637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mIntentExtras != null) { 13647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAutoAddToDefaultGroup = 13657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIntentExtras.containsKey(INTENT_EXTRA_ADD_TO_DEFAULT_DIRECTORY); 13667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mNewLocalProfile = 13677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIntentExtras.getBoolean(INTENT_EXTRA_NEW_LOCAL_PROFILE); 13687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mDisableDeleteMenuOption = 13697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIntentExtras.getBoolean(INTENT_EXTRA_DISABLE_DELETE_MENU_OPTION); 13707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mIntentExtras.containsKey(INTENT_EXTRA_MATERIAL_PALETTE_PRIMARY_COLOR) 13717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang && mIntentExtras.containsKey(INTENT_EXTRA_MATERIAL_PALETTE_SECONDARY_COLOR)) { 13727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mMaterialPalette = new MaterialColorMapUtils.MaterialPalette( 13737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIntentExtras.getInt(INTENT_EXTRA_MATERIAL_PALETTE_PRIMARY_COLOR), 13747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIntentExtras.getInt(INTENT_EXTRA_MATERIAL_PALETTE_SECONDARY_COLOR)); 13757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 1376a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai mRawContactIdToDisplayAlone = mIntentExtras 1377a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai .getLong(INTENT_EXTRA_RAW_CONTACT_ID_TO_DISPLAY_ALONE); 13787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 13797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 13807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 13817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 13827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void setIntentExtras(Bundle extras) { 13835336e6ef1924162b94942cbd8f69202d553822daGary Mai getContent().setIntentExtras(extras); 13847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 13857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 13867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 13877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onJoinCompleted(Uri uri) { 13887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang onSaveCompleted(false, SaveMode.RELOAD, uri != null, uri, /* joinContactId */ null); 13897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 13907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1391e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey 1392e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey private String getNameToDisplay(Uri contactUri) { 1393c000d2ee0e292d9b160f65ab74ebd1258346046bGary Mai // The contact has been deleted or the uri is otherwise no longer right. 1394c000d2ee0e292d9b160f65ab74ebd1258346046bGary Mai if (contactUri == null) { 1395c000d2ee0e292d9b160f65ab74ebd1258346046bGary Mai return null; 1396c000d2ee0e292d9b160f65ab74ebd1258346046bGary Mai } 1397e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey final ContentResolver resolver = mContext.getContentResolver(); 1398e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey final Cursor cursor = resolver.query(contactUri, new String[]{ 1399e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey ContactsContract.Contacts.DISPLAY_NAME, 1400e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey ContactsContract.Contacts.DISPLAY_NAME_ALTERNATIVE}, null, null, null); 1401a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai 1402a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai if (cursor != null) { 1403a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai try { 1404a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai if (cursor.moveToFirst()) { 1405a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai final String displayName = cursor.getString(0); 1406a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai final String displayNameAlt = cursor.getString(1); 1407a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai cursor.close(); 1408a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai return ContactDisplayUtils.getPreferredDisplayName(displayName, displayNameAlt, 1409a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai new ContactsPreferences(mContext)); 1410a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai } 1411a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai } finally { 1412e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey cursor.close(); 1413e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey } 1414e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey } 1415e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey return null; 1416e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey } 1417e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey 1418e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey 14197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 14207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onSaveCompleted(boolean hadChanges, int saveMode, boolean saveSucceeded, 14217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Uri contactLookupUri, Long joinContactId) { 14227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (hadChanges) { 14237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (saveSucceeded) { 14247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang switch (saveMode) { 14257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case SaveMode.JOIN: 14267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 14277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case SaveMode.SPLIT: 14287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Toast.makeText(mContext, R.string.contactUnlinkedToast, Toast.LENGTH_SHORT) 14297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang .show(); 14307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 14317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang default: 1432e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey final String displayName = getNameToDisplay(contactLookupUri); 1433b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey final String toastMessage; 1434b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey if (!TextUtils.isEmpty(displayName)) { 1435b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey toastMessage = getResources().getString( 1436b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey R.string.contactSavedNamedToast, displayName); 1437b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey } else { 1438b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey toastMessage = getResources().getString(R.string.contactSavedToast); 1439b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey } 1440b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey Toast.makeText(mContext, toastMessage, Toast.LENGTH_SHORT).show(); 14417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 14437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 14447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Toast.makeText(mContext, R.string.contactSavedErrorToast, Toast.LENGTH_LONG).show(); 14457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang switch (saveMode) { 14487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case SaveMode.CLOSE: { 14498d26c0a7214cf6520a4def851afa138a133a68a2Walter Jang final Intent resultIntent; 14507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (saveSucceeded && contactLookupUri != null) { 14517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Uri lookupUri = ContactEditorUtils.maybeConvertToLegacyLookupUri( 14527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mContext, contactLookupUri, mLookupUri); 14538d26c0a7214cf6520a4def851afa138a133a68a2Walter Jang resultIntent = ImplicitIntentsUtil.composeQuickContactIntent( 14548d26c0a7214cf6520a4def851afa138a133a68a2Walter Jang mContext, lookupUri, ScreenType.EDITOR); 14558d26c0a7214cf6520a4def851afa138a133a68a2Walter Jang resultIntent.putExtra(QuickContactActivity.EXTRA_CONTACT_EDITED, true); 14567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 14577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang resultIntent = null; 14587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // It is already saved, so prevent it from being saved again 14607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.CLOSING; 14617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mListener != null) mListener.onSaveFinished(resultIntent); 14627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 14637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 1464363af60ea23e5a3b945005712a16564ab69db18bGary Mai case SaveMode.EDITOR: { 14657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // It is already saved, so prevent it from being saved again 14667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.CLOSING; 14677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mListener != null) mListener.onSaveFinished(/* resultIntent= */ null); 14687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 14697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case SaveMode.JOIN: 14717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (saveSucceeded && contactLookupUri != null && joinContactId != null) { 14727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang joinAggregate(joinContactId); 14737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 14757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case SaveMode.RELOAD: 14767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (saveSucceeded && contactLookupUri != null) { 14777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If this was in INSERT, we are changing into an EDIT now. 14787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If it already was an EDIT, we are changing to the new Uri now 14797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState = new RawContactDeltaList(); 14807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang load(Intent.ACTION_EDIT, contactLookupUri, null); 14817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.LOADING; 14827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang getLoaderManager().restartLoader(LOADER_CONTACT, null, mContactLoaderListener); 14837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 14857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 14867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case SaveMode.SPLIT: 14877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.CLOSING; 14887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mListener != null) { 14897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mListener.onContactSplit(contactLookupUri); 149057a0e98eed836b72dd3dc3540b9cac029266ed7cWenyi Wang } else if (Log.isLoggable(TAG, Log.DEBUG)) { 14917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Log.d(TAG, "No listener registered, can not call onSplitFinished"); 14927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 14947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 14977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 14987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Shows a list of aggregates that can be joined into the currently viewed aggregate. 14997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * 15007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param contactLookupUri the fresh URI for the currently edited contact (after saving it) 15017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 15027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void showJoinAggregateActivity(Uri contactLookupUri) { 15037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (contactLookupUri == null || !isAdded()) { 15047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 15057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mContactIdForJoin = ContentUris.parseId(contactLookupUri); 15087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Intent intent = new Intent(mContext, ContactSelectionActivity.class); 15097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang intent.setAction(UiIntentActions.PICK_JOIN_CONTACT_ACTION); 15107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang intent.putExtra(UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY, mContactIdForJoin); 15117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang startActivityForResult(intent, REQUEST_CODE_JOIN); 15127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 15157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Aggregation PopupWindow 15167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 15177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 15197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Triggers an asynchronous search for aggregation suggestions. 15207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 15217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected void acquireAggregationSuggestions(Context context, 15227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang long rawContactId, ValuesDelta valuesDelta) { 15237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionsRawContactId = rawContactId; 15247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mAggregationSuggestionEngine == null) { 15267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionEngine = new AggregationSuggestionEngine(context); 15277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionEngine.setListener(this); 15287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionEngine.start(); 15297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionEngine.setContactId(getContactId()); 1532220d10cd7095f5ab803ff6155d7adaa576a8c4ffGary Mai mAggregationSuggestionEngine.setAccountFilter( 1533220d10cd7095f5ab803ff6155d7adaa576a8c4ffGary Mai getContent().getCurrentRawContactDelta().getAccountWithDataSet()); 15347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionEngine.onNameChange(valuesDelta); 15367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 15397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Returns the contact ID for the currently edited contact or 0 if the contact is new. 15407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 15417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private long getContactId() { 15427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang for (RawContactDelta rawContact : mState) { 15437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Long contactId = rawContact.getValues().getAsLong(RawContacts.CONTACT_ID); 15447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (contactId != null) { 15457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return contactId; 15467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return 0; 15497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15513f990ba4e35a99078d831c041290e574a320caa5Walter Jang @Override 15527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onAggregationSuggestionChange() { 15537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Activity activity = getActivity(); 15547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if ((activity != null && activity.isFinishing()) 15557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang || !isVisible() || mState.isEmpty() || mStatus != Status.EDITING) { 15567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 15577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang UiClosables.closeQuietly(mAggregationSuggestionPopup); 15607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mAggregationSuggestionEngine.getSuggestedContactCount() == 0) { 15627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 15637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1565da20b47c2b85390a2c3772379e71203c5aab513cGary Mai final View anchorView = getAggregationAnchorView(); 15667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (anchorView == null) { 15677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; // Raw contact deleted? 15687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup = new ListPopupWindow(mContext, null); 15707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup.setAnchorView(anchorView); 15717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup.setWidth(anchorView.getWidth()); 15727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED); 15737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup.setAdapter( 15747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang new AggregationSuggestionAdapter( 15757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang getActivity(), 15767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /* listener =*/ this, 15777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionEngine.getSuggestions())); 15787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup.setOnItemClickListener(new AdapterView.OnItemClickListener() { 15797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 15807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 15817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final AggregationSuggestionView suggestionView = (AggregationSuggestionView) view; 15827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang suggestionView.handleItemClickEvent(); 15837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang UiClosables.closeQuietly(mAggregationSuggestionPopup); 15847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup = null; 15857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang }); 15877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup.show(); 15887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 1591da20b47c2b85390a2c3772379e71203c5aab513cGary Mai * Returns the editor view that should be used as the anchor for aggregation suggestions. 15927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1593da20b47c2b85390a2c3772379e71203c5aab513cGary Mai protected View getAggregationAnchorView() { 1594d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang return getContent().getAggregationAnchorView(); 1595d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang } 1596d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang 15977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 15987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Joins the suggested contact (specified by the id's of constituent raw 15997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * contacts), save all changes, and stay in the editor. 16007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 16017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void doJoinSuggestedContact(long[] rawContactIds) { 16027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!hasValidState() || mStatus != Status.EDITING) { 16037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 16047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 16057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 16067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState.setJoinWithRawContacts(rawContactIds); 16077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang save(SaveMode.RELOAD); 16087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 16097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 16107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 1611678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai public void onEditAction(Uri contactLookupUri, long rawContactId) { 1612678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai SuggestionEditConfirmationDialogFragment.show(this, contactLookupUri, rawContactId); 16137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 16147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 16157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 1616678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai * Abandons the currently edited contact and switches to editing the selected raw contact, 1617678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai * transferring all the data there 16187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1619678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai public void doEditSuggestedContact(Uri contactUri, long rawContactId) { 16207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mListener != null) { 16217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // make sure we don't save this contact when closing down 16227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.CLOSING; 1623678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai mListener.onEditOtherRawContactRequested(contactUri, rawContactId, 1624678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai getContent().getCurrentRawContactDelta().getContentValues()); 16257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 16267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 16277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 16287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 16297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Sets group metadata on all bound editors. 16307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 163192f8ccc1f15df787b7434224857c056721281046Walter Jang protected void setGroupMetaData() { 1632f10ca15ffa550b36805d2330fc210b58601a215cWalter Jang if (mGroupMetaData != null) { 1633f10ca15ffa550b36805d2330fc210b58601a215cWalter Jang getContent().setGroupMetaData(mGroupMetaData); 1634f10ca15ffa550b36805d2330fc210b58601a215cWalter Jang } 16353f990ba4e35a99078d831c041290e574a320caa5Walter Jang } 16363f990ba4e35a99078d831c041290e574a320caa5Walter Jang 16377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 16387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Persist the accumulated editor deltas. 16397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * 16407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param joinContactId the raw contact ID to join the contact being saved to after the save, 16417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * may be null. 16427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1643e3373dceb689209533e95a2cfbfbf1d9008ab6f6Walter Jang protected boolean doSaveAction(int saveMode, Long joinContactId) { 164449ed2033f83005f92c30068ae33c3138d75e1825Walter Jang final Intent intent = ContactSaveService.createSaveContactIntent(mContext, mState, 164549ed2033f83005f92c30068ae33c3138d75e1825Walter Jang SAVE_MODE_EXTRA_KEY, saveMode, isEditingUserProfile(), 164649ed2033f83005f92c30068ae33c3138d75e1825Walter Jang ((Activity) mContext).getClass(), 1647363af60ea23e5a3b945005712a16564ab69db18bGary Mai ContactEditorActivity.ACTION_SAVE_COMPLETED, mUpdatedPhotos, 1648e3373dceb689209533e95a2cfbfbf1d9008ab6f6Walter Jang JOIN_CONTACT_ID_EXTRA_KEY, joinContactId); 1649dd7d456a080f48d93aa3a9f9b04da0f17a8833a7Wenyi Wang return startSaveService(mContext, intent, saveMode); 165049ed2033f83005f92c30068ae33c3138d75e1825Walter Jang } 165149ed2033f83005f92c30068ae33c3138d75e1825Walter Jang 16527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean startSaveService(Context context, Intent intent, int saveMode) { 16537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final boolean result = ContactSaveService.startService( 16547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang context, intent, saveMode); 16557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!result) { 16567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang onCancelEditConfirmed(); 16577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 16587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return result; 16597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 16607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 16617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 16627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Join Activity 16637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 16647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 16657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 16667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Performs aggregation with the contact selected by the user from suggestions or A-Z list. 16677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 166849ed2033f83005f92c30068ae33c3138d75e1825Walter Jang protected void joinAggregate(final long contactId) { 166949ed2033f83005f92c30068ae33c3138d75e1825Walter Jang final Intent intent = ContactSaveService.createJoinContactsIntent( 1670363af60ea23e5a3b945005712a16564ab69db18bGary Mai mContext, mContactIdForJoin, contactId, ContactEditorActivity.class, 1671363af60ea23e5a3b945005712a16564ab69db18bGary Mai ContactEditorActivity.ACTION_JOIN_COMPLETED); 167249ed2033f83005f92c30068ae33c3138d75e1825Walter Jang mContext.startService(intent); 16733f990ba4e35a99078d831c041290e574a320caa5Walter Jang } 1674b6ca272f26b47ecef8fafe94326c4d553576c521Walter Jang 167531a74ad969b650eb733e536569254ed3978c4f54Walter Jang public void removePhoto() { 167631a74ad969b650eb733e536569254ed3978c4f54Walter Jang getContent().removePhoto(); 167731a74ad969b650eb733e536569254ed3978c4f54Walter Jang mUpdatedPhotos.remove(String.valueOf(mPhotoRawContactId)); 16780e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang } 16790e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang 168031a74ad969b650eb733e536569254ed3978c4f54Walter Jang public void updatePhoto(Uri uri) throws FileNotFoundException { 168131a74ad969b650eb733e536569254ed3978c4f54Walter Jang final Bitmap bitmap = ContactPhotoUtils.getBitmapFromUri(getActivity(), uri); 168231a74ad969b650eb733e536569254ed3978c4f54Walter Jang if (bitmap == null || bitmap.getHeight() <= 0 || bitmap.getWidth() <= 0) { 16839bc9ba878cf7f77a2a6b3200a6ab716d13f1affcWenyi Wang Toast.makeText(mContext, R.string.contactPhotoSavedErrorToast, 168431a74ad969b650eb733e536569254ed3978c4f54Walter Jang Toast.LENGTH_SHORT).show(); 168531a74ad969b650eb733e536569254ed3978c4f54Walter Jang return; 16860e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang } 168731a74ad969b650eb733e536569254ed3978c4f54Walter Jang mUpdatedPhotos.putParcelable(String.valueOf(mPhotoRawContactId), uri); 168831a74ad969b650eb733e536569254ed3978c4f54Walter Jang getContent().updatePhoto(uri); 16890e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang } 16900e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang 1691da20b47c2b85390a2c3772379e71203c5aab513cGary Mai public void setPrimaryPhoto() { 1692da20b47c2b85390a2c3772379e71203c5aab513cGary Mai getContent().setPrimaryPhoto(); 16930e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang } 16940e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang 16950e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang @Override 1696151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang public void onNameFieldChanged(long rawContactId, ValuesDelta valuesDelta) { 1697151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang final Activity activity = getActivity(); 1698151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang if (activity == null || activity.isFinishing()) { 1699151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang return; 1700151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 170145b86d5e83a7d6eca4abe5cdfece2e9050b1809cWalter Jang acquireAggregationSuggestions(activity, rawContactId, valuesDelta); 1702151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 1703151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang 17045a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang @Override 1705708ea9e6f6f671178c0424f89e911000d4f330dcWalter Jang public void onRebindEditorsForNewContact(RawContactDelta oldState, 1706708ea9e6f6f671178c0424f89e911000d4f330dcWalter Jang AccountWithDataSet oldAccount, AccountWithDataSet newAccount) { 1707708ea9e6f6f671178c0424f89e911000d4f330dcWalter Jang mNewContactAccountChanged = true; 1708708ea9e6f6f671178c0424f89e911000d4f330dcWalter Jang rebindEditorsForNewContact(oldState, oldAccount, newAccount); 1709708ea9e6f6f671178c0424f89e911000d4f330dcWalter Jang } 1710708ea9e6f6f671178c0424f89e911000d4f330dcWalter Jang 171179658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang @Override 171279658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang public void onBindEditorsFailed() { 171379658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang final Activity activity = getActivity(); 171479658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang if (activity != null && !activity.isFinishing()) { 1715363af60ea23e5a3b945005712a16564ab69db18bGary Mai Toast.makeText(activity, R.string.editor_failed_to_load, 171679658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang Toast.LENGTH_SHORT).show(); 171779658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang activity.setResult(Activity.RESULT_CANCELED); 171879658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang activity.finish(); 171979658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang } 172079658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang } 172179658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang 1722d675315606e8be431e6e5487e0b1cc33036a6ed7Walter Jang @Override 1723d675315606e8be431e6e5487e0b1cc33036a6ed7Walter Jang public void onEditorsBound() { 17243cb77bbf7119749ed4854a4b981fcabcf55823beWenyi Wang final Activity activity = getActivity(); 17253cb77bbf7119749ed4854a4b981fcabcf55823beWenyi Wang if (activity == null || activity.isFinishing()) { 17263cb77bbf7119749ed4854a4b981fcabcf55823beWenyi Wang return; 17273cb77bbf7119749ed4854a4b981fcabcf55823beWenyi Wang } 1728d675315606e8be431e6e5487e0b1cc33036a6ed7Walter Jang getLoaderManager().initLoader(LOADER_GROUPS, null, mGroupsLoaderListener); 1729d675315606e8be431e6e5487e0b1cc33036a6ed7Walter Jang } 1730d675315606e8be431e6e5487e0b1cc33036a6ed7Walter Jang 173131a74ad969b650eb733e536569254ed3978c4f54Walter Jang @Override 173231a74ad969b650eb733e536569254ed3978c4f54Walter Jang public void onPhotoEditorViewClicked() { 17333f18d6197a54aad10bea9c5cc2c89ca82809e793Walter Jang // For contacts composed of a single writable raw contact, or raw contacts have no more 17343f18d6197a54aad10bea9c5cc2c89ca82809e793Walter Jang // than 1 photo, clicking the photo view simply opens the source photo dialog 173531a74ad969b650eb733e536569254ed3978c4f54Walter Jang getEditorActivity().changePhoto(getPhotoMode()); 173631a74ad969b650eb733e536569254ed3978c4f54Walter Jang } 173731a74ad969b650eb733e536569254ed3978c4f54Walter Jang 173831a74ad969b650eb733e536569254ed3978c4f54Walter Jang private int getPhotoMode() { 1739da20b47c2b85390a2c3772379e71203c5aab513cGary Mai return getContent().isWritablePhotoSet() ? PhotoActionPopup.Modes.WRITE_ABLE_PHOTO 1740da20b47c2b85390a2c3772379e71203c5aab513cGary Mai : PhotoActionPopup.Modes.NO_PHOTO; 174131a74ad969b650eb733e536569254ed3978c4f54Walter Jang } 174231a74ad969b650eb733e536569254ed3978c4f54Walter Jang 1743363af60ea23e5a3b945005712a16564ab69db18bGary Mai private ContactEditorActivity getEditorActivity() { 1744363af60ea23e5a3b945005712a16564ab69db18bGary Mai return (ContactEditorActivity) getActivity(); 174531a74ad969b650eb733e536569254ed3978c4f54Walter Jang } 174631a74ad969b650eb733e536569254ed3978c4f54Walter Jang 1747363af60ea23e5a3b945005712a16564ab69db18bGary Mai private RawContactEditorView getContent() { 1748363af60ea23e5a3b945005712a16564ab69db18bGary Mai return (RawContactEditorView) mContent; 17493efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang } 17503f990ba4e35a99078d831c041290e574a320caa5Walter Jang} 1751