ContactEditorFragment.java revision 8d26c0a7214cf6520a4def851afa138a133a68a2
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; 660a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.editor.AggregationSuggestionEngine.Suggestion; 670a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.group.GroupUtil; 680a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.list.UiIntentActions; 6969c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.logging.ScreenEvent.ScreenType; 7069c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.AccountTypeManager; 7169c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.Contact; 7269c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.ContactLoader; 7369c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.RawContact; 7469c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.RawContactDelta; 7569c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.RawContactDeltaList; 7669c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.RawContactModifier; 7769c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.ValuesDelta; 784bd50d69d2b8934dbd4cbd634ad83807d9b02735Marcus Hagerottimport com.android.contacts.model.account.AccountInfo; 7969c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.account.AccountType; 8069c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.account.AccountWithDataSet; 814bd50d69d2b8934dbd4cbd634ad83807d9b02735Marcus Hagerottimport com.android.contacts.model.account.AccountsLoader; 8269c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.preference.ContactsPreferences; 83e48746654178e9448819f86b3129fd32f539b3c9Gary Maiimport com.android.contacts.quickcontact.InvisibleContactUtil; 847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport com.android.contacts.quickcontact.QuickContactActivity; 850a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.util.ContactDisplayUtils; 867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport com.android.contacts.util.ContactPhotoUtils; 870a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.util.ImplicitIntentsUtil; 880a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.util.MaterialColorMapUtils; 897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport com.android.contacts.util.UiClosables; 90a4adae163d83db9226b831f8c9705914e68b5cd1Gary Maiimport com.android.contactsbind.HelpUtils; 918d26c0a7214cf6520a4def851afa138a133a68a2Walter Jang 92807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerottimport com.google.common.base.Preconditions; 937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport com.google.common.collect.ImmutableList; 947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport com.google.common.collect.Lists; 957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 963efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jangimport java.io.FileNotFoundException; 9731a74ad969b650eb733e536569254ed3978c4f54Walter Jangimport java.util.ArrayList; 984bd50d69d2b8934dbd4cbd634ad83807d9b02735Marcus Hagerottimport java.util.Collections; 997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport java.util.HashSet; 1007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport java.util.Iterator; 1017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport java.util.List; 1027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jangimport java.util.Set; 1033efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang 1043f990ba4e35a99078d831c041290e574a320caa5Walter Jang/** 1053f990ba4e35a99078d831c041290e574a320caa5Walter Jang * Contact editor with only the most important fields displayed initially. 1063f990ba4e35a99078d831c041290e574a320caa5Walter Jang */ 107363af60ea23e5a3b945005712a16564ab69db18bGary Maipublic class ContactEditorFragment extends Fragment implements 1087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang ContactEditor, SplitContactConfirmationDialogFragment.Listener, 1097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang JoinContactConfirmationDialogFragment.Listener, 1107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang AggregationSuggestionEngine.Listener, AggregationSuggestionView.Listener, 1117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang CancelEditDialogFragment.Listener, 1128c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott RawContactEditorView.Listener, PhotoEditorView.Listener, 1138c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott AccountsLoader.AccountsListener { 1143f990ba4e35a99078d831c041290e574a320caa5Walter Jang 1157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang static final String TAG = "ContactEditor"; 1167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final int LOADER_CONTACT = 1; 1187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final int LOADER_GROUPS = 2; 1194bd50d69d2b8934dbd4cbd634ad83807d9b02735Marcus Hagerott private static final int LOADER_ACCOUNTS = 3; 1207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1213efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang private static final String KEY_PHOTO_RAW_CONTACT_ID = "photo_raw_contact_id"; 12228a27279554af7b1e5ff664d3da97954c462a797Walter Jang private static final String KEY_UPDATED_PHOTOS = "updated_photos"; 1233efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang 1247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final List<String> VALID_INTENT_ACTIONS = new ArrayList<String>() {{ 1257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang add(Intent.ACTION_EDIT); 1267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang add(Intent.ACTION_INSERT); 127363af60ea23e5a3b945005712a16564ab69db18bGary Mai add(ContactEditorActivity.ACTION_SAVE_COMPLETED); 1287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang }}; 1297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_ACTION = "action"; 1317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_URI = "uri"; 1327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_AUTO_ADD_TO_DEFAULT_GROUP = "autoAddToDefaultGroup"; 1337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_DISABLE_DELETE_MENU_OPTION = "disableDeleteMenuOption"; 1347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_NEW_LOCAL_PROFILE = "newLocalProfile"; 1357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_MATERIAL_PALETTE = "materialPalette"; 136c135a5d502130aee06ffcc11170513053396e9b0Gary Mai private static final String KEY_ACCOUNT = "saveToAccount"; 1377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_VIEW_ID_GENERATOR = "viewidgenerator"; 1387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_RAW_CONTACTS = "rawContacts"; 1407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_EDIT_STATE = "state"; 1427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_STATUS = "status"; 1437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_HAS_NEW_CONTACT = "hasNewContact"; 1457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_NEW_CONTACT_READY = "newContactDataReady"; 1467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_IS_EDIT = "isEdit"; 1487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_EXISTING_CONTACT_READY = "existingContactDataReady"; 1497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_IS_USER_PROFILE = "isUserProfile"; 1517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_ENABLED = "enabled"; 1537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Aggregation PopupWindow 1557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_AGGREGATION_SUGGESTIONS_RAW_CONTACT_ID = 1567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang "aggregationSuggestionsRawContactId"; 1577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Join Activity 1597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final String KEY_CONTACT_ID_FOR_JOIN = "contactidforjoin"; 1607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 161698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai private static final String KEY_READ_ONLY_DISPLAY_NAME_ID = "readOnlyDisplayNameId"; 162698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai private static final String KEY_COPY_READ_ONLY_DISPLAY_NAME = "copyReadOnlyDisplayName"; 1637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected static final int REQUEST_CODE_JOIN = 0; 1657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected static final int REQUEST_CODE_ACCOUNTS_CHANGED = 1; 1667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 1687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * An intent extra that forces the editor to add the edited contact 1697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * to the default group (e.g. "My Contacts"). 1707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String INTENT_EXTRA_ADD_TO_DEFAULT_DIRECTORY = "addToDefaultDirectory"; 1727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String INTENT_EXTRA_NEW_LOCAL_PROFILE = "newLocalProfile"; 1747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String INTENT_EXTRA_DISABLE_DELETE_MENU_OPTION = 1767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang "disableDeleteMenuOption"; 1777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 1797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Intent key to pass the photo palette primary color calculated by 180363af60ea23e5a3b945005712a16564ab69db18bGary Mai * {@link com.android.contacts.quickcontact.QuickContactActivity} to the editor. 1817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String INTENT_EXTRA_MATERIAL_PALETTE_PRIMARY_COLOR = 1837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang "material_palette_primary_color"; 1847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 1867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Intent key to pass the photo palette secondary color calculated by 187363af60ea23e5a3b945005712a16564ab69db18bGary Mai * {@link com.android.contacts.quickcontact.QuickContactActivity} to the editor. 1887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String INTENT_EXTRA_MATERIAL_PALETTE_SECONDARY_COLOR = 1907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang "material_palette_secondary_color"; 1917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 1937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Intent key to pass the ID of the photo to display on the editor. 1947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 195da20b47c2b85390a2c3772379e71203c5aab513cGary Mai // TODO: This can be cleaned up if we decide to not pass the photo id through 196da20b47c2b85390a2c3772379e71203c5aab513cGary Mai // QuickContactActivity. 1977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String INTENT_EXTRA_PHOTO_ID = "photo_id"; 1987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 200a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai * Intent key to pass the ID of the raw contact id that should be displayed in the full editor 201a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai * by itself. 202a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai */ 203a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai public static final String INTENT_EXTRA_RAW_CONTACT_ID_TO_DISPLAY_ALONE = 204a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai "raw_contact_id_to_display_alone"; 205a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai 206a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai /** 2077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Intent extra to specify a {@link ContactEditor.SaveMode}. 2087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String SAVE_MODE_EXTRA_KEY = "saveMode"; 2107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Intent extra key for the contact ID to join the current contact to after saving. 2137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public static final String JOIN_CONTACT_ID_EXTRA_KEY = "joinContactId"; 2157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Callbacks for Activities that host contact editors Fragments. 2187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public interface Listener { 2207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Contact was not found, so somehow close this fragment. This is raised after a contact 2237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * is removed via Menu/Delete 2247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang void onContactNotFound(); 2267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Contact was split, so we can close now. 2297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * 2307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param newLookupUri The lookup uri of the new contact that should be shown to the user. 2317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * The editor tries best to chose the most natural contact here. 2327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang void onContactSplit(Uri newLookupUri); 2347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * User has tapped Revert, close the fragment now. 2377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang void onReverted(); 2397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Contact was saved and the Fragment can now be closed safely. 2427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang void onSaveFinished(Intent resultIntent); 2447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 246678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai * User switched to editing a different raw contact (a suggestion from the 2477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * aggregation engine). 2487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 249678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai void onEditOtherRawContactRequested(Uri contactLookupUri, long rawContactId, 2507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang ArrayList<ContentValues> contentValues); 2517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * User has requested that contact be deleted. 2547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang void onDeleteRequested(Uri contactUri); 2567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 2577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 2597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Adapter for aggregation suggestions displayed in a PopupWindow when 2607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * editor fields change. 2617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 2627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static final class AggregationSuggestionAdapter extends BaseAdapter { 2637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private final LayoutInflater mLayoutInflater; 2647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private final AggregationSuggestionView.Listener mListener; 2657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private final List<AggregationSuggestionEngine.Suggestion> mSuggestions; 2667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 267678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai public AggregationSuggestionAdapter(Activity activity, 2687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang AggregationSuggestionView.Listener listener, List<Suggestion> suggestions) { 2697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mLayoutInflater = activity.getLayoutInflater(); 2707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mListener = listener; 2717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mSuggestions = suggestions; 2727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 2737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 2757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public View getView(int position, View convertView, ViewGroup parent) { 2767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Suggestion suggestion = (Suggestion) getItem(position); 2777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final AggregationSuggestionView suggestionView = 2787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang (AggregationSuggestionView) mLayoutInflater.inflate( 2797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang R.layout.aggregation_suggestions_item, null); 2807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang suggestionView.setListener(mListener); 2817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang suggestionView.bindSuggestion(suggestion); 2827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return suggestionView; 2837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 2847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 2867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public long getItemId(int position) { 2877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return position; 2887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 2897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 2917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public Object getItem(int position) { 2927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return mSuggestions.get(position); 2937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 2947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 2957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 2967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public int getCount() { 2977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return mSuggestions.size(); 2987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 2997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 3007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected Context mContext; 3027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected Listener mListener; 3037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Views 3067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected LinearLayout mContent; 3087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected ListPopupWindow mAggregationSuggestionPopup; 3097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Parameters passed in on {@link #load} 3127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected String mAction; 3147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected Uri mLookupUri; 3157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected Bundle mIntentExtras; 3167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mAutoAddToDefaultGroup; 3177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mDisableDeleteMenuOption; 3187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mNewLocalProfile; 3197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected MaterialColorMapUtils.MaterialPalette mMaterialPalette; 3207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Helpers 3237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected ContactEditorUtils mEditorUtils; 3257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected RawContactDeltaComparator mComparator; 3267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected ViewIdGenerator mViewIdGenerator; 3277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private AggregationSuggestionEngine mAggregationSuggestionEngine; 3287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Loaded data 3317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Used to store existing contact data so it can be re-applied during a rebind call, 3337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // i.e. account switch. 3347b75145e9b4fcd46c3cbb5678f8842934467b3aaGary Mai protected Contact mContact; 3357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected ImmutableList<RawContact> mRawContacts; 3367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected Cursor mGroupMetaData; 3377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Editor state 3407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 3417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected RawContactDeltaList mState; 3427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected int mStatus; 3437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected long mRawContactIdToDisplayAlone = -1; 3447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Whether to show the new contact blank form and if it's corresponding delta is ready. 3467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mHasNewContact; 3477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected AccountWithDataSet mAccountWithDataSet; 3484bd50d69d2b8934dbd4cbd634ad83807d9b02735Marcus Hagerott protected List<AccountInfo> mWritableAccounts = Collections.emptyList(); 3497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mNewContactDataReady; 3507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mNewContactAccountChanged; 3517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Whether it's an edit of existing contact and if it's corresponding delta is ready. 3537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mIsEdit; 3547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mExistingContactDataReady; 3557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Whether we are editing the "me" profile 3577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected boolean mIsUserProfile; 3587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Whether editor views and options menu items should be enabled 3607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean mEnabled = true; 3617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Aggregation PopupWindow 3637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private long mAggregationSuggestionsRawContactId; 3647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Join Activity 3667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected long mContactIdForJoin; 3677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Used to pre-populate the editor with a display name when a user edits a read-only contact. 369698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai protected long mReadOnlyDisplayNameId; 370698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai protected boolean mCopyReadOnlyName; 3717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 3737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * The contact data loader listener. 3747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 3757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected final LoaderManager.LoaderCallbacks<Contact> mContactLoaderListener = 3767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang new LoaderManager.LoaderCallbacks<Contact>() { 3777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected long mLoaderStartTime; 3797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 3817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public Loader<Contact> onCreateLoader(int id, Bundle args) { 3827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mLoaderStartTime = SystemClock.elapsedRealtime(); 383e48746654178e9448819f86b3129fd32f539b3c9Gary Mai return new ContactLoader(mContext, mLookupUri, 384e48746654178e9448819f86b3129fd32f539b3c9Gary Mai /* postViewNotification */ true, 385e48746654178e9448819f86b3129fd32f539b3c9Gary Mai /* loadGroupMetaData */ true); 3867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 3877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 3887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 3897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onLoadFinished(Loader<Contact> loader, Contact contact) { 3907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final long loaderCurrentTime = SystemClock.elapsedRealtime(); 3917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Log.v(TAG, "Time needed for loading: " + (loaderCurrentTime-mLoaderStartTime)); 3927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!contact.isLoaded()) { 3937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Item has been deleted. Close activity without saving again. 3947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Log.i(TAG, "No contact found. Closing activity"); 3957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.CLOSING; 3967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mListener != null) mListener.onContactNotFound(); 3977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 3987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 3997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.EDITING; 4017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mLookupUri = contact.getLookupUri(); 4027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final long setDataStartTime = SystemClock.elapsedRealtime(); 4037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang setState(contact); 4047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final long setDataEndTime = SystemClock.elapsedRealtime(); 4057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Log.v(TAG, "Time needed for setting UI: " + (setDataEndTime - setDataStartTime)); 4077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 4107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onLoaderReset(Loader<Contact> loader) { 4117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang }; 4137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 4157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * The groups meta data loader listener. 4167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 4177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected final LoaderManager.LoaderCallbacks<Cursor> mGroupsLoaderListener = 4187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang new LoaderManager.LoaderCallbacks<Cursor>() { 4197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 4217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public CursorLoader onCreateLoader(int id, Bundle args) { 4225c1bff2efa542ea112c3f2a1d1ed1e271c7691a7Gary Mai return new GroupMetaDataLoader(mContext, ContactsContract.Groups.CONTENT_URI, 4235c1bff2efa542ea112c3f2a1d1ed1e271c7691a7Gary Mai GroupUtil.ALL_GROUPS_SELECTION); 4247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 4277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 4287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mGroupMetaData = data; 4297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang setGroupMetaData(); 4307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 4337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onLoaderReset(Loader<Cursor> loader) { 4347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang }; 4367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4373efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang private long mPhotoRawContactId; 43828a27279554af7b1e5ff664d3da97954c462a797Walter Jang private Bundle mUpdatedPhotos = new Bundle(); 4393efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang 4403efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang @Override 4417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public Context getContext() { 4427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return getActivity(); 4437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 4467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onAttach(Activity activity) { 4477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang super.onAttach(activity); 4487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mContext = activity; 449a7978d5bc3fcbe62a40e59e29aebea668385a98aMarcus Hagerott mEditorUtils = ContactEditorUtils.create(mContext); 4507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mComparator = new RawContactDeltaComparator(mContext); 4517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 4543efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang public void onCreate(Bundle savedState) { 4557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (savedState != null) { 4567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Restore mUri before calling super.onCreate so that onInitializeLoaders 4577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // would already have a uri and an action to work with 4587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAction = savedState.getString(KEY_ACTION); 4597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mLookupUri = savedState.getParcelable(KEY_URI); 4607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 4617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4623efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang super.onCreate(savedState); 4633efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang 4647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (savedState == null) { 4657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mViewIdGenerator = new ViewIdGenerator(); 4667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // mState can still be null because it may not have have finished loading before 4687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // onSaveInstanceState was called. 4697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState = new RawContactDeltaList(); 4707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 4717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mViewIdGenerator = savedState.getParcelable(KEY_VIEW_ID_GENERATOR); 4727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAutoAddToDefaultGroup = savedState.getBoolean(KEY_AUTO_ADD_TO_DEFAULT_GROUP); 4747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mDisableDeleteMenuOption = savedState.getBoolean(KEY_DISABLE_DELETE_MENU_OPTION); 4757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mNewLocalProfile = savedState.getBoolean(KEY_NEW_LOCAL_PROFILE); 4767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mMaterialPalette = savedState.getParcelable(KEY_MATERIAL_PALETTE); 477c135a5d502130aee06ffcc11170513053396e9b0Gary Mai mAccountWithDataSet = savedState.getParcelable(KEY_ACCOUNT); 4787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mRawContacts = ImmutableList.copyOf(savedState.<RawContact>getParcelableArrayList( 4797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang KEY_RAW_CONTACTS)); 4807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // NOTE: mGroupMetaData is not saved/restored 4817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Read state from savedState. No loading involved here 4837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState = savedState.<RawContactDeltaList> getParcelable(KEY_EDIT_STATE); 4847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = savedState.getInt(KEY_STATUS); 4857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mHasNewContact = savedState.getBoolean(KEY_HAS_NEW_CONTACT); 4877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mNewContactDataReady = savedState.getBoolean(KEY_NEW_CONTACT_READY); 4887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIsEdit = savedState.getBoolean(KEY_IS_EDIT); 4907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mExistingContactDataReady = savedState.getBoolean(KEY_EXISTING_CONTACT_READY); 4917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIsUserProfile = savedState.getBoolean(KEY_IS_USER_PROFILE); 4937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mEnabled = savedState.getBoolean(KEY_ENABLED); 4957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 4967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Aggregation PopupWindow 4977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionsRawContactId = savedState.getLong( 4987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang KEY_AGGREGATION_SUGGESTIONS_RAW_CONTACT_ID); 4997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Join Activity 5017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mContactIdForJoin = savedState.getLong(KEY_CONTACT_ID_FOR_JOIN); 5027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 503698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai mReadOnlyDisplayNameId = savedState.getLong(KEY_READ_ONLY_DISPLAY_NAME_ID); 504698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai mCopyReadOnlyName = savedState.getBoolean(KEY_COPY_READ_ONLY_DISPLAY_NAME, false); 5057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5063efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang mPhotoRawContactId = savedState.getLong(KEY_PHOTO_RAW_CONTACT_ID); 50728a27279554af7b1e5ff664d3da97954c462a797Walter Jang mUpdatedPhotos = savedState.getParcelable(KEY_UPDATED_PHOTOS); 5083efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang } 5093efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang } 5103efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang 5113f990ba4e35a99078d831c041290e574a320caa5Walter Jang @Override 5123f990ba4e35a99078d831c041290e574a320caa5Walter Jang public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) { 513ed8f6c9744dd38e089598acfba6fb90446954e6eWalter Jang setHasOptionsMenu(true); 514ed8f6c9744dd38e089598acfba6fb90446954e6eWalter Jang 5153f990ba4e35a99078d831c041290e574a320caa5Walter Jang final View view = inflater.inflate( 516363af60ea23e5a3b945005712a16564ab69db18bGary Mai R.layout.contact_editor_fragment, container, false); 517f5dfea4a5c94382a632eae5c538881f7da726a50Walter Jang mContent = (LinearLayout) view.findViewById(R.id.raw_contacts_editor_view); 5183f990ba4e35a99078d831c041290e574a320caa5Walter Jang return view; 5193f990ba4e35a99078d831c041290e574a320caa5Walter Jang } 5203f990ba4e35a99078d831c041290e574a320caa5Walter Jang 521ed8f6c9744dd38e089598acfba6fb90446954e6eWalter Jang @Override 5227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onActivityCreated(Bundle savedInstanceState) { 5237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang super.onActivityCreated(savedInstanceState); 5247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang validateAction(mAction); 5267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mState.isEmpty()) { 5287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // The delta list may not have finished loading before orientation change happens. 5297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // In this case, there will be a saved state but deltas will be missing. Reload from 5307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // database. 5317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (Intent.ACTION_EDIT.equals(mAction)) { 5327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Either 5337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 1) orientation change but load never finished. 5347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 2) not an orientation change so data needs to be loaded for first time. 5357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang getLoaderManager().initLoader(LOADER_CONTACT, null, mContactLoaderListener); 5367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang getLoaderManager().initLoader(LOADER_GROUPS, null, mGroupsLoaderListener); 5377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 5397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Orientation change, we already have mState, it was loaded by onCreate 5407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang bindEditors(); 5417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Handle initial actions only when existing state missing 5447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (savedInstanceState == null) { 545807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott if (mIntentExtras != null) { 546807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott final Account account = mIntentExtras == null ? null : 547807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott (Account) mIntentExtras.getParcelable(Intents.Insert.EXTRA_ACCOUNT); 548807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott final String dataSet = mIntentExtras == null ? null : 549807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott mIntentExtras.getString(Intents.Insert.EXTRA_DATA_SET); 550807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott mAccountWithDataSet = account != null 551807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott ? new AccountWithDataSet(account.name, account.type, dataSet) 552807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott : mIntentExtras.<AccountWithDataSet>getParcelable( 553807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott ContactEditorActivity.EXTRA_ACCOUNT_WITH_DATA_SET); 5547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (Intent.ACTION_EDIT.equals(mAction)) { 5577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIsEdit = true; 5587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else if (Intent.ACTION_INSERT.equals(mAction)) { 5597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mHasNewContact = true; 5607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mAccountWithDataSet != null) { 5617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang createContact(mAccountWithDataSet); 562807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott } // else wait for accounts to be loaded 5637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 565807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott 566807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott if (mHasNewContact) { 5678c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott AccountsLoader.loadAccounts(this, LOADER_ACCOUNTS, AccountTypeManager.writableFilter()); 568807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott } 5697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 5727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Checks if the requested action is valid. 5737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * 5747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param action The action to test. 5757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @throws IllegalArgumentException when the action is invalid. 5767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 5777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static void validateAction(String action) { 5787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (VALID_INTENT_ACTIONS.contains(action)) { 5797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 5807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang throw new IllegalArgumentException( 5827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang "Unknown action " + action + "; Supported actions: " + VALID_INTENT_ACTIONS); 5837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 5863efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang public void onSaveInstanceState(Bundle outState) { 5877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putString(KEY_ACTION, mAction); 5887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putParcelable(KEY_URI, mLookupUri); 5897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_AUTO_ADD_TO_DEFAULT_GROUP, mAutoAddToDefaultGroup); 5907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_DISABLE_DELETE_MENU_OPTION, mDisableDeleteMenuOption); 5917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_NEW_LOCAL_PROFILE, mNewLocalProfile); 5927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mMaterialPalette != null) { 5937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putParcelable(KEY_MATERIAL_PALETTE, mMaterialPalette); 5947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 5957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putParcelable(KEY_VIEW_ID_GENERATOR, mViewIdGenerator); 5967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 5977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putParcelableArrayList(KEY_RAW_CONTACTS, mRawContacts == null ? 5987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Lists.<RawContact>newArrayList() : Lists.newArrayList(mRawContacts)); 5997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // NOTE: mGroupMetaData is not saved 6007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 60136ceb4235ed685a222af86076dcf160ba124a583Gary Mai outState.putParcelable(KEY_EDIT_STATE, mState); 6027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putInt(KEY_STATUS, mStatus); 6037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_HAS_NEW_CONTACT, mHasNewContact); 6047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_NEW_CONTACT_READY, mNewContactDataReady); 6057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_IS_EDIT, mIsEdit); 6067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_EXISTING_CONTACT_READY, mExistingContactDataReady); 607c135a5d502130aee06ffcc11170513053396e9b0Gary Mai outState.putParcelable(KEY_ACCOUNT, mAccountWithDataSet); 6087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_IS_USER_PROFILE, mIsUserProfile); 6097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putBoolean(KEY_ENABLED, mEnabled); 6117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Aggregation PopupWindow 6137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putLong(KEY_AGGREGATION_SUGGESTIONS_RAW_CONTACT_ID, 6147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionsRawContactId); 6157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Join Activity 6177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang outState.putLong(KEY_CONTACT_ID_FOR_JOIN, mContactIdForJoin); 6187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 619698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai outState.putLong(KEY_READ_ONLY_DISPLAY_NAME_ID, mReadOnlyDisplayNameId); 620698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai outState.putBoolean(KEY_COPY_READ_ONLY_DISPLAY_NAME, mCopyReadOnlyName); 6217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6223efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang outState.putLong(KEY_PHOTO_RAW_CONTACT_ID, mPhotoRawContactId); 62328a27279554af7b1e5ff664d3da97954c462a797Walter Jang outState.putParcelable(KEY_UPDATED_PHOTOS, mUpdatedPhotos); 6243efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang super.onSaveInstanceState(outState); 6253efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang } 6263efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang 6273efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang @Override 6287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onStop() { 6297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang super.onStop(); 6307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang UiClosables.closeQuietly(mAggregationSuggestionPopup); 6317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 6347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onDestroy() { 6357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang super.onDestroy(); 6367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mAggregationSuggestionEngine != null) { 6377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionEngine.quit(); 6387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 6427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onActivityResult(int requestCode, int resultCode, Intent data) { 6437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang switch (requestCode) { 6447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case REQUEST_CODE_JOIN: { 6457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Ignore failed requests 6467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (resultCode != Activity.RESULT_OK) return; 6477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (data != null) { 6487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final long contactId = ContentUris.parseId(data.getData()); 6497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (hasPendingChanges()) { 6507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Ask the user if they want to save changes before doing the join 6517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang JoinContactConfirmationDialogFragment.show(this, contactId); 6527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 6537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Do the join immediately 6547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang joinAggregate(contactId); 6557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 6587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case REQUEST_CODE_ACCOUNTS_CHANGED: { 6607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Bail if the account selector was not successful. 661807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott if (resultCode != Activity.RESULT_OK || data == null || 662807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott !data.hasExtra(Intents.Insert.EXTRA_ACCOUNT)) { 6637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mListener != null) { 6647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mListener.onReverted(); 6657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 6677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 668807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott AccountWithDataSet account = data.getParcelableExtra( 669807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott Intents.Insert.EXTRA_ACCOUNT); 670807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott createContact(account); 6717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 6727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 6757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 6768c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott @Override 6778c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott public void onAccountsLoaded(List<AccountInfo> data) { 6788c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott mWritableAccounts = data; 6798c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott // The user may need to select a new account to save to 6808c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott if (mAccountWithDataSet == null && mHasNewContact) { 6818c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott selectAccountAndCreateContact(); 6828c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott } 6838c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott 6848c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott final RawContactEditorView view = getContent(); 6858c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott if (view == null) { 6868c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott return; 6878c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott } 6888c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott view.setAccounts(data); 6898c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott if (mAccountWithDataSet == null && view.getCurrentRawContactDelta() == null) { 6908c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott return; 6918c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott } 6928c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott 6938c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott final AccountWithDataSet account = mAccountWithDataSet != null 6948c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott ? mAccountWithDataSet 6958c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott : view.getCurrentRawContactDelta().getAccountWithDataSet(); 6968c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott 6978c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott // The current account was removed 6988c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott if (!AccountInfo.contains(data, account) && !data.isEmpty()) { 6998c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott if (isReadyToBindEditors()) { 7008c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott onRebindEditorsForNewContact(getContent().getCurrentRawContactDelta(), 7018c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott account, data.get(0).getAccount()); 7028c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott } else { 7038c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott mAccountWithDataSet = data.get(0).getAccount(); 7048c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott } 7058c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott } 7068c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott } 7078c6b5bdb3812fcbe5680fafca59d2ab9ec90d839Marcus Hagerott 7087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 7097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Options menu 7107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 7117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 7137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onCreateOptionsMenu(Menu menu, final MenuInflater inflater) { 7147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang inflater.inflate(R.menu.edit_contact, menu); 7157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 7187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onPrepareOptionsMenu(Menu menu) { 7197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // This supports the keyboard shortcut to save changes to a contact but shouldn't be visible 7207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // because the custom action bar contains the "save" button now (not the overflow menu). 7217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // TODO: Find a better way to handle shortcuts, i.e. onKeyDown()? 7227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final MenuItem saveMenu = menu.findItem(R.id.menu_save); 7237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final MenuItem splitMenu = menu.findItem(R.id.menu_split); 7247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final MenuItem joinMenu = menu.findItem(R.id.menu_join); 7257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final MenuItem deleteMenu = menu.findItem(R.id.menu_delete); 7267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7275eda257528e45fe6ae59cca3f1178590b53662f8Gary Mai // TODO: b/30771904, b/31827701, temporarily disable these items until we get them to work 7285eda257528e45fe6ae59cca3f1178590b53662f8Gary Mai // on a raw contact level. 7295eda257528e45fe6ae59cca3f1178590b53662f8Gary Mai joinMenu.setVisible(false); 7305eda257528e45fe6ae59cca3f1178590b53662f8Gary Mai splitMenu.setVisible(false); 7315eda257528e45fe6ae59cca3f1178590b53662f8Gary Mai deleteMenu.setVisible(false); 7327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Save menu is invisible when there's only one read only contact in the editor. 733d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai saveMenu.setVisible(!isEditingReadOnlyRawContact()); 7347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (saveMenu.isVisible()) { 7357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Since we're using a custom action layout we have to manually hook up the handler. 7367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang saveMenu.getActionView().setOnClickListener(new View.OnClickListener() { 7377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 7387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onClick(View v) { 7397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang onOptionsItemSelected(saveMenu); 7407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang }); 7427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang int size = menu.size(); 7457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang for (int i = 0; i < size; i++) { 7467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang menu.getItem(i).setEnabled(mEnabled); 7477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 751c90cc15b804fb00339a3b98e5c951549f9b03599Walter Jang public boolean onOptionsItemSelected(MenuItem item) { 752c90cc15b804fb00339a3b98e5c951549f9b03599Walter Jang if (item.getItemId() == android.R.id.home) { 753c90cc15b804fb00339a3b98e5c951549f9b03599Walter Jang return revert(); 754c90cc15b804fb00339a3b98e5c951549f9b03599Walter Jang } 7557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Activity activity = getActivity(); 7577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (activity == null || activity.isFinishing() || activity.isDestroyed()) { 7587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If we no longer are attached to a running activity want to 7597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // drain this event. 7607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 7617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 763b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott final int id = item.getItemId(); 764b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott if (id == R.id.menu_save) { 765b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott return save(SaveMode.CLOSE); 766b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott } else if (id == R.id.menu_delete) { 767b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott if (mListener != null) mListener.onDeleteRequested(mLookupUri); 768b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott return true; 769b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott } else if (id == R.id.menu_split) { 770b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott return doSplitContactAction(); 771b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott } else if (id == R.id.menu_join) { 772b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott return doJoinContactAction(); 773b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott } else if (id == R.id.menu_help) { 774b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott HelpUtils.launchHelpAndFeedbackForContactScreen(getActivity()); 775b697ed768fb817f94524f6c3992547665df331c4Marcus Hagerott return true; 7767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return false; 7797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 7827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public boolean revert() { 7837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mState.isEmpty() || !hasPendingChanges()) { 7847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang onCancelEditConfirmed(); 7857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 7867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang CancelEditDialogFragment.show(this); 7877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 7897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 7917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 7927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onCancelEditConfirmed() { 7937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // When this Fragment is closed we don't want it to auto-save 7947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.CLOSING; 7957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mListener != null) { 7967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mListener.onReverted(); 7977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 7997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 8017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onSplitContactConfirmed(boolean hasPendingChanges) { 8027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mState.isEmpty()) { 8037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // This may happen when this Fragment is recreated by the system during users 8047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // confirming the split action (and thus this method is called just before onCreate()), 8057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // for example. 8067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Log.e(TAG, "mState became null during the user's confirming split action. " + 8077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang "Cannot perform the save action."); 8087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 8097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!hasPendingChanges && mHasNewContact) { 8127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If the user didn't add anything new, we don't want to split out the newly created 8137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // raw contact into a name-only contact so remove them. 8147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Iterator<RawContactDelta> iterator = mState.iterator(); 8157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang while (iterator.hasNext()) { 8167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final RawContactDelta rawContactDelta = iterator.next(); 8177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (rawContactDelta.getRawContactId() < 0) { 8187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang iterator.remove(); 8197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState.markRawContactsForSplitting(); 8237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang save(SaveMode.SPLIT); 8247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 826b9065ddb28a2040cabda251891be2062b5260217Gary Mai @Override 827b9065ddb28a2040cabda251891be2062b5260217Gary Mai public void onSplitContactCanceled() {} 828b9065ddb28a2040cabda251891be2062b5260217Gary Mai 8297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean doSplitContactAction() { 8307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!hasValidState()) return false; 8317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang SplitContactConfirmationDialogFragment.show(this, hasPendingChanges()); 8337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 8347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean doJoinContactAction() { 8377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!hasValidState() || mLookupUri == null) { 8387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return false; 8397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If we just started creating a new contact and haven't added any data, it's too 8427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // early to do a join 8437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mState.size() == 1 && mState.get(0).isContactInsert() 8447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang && !hasPendingChanges()) { 8457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Toast.makeText(mContext, R.string.toast_join_with_empty_contact, 8467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Toast.LENGTH_LONG).show(); 8477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 8487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang showJoinAggregateActivity(mLookupUri); 8517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 8527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 8557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onJoinContactConfirmed(long joinContactId) { 8567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang doSaveAction(SaveMode.JOIN, joinContactId); 8577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 859c90cc15b804fb00339a3b98e5c951549f9b03599Walter Jang @Override 8607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public boolean save(int saveMode) { 8617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!hasValidState() || mStatus != Status.EDITING) { 8627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return false; 8637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If we are about to close the editor - there is no need to refresh the data 866363af60ea23e5a3b945005712a16564ab69db18bGary Mai if (saveMode == SaveMode.CLOSE || saveMode == SaveMode.EDITOR 8677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang || saveMode == SaveMode.SPLIT) { 8687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang getLoaderManager().destroyLoader(LOADER_CONTACT); 8697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.SAVING; 8727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!hasPendingChanges()) { 8747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mLookupUri == null && saveMode == SaveMode.RELOAD) { 8757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // We don't have anything to save and there isn't even an existing contact yet. 8767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Nothing to do, simply go back to editing mode 8777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.EDITING; 8787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 8797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang onSaveCompleted(/* hadChanges =*/ false, saveMode, 8817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /* saveSucceeded =*/ mLookupUri != null, mLookupUri, /* joinContactId =*/ null); 8827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 8837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang setEnabled(false); 8867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return doSaveAction(saveMode, /* joinContactId */ null); 8887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 8897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 8917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // State accessor methods 8927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 8937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 8947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 8957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Check if our internal {@link #mState} is valid, usually checked before 8967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * performing user actions. 8977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 8987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean hasValidState() { 8997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return mState.size() > 0; 9007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 9017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 9027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean isEditingUserProfile() { 9037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return mNewLocalProfile || mIsUserProfile; 9047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 9057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 9067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 9075a00de39004d298de4daee3e183add5eff17102cGary Mai * Whether the contact being edited is composed of read-only raw contacts 9087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * aggregated with a newly created writable raw contact. 9097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 9107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean isEditingReadOnlyRawContactWithNewContact() { 9115a00de39004d298de4daee3e183add5eff17102cGary Mai return mHasNewContact && mState.size() > 1; 9127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 9137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 9147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 915d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai * @return true if the single raw contact we're looking at is read-only. 916d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai */ 917d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai private boolean isEditingReadOnlyRawContact() { 918d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai return hasValidState() && mRawContactIdToDisplayAlone > 0 919d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai && !mState.getByRawContactId(mRawContactIdToDisplayAlone) 920d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai .getAccountType(AccountTypeManager.getInstance(mContext)) 921d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai .areContactsWritable(); 922d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai } 923d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai 924d7faa65c1349a7ded4d2d478822c07d024e5e792Gary Mai /** 9257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Return true if there are any edits to the current contact which need to 9267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * be saved. 9277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 9287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean hasPendingRawContactChanges(Set<String> excludedMimeTypes) { 9297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 9307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return RawContactModifier.hasChanges(mState, accountTypes, excludedMimeTypes); 9317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 9327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 9337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 9347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Determines if changes were made in the editor that need to be saved, while taking into 9357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * account that name changes are not real for read-only contacts. 9367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * See go/editing-read-only-contacts 9377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 9387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean hasPendingChanges() { 939698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (isEditingReadOnlyRawContactWithNewContact()) { 9407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // We created a new raw contact delta with a default display name. 9417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // We must test for pending changes while ignoring the default display name. 942698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final ValuesDelta beforeDelta = mState.getByRawContactId(mReadOnlyDisplayNameId) 943698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai .getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE); 944698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final ValuesDelta pendingDelta = mState 945698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai .getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE); 946698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (structuredNamesAreEqual(beforeDelta, pendingDelta)) { 9477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Set<String> excludedMimeTypes = new HashSet<>(); 9487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang excludedMimeTypes.add(StructuredName.CONTENT_ITEM_TYPE); 9497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return hasPendingRawContactChanges(excludedMimeTypes); 9507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 9517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return true; 9527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 9537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return hasPendingRawContactChanges(/* excludedMimeTypes =*/ null); 9547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 9557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 9567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 957698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai * Compares the two {@link ValuesDelta} to see if the structured name is changed. We made a copy 958698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai * of a read only delta and now we want to check if the copied delta has changes. 959698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai * 960698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai * @param before original {@link ValuesDelta} 961698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai * @param after copied {@link ValuesDelta} 962698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai * @return true if the copied {@link ValuesDelta} has all the same values in the structured 963698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai * name fields as the original. 964698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai */ 965698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai private boolean structuredNamesAreEqual(ValuesDelta before, ValuesDelta after) { 9665a00de39004d298de4daee3e183add5eff17102cGary Mai if (before == after) return true; 967698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (before == null || after == null) return false; 968698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final ContentValues original = before.getBefore(); 969698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final ContentValues pending = after.getAfter(); 970698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (original != null && pending != null) { 971a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai final String beforeDisplayName = original.getAsString(StructuredName.DISPLAY_NAME); 972698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String afterDisplayName = pending.getAsString(StructuredName.DISPLAY_NAME); 973698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (!TextUtils.equals(beforeDisplayName, afterDisplayName)) return false; 974698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai 975698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String beforePrefix = original.getAsString(StructuredName.PREFIX); 976698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String afterPrefix = pending.getAsString(StructuredName.PREFIX); 977698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (!TextUtils.equals(beforePrefix, afterPrefix)) return false; 978698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai 979698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String beforeFirstName = original.getAsString(StructuredName.GIVEN_NAME); 980698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String afterFirstName = pending.getAsString(StructuredName.GIVEN_NAME); 981698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (!TextUtils.equals(beforeFirstName, afterFirstName)) return false; 982698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai 983698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String beforeMiddleName = original.getAsString(StructuredName.MIDDLE_NAME); 984698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String afterMiddleName = pending.getAsString(StructuredName.MIDDLE_NAME); 985698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (!TextUtils.equals(beforeMiddleName, afterMiddleName)) return false; 986698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai 987698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String beforeLastName = original.getAsString(StructuredName.FAMILY_NAME); 988698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String afterLastName = pending.getAsString(StructuredName.FAMILY_NAME); 989698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (!TextUtils.equals(beforeLastName, afterLastName)) return false; 990698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai 991698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String beforeSuffix = original.getAsString(StructuredName.SUFFIX); 992698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final String afterSuffix = pending.getAsString(StructuredName.SUFFIX); 993698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai return TextUtils.equals(beforeSuffix, afterSuffix); 994698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai } 995698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai return false; 996698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai } 997698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai 9987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 9997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Account creation 10007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 10017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void selectAccountAndCreateContact() { 1003807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott Preconditions.checkNotNull(mWritableAccounts, "Accounts must be loaded first"); 10047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If this is a local profile, then skip the logic about showing the accounts changed 10057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // activity and create a phone-local contact. 10067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mNewLocalProfile) { 10077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang createContact(null); 10087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 10097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1011807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott final List<AccountWithDataSet> accounts = AccountInfo.extractAccounts(mWritableAccounts); 10127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If there is no default account or the accounts have changed such that we need to 10137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // prompt the user again, then launch the account prompt. 1014807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott if (mEditorUtils.shouldShowAccountChangedNotification(accounts)) { 10157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Intent intent = new Intent(mContext, ContactEditorAccountsChangedActivity.class); 10167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Prevent a second instance from being started on rotates 101780ab7ea6a518410594058c74f32c4b551097edbdMarcus Hagerott intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 10187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.SUB_ACTIVITY; 10197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang startActivityForResult(intent, REQUEST_CODE_ACCOUNTS_CHANGED); 10207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 10213107b25dcaea54943c58f984084fa9b348ea1885Gary Mai // Make sure the default account is automatically set if there is only one non-device 10223107b25dcaea54943c58f984084fa9b348ea1885Gary Mai // account. 1023807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott mEditorUtils.maybeUpdateDefaultAccount(accounts); 10247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Otherwise, there should be a default account. Then either create a local contact 10257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // (if default account is null) or create a contact with the specified account. 1026807e6208d6bc4ff1a6b0b4d8900229df27077246Marcus Hagerott AccountWithDataSet defaultAccount = mEditorUtils.getOnlyOrDefaultAccount(accounts); 10277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang createContact(defaultAccount); 10287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 10327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Shows account creation screen associated with a given account. 10337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * 10347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param account may be null to signal a device-local contact should be created. 10357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 10367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void createContact(AccountWithDataSet account) { 10377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 10387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final AccountType accountType = accountTypes.getAccountTypeForAccount(account); 10397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1040aebf3206766a05cce290245f09506adb789b6e37Gary Mai setStateForNewContact(account, accountType, isEditingUserProfile()); 10417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 10447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Data binding 10457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 10467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void setState(Contact contact) { 10487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If we have already loaded data, we do not want to change it here to not confuse the user 10497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!mState.isEmpty()) { 10507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Log.v(TAG, "Ignoring background change. This will have to be rebased later"); 10517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 10527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10537b75145e9b4fcd46c3cbb5678f8842934467b3aaGary Mai mContact = contact; 10544ceabed629c43cb247fd4a0faa36c09bd5ec999aGary Mai mRawContacts = contact.getRawContacts(); 10557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Check for writable raw contacts. If there are none, then we need to create one so user 10577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // can edit. For the user profile case, there is already an editable contact. 10587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!contact.isUserProfile() && !contact.isWritableContact(mContext)) { 10597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mHasNewContact = true; 1060698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai mReadOnlyDisplayNameId = contact.getNameRawContactId(); 1061698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai mCopyReadOnlyName = true; 10627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // This is potentially an asynchronous call and will add deltas to list. 10637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang selectAccountAndCreateContact(); 10647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 10657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mHasNewContact = false; 10667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1068698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai setStateForExistingContact(contact.isUserProfile(), mRawContacts); 1069e48746654178e9448819f86b3129fd32f539b3c9Gary Mai if (mAutoAddToDefaultGroup 1070e48746654178e9448819f86b3129fd32f539b3c9Gary Mai && InvisibleContactUtil.isInvisibleAndAddable(contact, getContext())) { 1071e48746654178e9448819f86b3129fd32f539b3c9Gary Mai InvisibleContactUtil.markAddToDefaultGroup(contact, mState, getContext()); 1072e48746654178e9448819f86b3129fd32f539b3c9Gary Mai } 10737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 10767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Prepare {@link #mState} for a newly created phone-local contact. 10777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 10787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void setStateForNewContact(AccountWithDataSet account, AccountType accountType, 10797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang boolean isUserProfile) { 10807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang setStateForNewContact(account, accountType, /* oldState =*/ null, 10817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /* oldAccountType =*/ null, isUserProfile); 10827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 10857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Prepare {@link #mState} for a newly created phone-local contact, migrating the state 10867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * specified by oldState and oldAccountType. 10877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 10887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void setStateForNewContact(AccountWithDataSet account, AccountType accountType, 10897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactDelta oldState, AccountType oldAccountType, boolean isUserProfile) { 10907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.EDITING; 10919f691e8b1c30dcdae230daebd26da0f225f74008Gary Mai mAccountWithDataSet = account; 10927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState.add(createNewRawContactDelta(account, accountType, oldState, oldAccountType)); 10937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIsUserProfile = isUserProfile; 10947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mNewContactDataReady = true; 10957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang bindEditors(); 10967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 10977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 10987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 10997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Returns a {@link RawContactDelta} for a new contact suitable for addition into 11007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * {@link #mState}. 11017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * 11027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * If oldState and oldAccountType are specified, the state specified by those parameters 11037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * is migrated to the result {@link RawContactDelta}. 11047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 11057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private RawContactDelta createNewRawContactDelta(AccountWithDataSet account, 11067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang AccountType accountType, RawContactDelta oldState, AccountType oldAccountType) { 11077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final RawContact rawContact = new RawContact(); 11087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (account != null) { 11097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang rawContact.setAccount(account); 11107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 11117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang rawContact.setAccountToLocal(); 11127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final RawContactDelta result = new RawContactDelta( 11157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang ValuesDelta.fromAfter(rawContact.getValues())); 11167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (oldState == null) { 11177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Parse any values from incoming intent 11187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactModifier.parseExtras(mContext, accountType, result, mIntentExtras); 11197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 11207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactModifier.migrateStateForNewContact( 11217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mContext, oldState, result, oldAccountType, accountType); 11227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Ensure we have some default fields (if the account type does not support a field, 11257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // ensureKind will not add it, so it is safe to add e.g. Event) 112662ec0b10c0ddc00053df39aeaed1f3316116e849Gary Mai RawContactModifier.ensureKindExists(result, accountType, StructuredName.CONTENT_ITEM_TYPE); 11277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactModifier.ensureKindExists(result, accountType, Phone.CONTENT_ITEM_TYPE); 11287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactModifier.ensureKindExists(result, accountType, Email.CONTENT_ITEM_TYPE); 11297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactModifier.ensureKindExists(result, accountType, Organization.CONTENT_ITEM_TYPE); 11307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactModifier.ensureKindExists(result, accountType, Event.CONTENT_ITEM_TYPE); 11317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactModifier.ensureKindExists(result, accountType, 11327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang StructuredPostal.CONTENT_ITEM_TYPE); 11337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Set the correct URI for saving the contact as a profile 11357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mNewLocalProfile) { 11367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang result.setProfileQueryUri(); 11377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return result; 11407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 11437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Prepare {@link #mState} for an existing contact. 11447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1145698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai private void setStateForExistingContact(boolean isUserProfile, 11467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang ImmutableList<RawContact> rawContacts) { 11477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang setEnabled(true); 11487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState.addAll(rawContacts.iterator()); 11507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang setIntentExtras(mIntentExtras); 11517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIntentExtras = null; 11527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // For user profile, change the contacts query URI 11547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIsUserProfile = isUserProfile; 11557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang boolean localProfileExists = false; 11567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mIsUserProfile) { 11587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang for (RawContactDelta rawContactDelta : mState) { 11597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // For profile contacts, we need a different query URI 11607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang rawContactDelta.setProfileQueryUri(); 11617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Try to find a local profile contact 11627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (rawContactDelta.getValues().getAsString(RawContacts.ACCOUNT_TYPE) == null) { 11637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang localProfileExists = true; 11647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Editor should always present a local profile for editing 11677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // TODO(wjang): Need to figure out when this case comes up. We can't do this if we're 11687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // going to prune all but the one raw contact that we're trying to display by itself. 11697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!localProfileExists && mRawContactIdToDisplayAlone <= 0) { 11707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState.add(createLocalRawContactDelta()); 11717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mExistingContactDataReady = true; 11747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang bindEditors(); 11757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 11787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Set the enabled state of editors. 11797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 11807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void setEnabled(boolean enabled) { 11817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mEnabled != enabled) { 11827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mEnabled = enabled; 11837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Enable/disable editors 11857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mContent != null) { 11867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang int count = mContent.getChildCount(); 11877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang for (int i = 0; i < count; i++) { 11887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mContent.getChildAt(i).setEnabled(enabled); 11897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Maybe invalidate the options menu 11937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Activity activity = getActivity(); 11947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (activity != null) activity.invalidateOptionsMenu(); 11957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 11977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 11987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 11997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Returns a {@link RawContactDelta} for a local contact suitable for addition into 12007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * {@link #mState}. 12017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 12027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private static RawContactDelta createLocalRawContactDelta() { 12037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final RawContact rawContact = new RawContact(); 12047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang rawContact.setAccountToLocal(); 12057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 12067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final RawContactDelta result = new RawContactDelta( 12077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang ValuesDelta.fromAfter(rawContact.getValues())); 12087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang result.setProfileQueryUri(); 12097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 12107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return result; 12117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 12127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1213698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai private void copyReadOnlyName() { 1214698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai // We should only ever be doing this if we're creating a new writable contact to attach to 1215698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai // a read only contact. 1216698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (!isEditingReadOnlyRawContactWithNewContact()) { 1217698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai return; 1218698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai } 1219698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final int writableIndex = mState.indexOfFirstWritableRawContact(getContext()); 1220698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final RawContactDelta writable = mState.get(writableIndex); 12217b75145e9b4fcd46c3cbb5678f8842934467b3aaGary Mai final RawContactDelta readOnly = mState.getByRawContactId(mContact.getNameRawContactId()); 1222698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final ValuesDelta writeNameDelta = writable 1223698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai .getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE); 1224698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai final ValuesDelta readNameDelta = readOnly 1225698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai .getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE); 1226698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai mCopyReadOnlyName = false; 1227860698b8d4542a55da5ec40032a361433b525aadGary Mai if (writeNameDelta == null || readNameDelta == null) { 1228860698b8d4542a55da5ec40032a361433b525aadGary Mai return; 1229860698b8d4542a55da5ec40032a361433b525aadGary Mai } 1230860698b8d4542a55da5ec40032a361433b525aadGary Mai writeNameDelta.copyStructuredNameFieldsFrom(readNameDelta); 1231698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai } 1232698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai 12337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 12347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Bind editors using {@link #mState} and other members initialized from the loaded (or new) 12357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Contact. 12367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1237ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang protected void bindEditors() { 1238cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang if (!isReadyToBindEditors()) { 1239cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang return; 1240cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1241cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang 1242d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang // Add input fields for the loaded Contact 1243363af60ea23e5a3b945005712a16564ab69db18bGary Mai final RawContactEditorView editorView = getContent(); 1244b6ca272f26b47ecef8fafe94326c4d553576c521Walter Jang editorView.setListener(this); 1245698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai if (mCopyReadOnlyName) { 1246698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai copyReadOnlyName(); 1247698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai } 1248678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai editorView.setState(mState, mMaterialPalette, mViewIdGenerator, 12499a55237f705453caae1f8aa3576a9acd7596d5ecWalter Jang mHasNewContact, mIsUserProfile, mAccountWithDataSet, 12505a00de39004d298de4daee3e183add5eff17102cGary Mai mRawContactIdToDisplayAlone); 1251079598fa2e09c22bb672715a9559b9d8973044d5Gary Mai if (isEditingReadOnlyRawContact()) { 125215646ce3e2e7a7f889976dc5684ecbc3029230c2Gary Mai final Toolbar toolbar = getEditorActivity().getToolbar(); 125315646ce3e2e7a7f889976dc5684ecbc3029230c2Gary Mai if (toolbar != null) { 125415646ce3e2e7a7f889976dc5684ecbc3029230c2Gary Mai toolbar.setTitle(R.string.contact_editor_title_read_only_contact); 1255d8f3da6a4ea4054bd47959db85657a7e01d28358Gary Mai // Set activity title for Talkback 1256d8f3da6a4ea4054bd47959db85657a7e01d28358Gary Mai getEditorActivity().setTitle(R.string.contact_editor_title_read_only_contact); 1257bd9ef3c60669d71543b3506d4959c1fe4be409dcJohn Shao toolbar.setNavigationIcon(R.drawable.quantum_ic_arrow_back_vd_theme_24); 125815646ce3e2e7a7f889976dc5684ecbc3029230c2Gary Mai toolbar.setNavigationContentDescription(R.string.back_arrow_content_description); 1259bd9ef3c60669d71543b3506d4959c1fe4be409dcJohn Shao toolbar.getNavigationIcon().setAutoMirrored(true); 1260079598fa2e09c22bb672715a9559b9d8973044d5Gary Mai } 1261079598fa2e09c22bb672715a9559b9d8973044d5Gary Mai } 1262cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang 1263d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang // Set up the photo widget 126431a74ad969b650eb733e536569254ed3978c4f54Walter Jang editorView.setPhotoListener(this); 12653efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang mPhotoRawContactId = editorView.getPhotoRawContactId(); 126631a74ad969b650eb733e536569254ed3978c4f54Walter Jang // If there is an updated full resolution photo apply it now, this will be the case if 126731a74ad969b650eb733e536569254ed3978c4f54Walter Jang // the user selects or takes a new photo, then rotates the device. 126831a74ad969b650eb733e536569254ed3978c4f54Walter Jang final Uri uri = (Uri) mUpdatedPhotos.get(String.valueOf(mPhotoRawContactId)); 126931a74ad969b650eb733e536569254ed3978c4f54Walter Jang if (uri != null) { 127031a74ad969b650eb733e536569254ed3978c4f54Walter Jang editorView.setFullSizePhoto(uri); 127141b3ea1c712f01164feb55455f1391564cb76deeWalter Jang } 12723efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang 1273d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang // The editor is ready now so make it visible 1274678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai editorView.setEnabled(mEnabled); 1275d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang editorView.setVisibility(View.VISIBLE); 1276d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang 1277d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang // Refresh the ActionBar as the visibility of the join command 1278d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang // Activity can be null if we have been detached from the Activity. 1279cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang invalidateOptionsMenu(); 1280cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1281cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang 12827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 12837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Invalidates the options menu if we are still associated with an Activity. 12847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 12857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void invalidateOptionsMenu() { 12867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Activity activity = getActivity(); 12877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (activity != null) { 12887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang activity.invalidateOptionsMenu(); 12897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 12907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 12917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1292cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang private boolean isReadyToBindEditors() { 1293cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang if (mState.isEmpty()) { 1294cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang if (Log.isLoggable(TAG, Log.VERBOSE)) { 1295cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang Log.v(TAG, "No data to bind editors"); 1296cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1297cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang return false; 1298cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1299cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang if (mIsEdit && !mExistingContactDataReady) { 1300cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang if (Log.isLoggable(TAG, Log.VERBOSE)) { 1301cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang Log.v(TAG, "Existing contact data is not ready to bind editors."); 1302cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1303cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang return false; 1304cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1305cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang if (mHasNewContact && !mNewContactDataReady) { 1306cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang if (Log.isLoggable(TAG, Log.VERBOSE)) { 1307cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang Log.v(TAG, "New contact data is not ready to bind editors."); 1308cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1309cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang return false; 1310cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang } 1311cab3dcec1401a32aff583d946b4a9f8af954358fWalter Jang return true; 1312ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang } 1313ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang 13147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 13157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Removes a current editor ({@link #mState}) and rebinds new editor for a new account. 13167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Some of old data are reused with new restriction enforced by the new account. 13177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * 13187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param oldState Old data being edited. 13197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param oldAccount Old account associated with oldState. 13207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param newAccount New account to be used. 13217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 13227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void rebindEditorsForNewContact( 13237b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang RawContactDelta oldState, AccountWithDataSet oldAccount, 13247b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang AccountWithDataSet newAccount) { 13257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 13267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang AccountType oldAccountType = accountTypes.getAccountTypeForAccount(oldAccount); 13277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang AccountType newAccountType = accountTypes.getAccountTypeForAccount(newAccount); 13287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1329aebf3206766a05cce290245f09506adb789b6e37Gary Mai mExistingContactDataReady = false; 1330aebf3206766a05cce290245f09506adb789b6e37Gary Mai mNewContactDataReady = false; 1331aebf3206766a05cce290245f09506adb789b6e37Gary Mai mState = new RawContactDeltaList(); 1332aebf3206766a05cce290245f09506adb789b6e37Gary Mai setStateForNewContact(newAccount, newAccountType, oldState, oldAccountType, 1333aebf3206766a05cce290245f09506adb789b6e37Gary Mai isEditingUserProfile()); 1334aebf3206766a05cce290245f09506adb789b6e37Gary Mai if (mIsEdit) { 1335698cee7d410f06b0c883c11f53481bfa5b2b787aGary Mai setStateForExistingContact(isEditingUserProfile(), mRawContacts); 13367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 13377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 13387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 13397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 13407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // ContactEditor 13417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 13427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 13437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 13447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void setListener(Listener listener) { 13457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mListener = listener; 13467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 13477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 13487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 13497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void load(String action, Uri lookupUri, Bundle intentExtras) { 13507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAction = action; 13517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mLookupUri = lookupUri; 13527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIntentExtras = intentExtras; 13537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 13547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mIntentExtras != null) { 13557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAutoAddToDefaultGroup = 13567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIntentExtras.containsKey(INTENT_EXTRA_ADD_TO_DEFAULT_DIRECTORY); 13577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mNewLocalProfile = 13587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIntentExtras.getBoolean(INTENT_EXTRA_NEW_LOCAL_PROFILE); 13597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mDisableDeleteMenuOption = 13607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIntentExtras.getBoolean(INTENT_EXTRA_DISABLE_DELETE_MENU_OPTION); 13617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mIntentExtras.containsKey(INTENT_EXTRA_MATERIAL_PALETTE_PRIMARY_COLOR) 13627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang && mIntentExtras.containsKey(INTENT_EXTRA_MATERIAL_PALETTE_SECONDARY_COLOR)) { 13637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mMaterialPalette = new MaterialColorMapUtils.MaterialPalette( 13647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIntentExtras.getInt(INTENT_EXTRA_MATERIAL_PALETTE_PRIMARY_COLOR), 13657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mIntentExtras.getInt(INTENT_EXTRA_MATERIAL_PALETTE_SECONDARY_COLOR)); 13667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 1367a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai mRawContactIdToDisplayAlone = mIntentExtras 1368a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai .getLong(INTENT_EXTRA_RAW_CONTACT_ID_TO_DISPLAY_ALONE); 13697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 13707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 13717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 13727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 13737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void setIntentExtras(Bundle extras) { 13745336e6ef1924162b94942cbd8f69202d553822daGary Mai getContent().setIntentExtras(extras); 13757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 13767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 13777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 13787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onJoinCompleted(Uri uri) { 13797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang onSaveCompleted(false, SaveMode.RELOAD, uri != null, uri, /* joinContactId */ null); 13807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 13817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1382e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey 1383e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey private String getNameToDisplay(Uri contactUri) { 1384c000d2ee0e292d9b160f65ab74ebd1258346046bGary Mai // The contact has been deleted or the uri is otherwise no longer right. 1385c000d2ee0e292d9b160f65ab74ebd1258346046bGary Mai if (contactUri == null) { 1386c000d2ee0e292d9b160f65ab74ebd1258346046bGary Mai return null; 1387c000d2ee0e292d9b160f65ab74ebd1258346046bGary Mai } 1388e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey final ContentResolver resolver = mContext.getContentResolver(); 1389e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey final Cursor cursor = resolver.query(contactUri, new String[]{ 1390e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey ContactsContract.Contacts.DISPLAY_NAME, 1391e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey ContactsContract.Contacts.DISPLAY_NAME_ALTERNATIVE}, null, null, null); 1392a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai 1393a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai if (cursor != null) { 1394a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai try { 1395a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai if (cursor.moveToFirst()) { 1396a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai final String displayName = cursor.getString(0); 1397a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai final String displayNameAlt = cursor.getString(1); 1398a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai cursor.close(); 1399a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai return ContactDisplayUtils.getPreferredDisplayName(displayName, displayNameAlt, 1400a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai new ContactsPreferences(mContext)); 1401a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai } 1402a4adae163d83db9226b831f8c9705914e68b5cd1Gary Mai } finally { 1403e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey cursor.close(); 1404e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey } 1405e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey } 1406e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey return null; 1407e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey } 1408e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey 1409e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey 14107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 14117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onSaveCompleted(boolean hadChanges, int saveMode, boolean saveSucceeded, 14127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Uri contactLookupUri, Long joinContactId) { 14137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (hadChanges) { 14147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (saveSucceeded) { 14157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang switch (saveMode) { 14167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case SaveMode.JOIN: 14177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 14187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case SaveMode.SPLIT: 14197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Toast.makeText(mContext, R.string.contactUnlinkedToast, Toast.LENGTH_SHORT) 14207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang .show(); 14217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 14227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang default: 1423e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey final String displayName = getNameToDisplay(contactLookupUri); 1424b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey final String toastMessage; 1425b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey if (!TextUtils.isEmpty(displayName)) { 1426b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey toastMessage = getResources().getString( 1427b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey R.string.contactSavedNamedToast, displayName); 1428b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey } else { 1429b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey toastMessage = getResources().getString(R.string.contactSavedToast); 1430b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey } 1431b1671053e48d14f2c620f48bc5f2cd915b51a002James Laskey Toast.makeText(mContext, toastMessage, Toast.LENGTH_SHORT).show(); 14327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 14347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 14357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Toast.makeText(mContext, R.string.contactSavedErrorToast, Toast.LENGTH_LONG).show(); 14367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang switch (saveMode) { 14397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case SaveMode.CLOSE: { 14408d26c0a7214cf6520a4def851afa138a133a68a2Walter Jang final Intent resultIntent; 14417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (saveSucceeded && contactLookupUri != null) { 14427b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Uri lookupUri = ContactEditorUtils.maybeConvertToLegacyLookupUri( 14437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mContext, contactLookupUri, mLookupUri); 14448d26c0a7214cf6520a4def851afa138a133a68a2Walter Jang resultIntent = ImplicitIntentsUtil.composeQuickContactIntent( 14458d26c0a7214cf6520a4def851afa138a133a68a2Walter Jang mContext, lookupUri, ScreenType.EDITOR); 14468d26c0a7214cf6520a4def851afa138a133a68a2Walter Jang resultIntent.putExtra(QuickContactActivity.EXTRA_CONTACT_EDITED, true); 14477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 14487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang resultIntent = null; 14497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // It is already saved, so prevent it from being saved again 14517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.CLOSING; 14527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mListener != null) mListener.onSaveFinished(resultIntent); 14537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 14547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 1455363af60ea23e5a3b945005712a16564ab69db18bGary Mai case SaveMode.EDITOR: { 14567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // It is already saved, so prevent it from being saved again 14577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.CLOSING; 14587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mListener != null) mListener.onSaveFinished(/* resultIntent= */ null); 14597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 14607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case SaveMode.JOIN: 14627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (saveSucceeded && contactLookupUri != null && joinContactId != null) { 14637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang joinAggregate(joinContactId); 14647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 14667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case SaveMode.RELOAD: 14677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (saveSucceeded && contactLookupUri != null) { 14687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If this was in INSERT, we are changing into an EDIT now. 14697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // If it already was an EDIT, we are changing to the new Uri now 14707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState = new RawContactDeltaList(); 14717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang load(Intent.ACTION_EDIT, contactLookupUri, null); 14727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.LOADING; 14737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang getLoaderManager().restartLoader(LOADER_CONTACT, null, mContactLoaderListener); 14747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 14767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 14777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang case SaveMode.SPLIT: 14787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.CLOSING; 14797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mListener != null) { 14807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mListener.onContactSplit(contactLookupUri); 14817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } else { 14827b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Log.d(TAG, "No listener registered, can not call onSplitFinished"); 14837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14847b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang break; 14857b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14867b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14877b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 14887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 14897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Shows a list of aggregates that can be joined into the currently viewed aggregate. 14907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * 14917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param contactLookupUri the fresh URI for the currently edited contact (after saving it) 14927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 14937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private void showJoinAggregateActivity(Uri contactLookupUri) { 14947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (contactLookupUri == null || !isAdded()) { 14957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 14967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 14977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 14987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mContactIdForJoin = ContentUris.parseId(contactLookupUri); 14997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Intent intent = new Intent(mContext, ContactSelectionActivity.class); 15007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang intent.setAction(UiIntentActions.PICK_JOIN_CONTACT_ACTION); 15017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang intent.putExtra(UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY, mContactIdForJoin); 15027b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang startActivityForResult(intent, REQUEST_CODE_JOIN); 15037b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 15067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Aggregation PopupWindow 15077b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 15087b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 15107b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Triggers an asynchronous search for aggregation suggestions. 15117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 15127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang protected void acquireAggregationSuggestions(Context context, 15137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang long rawContactId, ValuesDelta valuesDelta) { 15147b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionsRawContactId = rawContactId; 15157b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mAggregationSuggestionEngine == null) { 15177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionEngine = new AggregationSuggestionEngine(context); 15187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionEngine.setListener(this); 15197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionEngine.start(); 15207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15227b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionEngine.setContactId(getContactId()); 1523220d10cd7095f5ab803ff6155d7adaa576a8c4ffGary Mai mAggregationSuggestionEngine.setAccountFilter( 1524220d10cd7095f5ab803ff6155d7adaa576a8c4ffGary Mai getContent().getCurrentRawContactDelta().getAccountWithDataSet()); 15257b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15267b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionEngine.onNameChange(valuesDelta); 15277b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 15307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Returns the contact ID for the currently edited contact or 0 if the contact is new. 15317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 15327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private long getContactId() { 15337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang for (RawContactDelta rawContact : mState) { 15347b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang Long contactId = rawContact.getValues().getAsLong(RawContacts.CONTACT_ID); 15357b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (contactId != null) { 15367b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return contactId; 15377b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15387b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15397b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return 0; 15407b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15417b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15423f990ba4e35a99078d831c041290e574a320caa5Walter Jang @Override 15437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onAggregationSuggestionChange() { 15447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final Activity activity = getActivity(); 15457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if ((activity != null && activity.isFinishing()) 15467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang || !isVisible() || mState.isEmpty() || mStatus != Status.EDITING) { 15477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 15487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang UiClosables.closeQuietly(mAggregationSuggestionPopup); 15517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mAggregationSuggestionEngine.getSuggestedContactCount() == 0) { 15537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 15547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 1556da20b47c2b85390a2c3772379e71203c5aab513cGary Mai final View anchorView = getAggregationAnchorView(); 15577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (anchorView == null) { 15587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; // Raw contact deleted? 15597b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15607b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup = new ListPopupWindow(mContext, null); 15617b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup.setAnchorView(anchorView); 15627b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup.setWidth(anchorView.getWidth()); 15637b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED); 15647b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup.setAdapter( 15657b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang new AggregationSuggestionAdapter( 15667b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang getActivity(), 15677b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /* listener =*/ this, 15687b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionEngine.getSuggestions())); 15697b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup.setOnItemClickListener(new AdapterView.OnItemClickListener() { 15707b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 15717b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 15727b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final AggregationSuggestionView suggestionView = (AggregationSuggestionView) view; 15737b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang suggestionView.handleItemClickEvent(); 15747b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang UiClosables.closeQuietly(mAggregationSuggestionPopup); 15757b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup = null; 15767b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15777b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang }); 15787b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mAggregationSuggestionPopup.show(); 15797b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15807b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15817b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 1582da20b47c2b85390a2c3772379e71203c5aab513cGary Mai * Returns the editor view that should be used as the anchor for aggregation suggestions. 15837b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1584da20b47c2b85390a2c3772379e71203c5aab513cGary Mai protected View getAggregationAnchorView() { 1585d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang return getContent().getAggregationAnchorView(); 1586d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang } 1587d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang 15887b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 15897b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Joins the suggested contact (specified by the id's of constituent raw 15907b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * contacts), save all changes, and stay in the editor. 15917b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 15927b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang public void doJoinSuggestedContact(long[] rawContactIds) { 15937b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!hasValidState() || mStatus != Status.EDITING) { 15947b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return; 15957b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 15967b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 15977b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mState.setJoinWithRawContacts(rawContactIds); 15987b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang save(SaveMode.RELOAD); 15997b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 16007b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 16017b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang @Override 1602678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai public void onEditAction(Uri contactLookupUri, long rawContactId) { 1603678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai SuggestionEditConfirmationDialogFragment.show(this, contactLookupUri, rawContactId); 16047b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 16057b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 16067b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 1607678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai * Abandons the currently edited contact and switches to editing the selected raw contact, 1608678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai * transferring all the data there 16097b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1610678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai public void doEditSuggestedContact(Uri contactUri, long rawContactId) { 16117b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (mListener != null) { 16127b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // make sure we don't save this contact when closing down 16137b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang mStatus = Status.CLOSING; 1614678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai mListener.onEditOtherRawContactRequested(contactUri, rawContactId, 1615678108ebb9926a79ad0d7ac4f11417dec1583d42Gary Mai getContent().getCurrentRawContactDelta().getContentValues()); 16167b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 16177b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 16187b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 16197b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 16207b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Sets group metadata on all bound editors. 16217b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 162292f8ccc1f15df787b7434224857c056721281046Walter Jang protected void setGroupMetaData() { 1623f10ca15ffa550b36805d2330fc210b58601a215cWalter Jang if (mGroupMetaData != null) { 1624f10ca15ffa550b36805d2330fc210b58601a215cWalter Jang getContent().setGroupMetaData(mGroupMetaData); 1625f10ca15ffa550b36805d2330fc210b58601a215cWalter Jang } 16263f990ba4e35a99078d831c041290e574a320caa5Walter Jang } 16273f990ba4e35a99078d831c041290e574a320caa5Walter Jang 16287b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 16297b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Persist the accumulated editor deltas. 16307b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * 16317b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * @param joinContactId the raw contact ID to join the contact being saved to after the save, 16327b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * may be null. 16337b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 1634e3373dceb689209533e95a2cfbfbf1d9008ab6f6Walter Jang protected boolean doSaveAction(int saveMode, Long joinContactId) { 163549ed2033f83005f92c30068ae33c3138d75e1825Walter Jang final Intent intent = ContactSaveService.createSaveContactIntent(mContext, mState, 163649ed2033f83005f92c30068ae33c3138d75e1825Walter Jang SAVE_MODE_EXTRA_KEY, saveMode, isEditingUserProfile(), 163749ed2033f83005f92c30068ae33c3138d75e1825Walter Jang ((Activity) mContext).getClass(), 1638363af60ea23e5a3b945005712a16564ab69db18bGary Mai ContactEditorActivity.ACTION_SAVE_COMPLETED, mUpdatedPhotos, 1639e3373dceb689209533e95a2cfbfbf1d9008ab6f6Walter Jang JOIN_CONTACT_ID_EXTRA_KEY, joinContactId); 1640dd7d456a080f48d93aa3a9f9b04da0f17a8833a7Wenyi Wang return startSaveService(mContext, intent, saveMode); 164149ed2033f83005f92c30068ae33c3138d75e1825Walter Jang } 164249ed2033f83005f92c30068ae33c3138d75e1825Walter Jang 16437b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang private boolean startSaveService(Context context, Intent intent, int saveMode) { 16447b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang final boolean result = ContactSaveService.startService( 16457b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang context, intent, saveMode); 16467b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang if (!result) { 16477b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang onCancelEditConfirmed(); 16487b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 16497b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang return result; 16507b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang } 16517b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 16527b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 16537b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // Join Activity 16547b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang // 16557b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang 16567b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang /** 16577b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang * Performs aggregation with the contact selected by the user from suggestions or A-Z list. 16587b0970fd1db1a97f1be915d66d07f4dc8499f96dWalter Jang */ 165949ed2033f83005f92c30068ae33c3138d75e1825Walter Jang protected void joinAggregate(final long contactId) { 166049ed2033f83005f92c30068ae33c3138d75e1825Walter Jang final Intent intent = ContactSaveService.createJoinContactsIntent( 1661363af60ea23e5a3b945005712a16564ab69db18bGary Mai mContext, mContactIdForJoin, contactId, ContactEditorActivity.class, 1662363af60ea23e5a3b945005712a16564ab69db18bGary Mai ContactEditorActivity.ACTION_JOIN_COMPLETED); 166349ed2033f83005f92c30068ae33c3138d75e1825Walter Jang mContext.startService(intent); 16643f990ba4e35a99078d831c041290e574a320caa5Walter Jang } 1665b6ca272f26b47ecef8fafe94326c4d553576c521Walter Jang 166631a74ad969b650eb733e536569254ed3978c4f54Walter Jang public void removePhoto() { 166731a74ad969b650eb733e536569254ed3978c4f54Walter Jang getContent().removePhoto(); 166831a74ad969b650eb733e536569254ed3978c4f54Walter Jang mUpdatedPhotos.remove(String.valueOf(mPhotoRawContactId)); 16690e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang } 16700e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang 167131a74ad969b650eb733e536569254ed3978c4f54Walter Jang public void updatePhoto(Uri uri) throws FileNotFoundException { 167231a74ad969b650eb733e536569254ed3978c4f54Walter Jang final Bitmap bitmap = ContactPhotoUtils.getBitmapFromUri(getActivity(), uri); 167331a74ad969b650eb733e536569254ed3978c4f54Walter Jang if (bitmap == null || bitmap.getHeight() <= 0 || bitmap.getWidth() <= 0) { 16749bc9ba878cf7f77a2a6b3200a6ab716d13f1affcWenyi Wang Toast.makeText(mContext, R.string.contactPhotoSavedErrorToast, 167531a74ad969b650eb733e536569254ed3978c4f54Walter Jang Toast.LENGTH_SHORT).show(); 167631a74ad969b650eb733e536569254ed3978c4f54Walter Jang return; 16770e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang } 167831a74ad969b650eb733e536569254ed3978c4f54Walter Jang mUpdatedPhotos.putParcelable(String.valueOf(mPhotoRawContactId), uri); 167931a74ad969b650eb733e536569254ed3978c4f54Walter Jang getContent().updatePhoto(uri); 16800e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang } 16810e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang 1682da20b47c2b85390a2c3772379e71203c5aab513cGary Mai public void setPrimaryPhoto() { 1683da20b47c2b85390a2c3772379e71203c5aab513cGary Mai getContent().setPrimaryPhoto(); 16840e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang } 16850e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang 16860e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang @Override 1687151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang public void onNameFieldChanged(long rawContactId, ValuesDelta valuesDelta) { 1688151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang final Activity activity = getActivity(); 1689151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang if (activity == null || activity.isFinishing()) { 1690151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang return; 1691151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 169245b86d5e83a7d6eca4abe5cdfece2e9050b1809cWalter Jang acquireAggregationSuggestions(activity, rawContactId, valuesDelta); 1693151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 1694151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang 16955a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang @Override 1696708ea9e6f6f671178c0424f89e911000d4f330dcWalter Jang public void onRebindEditorsForNewContact(RawContactDelta oldState, 1697708ea9e6f6f671178c0424f89e911000d4f330dcWalter Jang AccountWithDataSet oldAccount, AccountWithDataSet newAccount) { 1698708ea9e6f6f671178c0424f89e911000d4f330dcWalter Jang mNewContactAccountChanged = true; 1699708ea9e6f6f671178c0424f89e911000d4f330dcWalter Jang rebindEditorsForNewContact(oldState, oldAccount, newAccount); 1700708ea9e6f6f671178c0424f89e911000d4f330dcWalter Jang } 1701708ea9e6f6f671178c0424f89e911000d4f330dcWalter Jang 170279658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang @Override 170379658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang public void onBindEditorsFailed() { 170479658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang final Activity activity = getActivity(); 170579658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang if (activity != null && !activity.isFinishing()) { 1706363af60ea23e5a3b945005712a16564ab69db18bGary Mai Toast.makeText(activity, R.string.editor_failed_to_load, 170779658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang Toast.LENGTH_SHORT).show(); 170879658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang activity.setResult(Activity.RESULT_CANCELED); 170979658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang activity.finish(); 171079658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang } 171179658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang } 171279658e14360a4ec75530a9dcae338f48c9d5f043Walter Jang 1713d675315606e8be431e6e5487e0b1cc33036a6ed7Walter Jang @Override 1714d675315606e8be431e6e5487e0b1cc33036a6ed7Walter Jang public void onEditorsBound() { 17153cb77bbf7119749ed4854a4b981fcabcf55823beWenyi Wang final Activity activity = getActivity(); 17163cb77bbf7119749ed4854a4b981fcabcf55823beWenyi Wang if (activity == null || activity.isFinishing()) { 17173cb77bbf7119749ed4854a4b981fcabcf55823beWenyi Wang return; 17183cb77bbf7119749ed4854a4b981fcabcf55823beWenyi Wang } 1719d675315606e8be431e6e5487e0b1cc33036a6ed7Walter Jang getLoaderManager().initLoader(LOADER_GROUPS, null, mGroupsLoaderListener); 1720d675315606e8be431e6e5487e0b1cc33036a6ed7Walter Jang } 1721d675315606e8be431e6e5487e0b1cc33036a6ed7Walter Jang 172231a74ad969b650eb733e536569254ed3978c4f54Walter Jang @Override 172331a74ad969b650eb733e536569254ed3978c4f54Walter Jang public void onPhotoEditorViewClicked() { 17243f18d6197a54aad10bea9c5cc2c89ca82809e793Walter Jang // For contacts composed of a single writable raw contact, or raw contacts have no more 17253f18d6197a54aad10bea9c5cc2c89ca82809e793Walter Jang // than 1 photo, clicking the photo view simply opens the source photo dialog 172631a74ad969b650eb733e536569254ed3978c4f54Walter Jang getEditorActivity().changePhoto(getPhotoMode()); 172731a74ad969b650eb733e536569254ed3978c4f54Walter Jang } 172831a74ad969b650eb733e536569254ed3978c4f54Walter Jang 172931a74ad969b650eb733e536569254ed3978c4f54Walter Jang private int getPhotoMode() { 1730da20b47c2b85390a2c3772379e71203c5aab513cGary Mai return getContent().isWritablePhotoSet() ? PhotoActionPopup.Modes.WRITE_ABLE_PHOTO 1731da20b47c2b85390a2c3772379e71203c5aab513cGary Mai : PhotoActionPopup.Modes.NO_PHOTO; 173231a74ad969b650eb733e536569254ed3978c4f54Walter Jang } 173331a74ad969b650eb733e536569254ed3978c4f54Walter Jang 1734363af60ea23e5a3b945005712a16564ab69db18bGary Mai private ContactEditorActivity getEditorActivity() { 1735363af60ea23e5a3b945005712a16564ab69db18bGary Mai return (ContactEditorActivity) getActivity(); 173631a74ad969b650eb733e536569254ed3978c4f54Walter Jang } 173731a74ad969b650eb733e536569254ed3978c4f54Walter Jang 1738363af60ea23e5a3b945005712a16564ab69db18bGary Mai private RawContactEditorView getContent() { 1739363af60ea23e5a3b945005712a16564ab69db18bGary Mai return (RawContactEditorView) mContent; 17403efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang } 17413f990ba4e35a99078d831c041290e574a320caa5Walter Jang} 1742