ContactEditorFragment.java revision 3e9a62449b8ca3a38b1d51019c6ea13972263bc2
1cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann/*
2ef3f8f045ed4150caa64749742227acd0e6b85d8Daniel Lehmann * Copyright (C) 2010 The Android Open Source Project
3cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann *
4cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * Licensed under the Apache License, Version 2.0 (the "License");
5cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * you may not use this file except in compliance with the License.
6cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * You may obtain a copy of the License at
7cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann *
8cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann *      http://www.apache.org/licenses/LICENSE-2.0
9cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann *
10cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * Unless required by applicable law or agreed to in writing, software
11cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * distributed under the License is distributed on an "AS IS" BASIS,
12cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * See the License for the specific language governing permissions and
14cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * limitations under the License
15cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann */
16cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
1718ffaa2561cc7dd2e3ef81737e6537931c0a9a11Dmitri Plotnikovpackage com.android.contacts.editor;
18cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
19cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.app.Activity;
20cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.content.Context;
21cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.content.Intent;
22f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmannimport android.graphics.Bitmap;
23cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.net.Uri;
24cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.os.Bundle;
2591004b37683c15650eccde68ff04defcf94a1c84Maurice Chuimport android.provider.ContactsContract.CommonDataKinds.Photo;
26688c228b2d7cf0c812fb673451f24e7cb457d63bYorke Leeimport android.text.TextUtils;
27cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.util.Log;
28cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.view.LayoutInflater;
29cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.view.View;
30cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.view.ViewGroup;
31d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport android.widget.AdapterView;
3280d527c94389cab477e2c75ded03eec877ea6835Daniel Lehmannimport android.widget.LinearLayout;
33d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport android.widget.ListPopupWindow;
34cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
35e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.ContactSaveService;
36e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R;
37e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.activities.ContactEditorActivity;
383f990ba4e35a99078d831c041290e574a320caa5Walter Jangimport com.android.contacts.activities.ContactEditorBaseActivity.ContactEditor;
3944cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.model.AccountTypeManager;
4092101e77238e450dedb56814cec80edc0adf79c0Walter Jangimport com.android.contacts.common.model.RawContactDelta;
4192101e77238e450dedb56814cec80edc0adf79c0Walter Jangimport com.android.contacts.common.model.RawContactDeltaList;
4292101e77238e450dedb56814cec80edc0adf79c0Walter Jangimport com.android.contacts.common.model.RawContactModifier;
4344cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.model.ValuesDelta;
4444cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.model.account.AccountType;
4544cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.model.account.AccountWithDataSet;
4644cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.util.AccountsListAdapter;
4744cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.util.AccountsListAdapter.AccountListFilter;
48e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.detail.PhotoSelectionHandler;
49e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.editor.Editor.EditorListener;
50e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.ContactPhotoUtils;
5186625158bdc52855c37e96bf098ba7a213c810d7Chiao Chengimport com.android.contacts.util.UiClosables;
5292101e77238e450dedb56814cec80edc0adf79c0Walter Jang
53851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.google.common.collect.ImmutableList;
5444cfc56d1701629070384364416c1311b780535dChiao Chengimport com.google.common.collect.Lists;
55e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng
56637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Leeimport java.io.FileNotFoundException;
57f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmannimport java.util.Collections;
58daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwellimport java.util.HashMap;
59f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport java.util.List;
60f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
613f990ba4e35a99078d831c041290e574a320caa5Walter Jang/**
623f990ba4e35a99078d831c041290e574a320caa5Walter Jang * Contact editor with all fields displayed.
633f990ba4e35a99078d831c041290e574a320caa5Walter Jang */
643f990ba4e35a99078d831c041290e574a320caa5Walter Jangpublic class ContactEditorFragment extends ContactEditorBaseFragment implements
653f990ba4e35a99078d831c041290e574a320caa5Walter Jang        ContactEditor, SplitContactConfirmationDialogFragment.Listener,
662b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann        RawContactReadOnlyEditorView.Listener {
67cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
68daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    private static final String KEY_EXPANDED_EDITORS = "expandedEditors";
69f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
70cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang    private static final String KEY_RAW_CONTACT_ID_REQUESTING_PHOTO = "photorequester";
71cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang    private static final String KEY_CURRENT_PHOTO_URI = "currentphotouri";
72cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang    private static final String KEY_UPDATED_PHOTOS = "updatedPhotos";
73cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang
74a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov    public static final String SAVE_MODE_EXTRA_KEY = "saveMode";
75a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov
76fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    // Used to store which raw contact editors have been expanded. Keyed on raw contact ids.
77fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    private HashMap<Long, Boolean> mExpandedEditors = new HashMap<Long, Boolean>();
78fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang
79fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    /**
80fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     * The raw contact for which we started "take photo" or "choose photo from gallery" most
81fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     * recently.  Used to restore {@link #mCurrentPhotoHandler} after orientation change.
82fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     */
83fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    private long mRawContactIdRequestingPhoto;
8444cfc56d1701629070384364416c1311b780535dChiao Cheng
85fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    /**
86fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     * The {@link PhotoHandler} for the photo editor for the {@link #mRawContactIdRequestingPhoto}
87fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     * raw contact.
88fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     *
89fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     * A {@link PhotoHandler} is created for each photo editor in {@link #bindPhotoHandler}, but
90fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     * the only "active" one should get the activity result.  This member represents the active
91fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     * one.
92fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     */
93fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    private PhotoHandler mCurrentPhotoHandler;
94fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    private Uri mCurrentPhotoUri;
95fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    private Bundle mUpdatedPhotos = new Bundle();
96daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell
97cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    public ContactEditorFragment() {
98cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    }
99cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
100cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    @Override
101cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
102cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        final View view = inflater.inflate(R.layout.contact_editor_fragment, container, false);
103cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
104f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        mContent = (LinearLayout) view.findViewById(R.id.editors);
105e8767a1136d2a2f9cb3e3ca5f44b2142baab9709Daniel Lehmann
1063648d2ea76a6649230d1fdd3dba92797ae7cfb26Daniel Lehmann        setHasOptionsMenu(true);
107cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
108cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        return view;
109cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    }
110cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
111222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann    @Override
112f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann    public void onCreate(Bundle savedState) {
113f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        super.onCreate(savedState);
114f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
115ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang        if (savedState != null) {
116daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            mExpandedEditors = (HashMap<Long, Boolean>)
117daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                    savedState.getSerializable(KEY_EXPANDED_EDITORS);
118cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang            mRawContactIdRequestingPhoto = savedState.getLong(
119cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang                    KEY_RAW_CONTACT_ID_REQUESTING_PHOTO);
120cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang            mCurrentPhotoUri = savedState.getParcelable(KEY_CURRENT_PHOTO_URI);
121cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang            mUpdatedPhotos = savedState.getParcelable(KEY_UPDATED_PHOTOS);
12244cfc56d1701629070384364416c1311b780535dChiao Cheng        }
123fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov    }
124fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov
125fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov    @Override
1262b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro    public void onExternalEditorRequest(AccountWithDataSet account, Uri uri) {
127fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov        mListener.onCustomEditContactActivityRequested(account, uri, null, false);
128fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov    }
129fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov
130daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    @Override
131daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    public void onEditorExpansionChanged() {
132daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        updatedExpandedEditorsMap();
133daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    }
134daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell
135ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang    @Override
1361ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov    public void setIntentExtras(Bundle extras) {
1371ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov        if (extras == null || extras.size() == 0) {
1381ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov            return;
139bb11be3f5867453e7561cdc7bebe6a380eff6881Daniel Lehmann        }
140916cf2661ada41a83556884d8f5b322d32ef452bDmitri Plotnikov
141a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
142851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        for (RawContactDelta state : mState) {
143851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final AccountType type = state.getAccountType(accountTypes);
14496e87fd6e808e9d853263ffeb5104f3253a18639Daniel Lehmann            if (type.areContactsWritable()) {
1451ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov                // Apply extras to the first writable raw contact only
146851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                RawContactModifier.parseExtras(mContext, type, state, extras);
1471ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov                break;
1481ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov            }
1491ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov        }
150f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann    }
151cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
152d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    /**
153d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * Removes a current editor ({@link #mState}) and rebinds new editor for a new account.
154d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * Some of old data are reused with new restriction enforced by the new account.
155d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     *
1562b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro     * @param oldState Old data being edited.
157d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * @param oldAccount Old account associated with oldState.
158d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * @param newAccount New account to be used.
159d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     */
160d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    private void rebindEditorsForNewContact(
161851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            RawContactDelta oldState, AccountWithDataSet oldAccount,
162851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            AccountWithDataSet newAccount) {
163d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
16467e83223e954ed54898daa5e32400dbff6d3831aJay Shrauner        AccountType oldAccountType = accountTypes.getAccountTypeForAccount(oldAccount);
16567e83223e954ed54898daa5e32400dbff6d3831aJay Shrauner        AccountType newAccountType = accountTypes.getAccountTypeForAccount(newAccount);
166d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
167d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        if (newAccountType.getCreateContactActivityClassName() != null) {
168d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            Log.w(TAG, "external activity called in rebind situation");
169d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            if (mListener != null) {
170d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                mListener.onCustomCreateContactActivityRequested(newAccount, mIntentExtras);
171d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            }
172d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        } else {
17344cfc56d1701629070384364416c1311b780535dChiao Cheng            mExistingContactDataReady = false;
17444cfc56d1701629070384364416c1311b780535dChiao Cheng            mNewContactDataReady = false;
17544cfc56d1701629070384364416c1311b780535dChiao Cheng            mState = new RawContactDeltaList();
176b55107303cc46906c265582a8931172f13d684b6Walter Jang            setStateForNewContact(newAccount, newAccountType, oldState, oldAccountType);
17744cfc56d1701629070384364416c1311b780535dChiao Cheng            if (mIsEdit) {
178b55107303cc46906c265582a8931172f13d684b6Walter Jang                setStateForExistingContact(mDefaultDisplayName, mIsUserProfile, mRawContacts);
17944cfc56d1701629070384364416c1311b780535dChiao Cheng            }
180d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        }
181d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
182d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
183ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang    @Override
184ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang    protected void bindEditors() {
1855671c7e7718c3285dc0391807401083986fcfd51Maurice Chu        // bindEditors() can only bind views if there is data in mState, so immediately return
1865671c7e7718c3285dc0391807401083986fcfd51Maurice Chu        // if mState is null
18744cfc56d1701629070384364416c1311b780535dChiao Cheng        if (mState.isEmpty()) {
18844cfc56d1701629070384364416c1311b780535dChiao Cheng            return;
18944cfc56d1701629070384364416c1311b780535dChiao Cheng        }
19044cfc56d1701629070384364416c1311b780535dChiao Cheng
19144cfc56d1701629070384364416c1311b780535dChiao Cheng        // Check if delta list is ready.  Delta list is populated from existing data and when
19244cfc56d1701629070384364416c1311b780535dChiao Cheng        // editing an read-only contact, it's also populated with newly created data for the
19344cfc56d1701629070384364416c1311b780535dChiao Cheng        // blank form.  When the data is not ready, skip. This method will be called multiple times.
19444cfc56d1701629070384364416c1311b780535dChiao Cheng        if ((mIsEdit && !mExistingContactDataReady) || (mHasNewContact && !mNewContactDataReady)) {
1955671c7e7718c3285dc0391807401083986fcfd51Maurice Chu            return;
1965671c7e7718c3285dc0391807401083986fcfd51Maurice Chu        }
1975671c7e7718c3285dc0391807401083986fcfd51Maurice Chu
198f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        // Sort the editors
199f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        Collections.sort(mState, mComparator);
200cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
201f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        // Remove any existing editors and rebuild any visible
202f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        mContent.removeAllViews();
203cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
204f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
205f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann                Context.LAYOUT_INFLATER_SERVICE);
206a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
207a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan        int numRawContacts = mState.size();
20844cfc56d1701629070384364416c1311b780535dChiao Cheng
209a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan        for (int i = 0; i < numRawContacts; i++) {
210f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann            // TODO ensure proper ordering of entities in the list
211851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final RawContactDelta rawContactDelta = mState.get(i);
212851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            if (!rawContactDelta.isVisible()) continue;
213f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
214851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final AccountType type = rawContactDelta.getAccountType(accountTypes);
215851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final long rawContactId = rawContactDelta.getRawContactId();
216f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
21772af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann            final BaseRawContactEditorView editor;
2182b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann            if (!type.areContactsWritable()) {
219fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov                editor = (BaseRawContactEditorView) inflater.inflate(
2202b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann                        R.layout.raw_contact_readonly_editor_view, mContent, false);
221fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov            } else {
222fd70903236883f47b21f23b8cb49a1ccacdfcdf1Katherine Kuan                editor = (RawContactEditorView) inflater.inflate(R.layout.raw_contact_editor_view,
223fd70903236883f47b21f23b8cb49a1ccacdfcdf1Katherine Kuan                        mContent, false);
224cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann            }
225daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            editor.setListener(this);
226daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            final List<AccountWithDataSet> accounts = AccountTypeManager.getInstance(mContext)
227daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                    .getAccounts(true);
228daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            if (mHasNewContact && !mNewLocalProfile && accounts.size() > 1) {
229daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                addAccountSwitcher(mState.get(0), editor);
230d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            }
231a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan
232b55107303cc46906c265582a8931172f13d684b6Walter Jang            editor.setEnabled(isEnabled());
233cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
234daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            if (mExpandedEditors.containsKey(rawContactId)) {
235daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                editor.setCollapsed(mExpandedEditors.get(rawContactId));
236daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            } else {
237daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                // By default, only the first editor will be expanded.
238daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                editor.setCollapsed(i != 0);
239daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            }
240daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell
241f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann            mContent.addView(editor);
2427d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov
243851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            editor.setState(rawContactDelta, type, mViewIdGenerator, isEditingUserProfile());
244daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            editor.setCollapsible(numRawContacts > 1);
245f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov
2466fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            // Set up the photo handler.
2476fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            bindPhotoHandler(editor, type, mState);
2486fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro
249c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell            // If a new photo was chosen but not yet saved, we need to update the UI to
250c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell            // reflect this.
251c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell            final Uri photoUri = updatedPhotoUriForRawContact(rawContactId);
252c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell            if (photoUri != null) editor.setFullSizedPhoto(photoUri);
25328eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus
25472af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann            if (editor instanceof RawContactEditorView) {
2552828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki                final Activity activity = getActivity();
25672af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann                final RawContactEditorView rawContactEditor = (RawContactEditorView) editor;
2575ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                EditorListener listener = new EditorListener() {
258f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov
259f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov                    @Override
260f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov                    public void onRequest(int request) {
2612828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki                        if (activity.isFinishing()) { // Make sure activity is still running.
2622828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki                            return;
2632828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki                        }
2642bbfae8f92d5c218c83a49621a4c8f98f4d7a394Isaac Katzenelson                        if (request == EditorListener.FIELD_CHANGED && !isEditingUserProfile()) {
2652828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki                            acquireAggregationSuggestions(activity, rawContactEditor);
266d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                        } else if (request == EditorListener.EDITOR_FOCUS_CHANGED) {
267d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                            adjustNameFieldsHintDarkness(rawContactEditor);
26811bb73bcdf4290ced99e3e06b1f76d4c37357aeaDmitri Plotnikov                        }
269f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov                    }
270f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov
271f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov                    @Override
2722293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan                    public void onDeleteRequested(Editor removedEditor) {
273f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov                    }
2745ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                };
2755ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
27644cfc56d1701629070384364416c1311b780535dChiao Cheng                final StructuredNameEditorView nameEditor = rawContactEditor.getNameEditor();
2775ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                if (mRequestFocus) {
2785ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                    nameEditor.requestFocus();
2795ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                    mRequestFocus = false;
2805ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                }
2815ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                nameEditor.setEditorListener(listener);
282688c228b2d7cf0c812fb673451f24e7cb457d63bYorke Lee                if (!TextUtils.isEmpty(mDefaultDisplayName)) {
283688c228b2d7cf0c812fb673451f24e7cb457d63bYorke Lee                    nameEditor.setDisplayName(mDefaultDisplayName);
284688c228b2d7cf0c812fb673451f24e7cb457d63bYorke Lee                }
285f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov
2865ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                final TextFieldsEditorView phoneticNameEditor =
2875ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                        rawContactEditor.getPhoneticNameEditor();
2885ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                phoneticNameEditor.setEditorListener(listener);
2897d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov                rawContactEditor.setAutoAddToDefaultGroup(mAutoAddToDefaultGroup);
2907d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov
291d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                final TextFieldsEditorView nickNameEditor =
292d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                        rawContactEditor.getNickNameEditor();
293d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                nickNameEditor.setEditorListener(listener);
294d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell
2953e9a62449b8ca3a38b1d51019c6ea13972263bc2Walter Jang                if (isAggregationSuggestionRawContactId(rawContactId)) {
2962828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki                    acquireAggregationSuggestions(activity, rawContactEditor);
297f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov                }
298d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell
299d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                adjustNameFieldsHintDarkness(rawContactEditor);
300f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov            }
301cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        }
302f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
303eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov        mRequestFocus = false;
304eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov
305b55107303cc46906c265582a8931172f13d684b6Walter Jang        setGroupMetaData();
306e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov
307f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        // Show editor now that we've loaded state
308f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        mContent.setVisibility(View.VISIBLE);
309a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann
310a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann        // Refresh Action Bar as the visibility of the join command
311825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann        // Activity can be null if we have been detached from the Activity
312825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann        final Activity activity = getActivity();
313825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann        if (activity != null) activity.invalidateOptionsMenu();
314daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell
315daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        updatedExpandedEditorsMap();
316daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    }
317daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell
318daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    /**
319d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell     * Adjust how dark the hint text should be on all the names' text fields.
320d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell     *
321d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell     * @param rawContactEditor editor to update
322d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell     */
323d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell    private void adjustNameFieldsHintDarkness(RawContactEditorView rawContactEditor) {
324d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell        // Check whether fields contain focus by calling findFocus() instead of hasFocus().
325d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell        // The hasFocus() value is not necessarily up to date.
326d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell        final boolean nameFieldsAreNotFocused
327d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                = rawContactEditor.getNameEditor().findFocus() == null
328d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                && rawContactEditor.getPhoneticNameEditor().findFocus() == null
329d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                && rawContactEditor.getNickNameEditor().findFocus() == null;
330d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell        rawContactEditor.getNameEditor().setHintColorDark(!nameFieldsAreNotFocused);
331d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell        rawContactEditor.getPhoneticNameEditor().setHintColorDark(!nameFieldsAreNotFocused);
332d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell        rawContactEditor.getNickNameEditor().setHintColorDark(!nameFieldsAreNotFocused);
333d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell    }
334d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell
335d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell    /**
336daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell     * Update the values in {@link #mExpandedEditors}.
337daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell     */
338daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    private void updatedExpandedEditorsMap() {
339daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        for (int i = 0; i < mContent.getChildCount(); i++) {
340daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            final View childView = mContent.getChildAt(i);
341daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            if (childView instanceof BaseRawContactEditorView) {
342daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                BaseRawContactEditorView childEditor = (BaseRawContactEditorView) childView;
343daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                mExpandedEditors.put(childEditor.getRawContactId(), childEditor.isCollapsed());
344daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            }
345daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        }
3466fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro    }
347eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov
34828eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus    /**
349c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell     * If we've stashed a temporary file containing a contact's new photo, return its URI.
35028eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus     * @param rawContactId identifies the raw-contact whose Bitmap we'll try to return.
351c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell     * @return Uru of photo for specified raw-contact, or null
352c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell     */
353c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell    private Uri updatedPhotoUriForRawContact(long rawContactId) {
354c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell        return (Uri) mUpdatedPhotos.get(String.valueOf(rawContactId));
35528eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus    }
35628eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus
3576fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro    private void bindPhotoHandler(BaseRawContactEditorView editor, AccountType type,
358851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            RawContactDeltaList state) {
3596fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        final int mode;
3607e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell        final boolean showIsPrimaryOption;
3616fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        if (type.areContactsWritable()) {
3626fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            if (editor.hasSetPhoto()) {
3637e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                mode = PhotoActionPopup.Modes.WRITE_ABLE_PHOTO;
3647e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                showIsPrimaryOption = hasMoreThanOnePhoto();
3656fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            } else {
366ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus                mode = PhotoActionPopup.Modes.NO_PHOTO;
3677e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                showIsPrimaryOption = false;
3686fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            }
3697e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell        } else if (editor.hasSetPhoto() && hasMoreThanOnePhoto()) {
3707e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            mode = PhotoActionPopup.Modes.READ_ONLY_PHOTO;
3717e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            showIsPrimaryOption = true;
3726fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        } else {
3737e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            // Read-only and either no photo or the only photo ==> no options
3747e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            editor.getPhotoEditor().setEditorListener(null);
3757e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            editor.getPhotoEditor().setShowPrimary(false);
3767e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            return;
3776fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        }
37891004b37683c15650eccde68ff04defcf94a1c84Maurice Chu        final PhotoHandler photoHandler = new PhotoHandler(mContext, editor, mode, state);
3796fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        editor.getPhotoEditor().setEditorListener(
38091004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                (PhotoHandler.PhotoEditorListener) photoHandler.getListener());
3817e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell        editor.getPhotoEditor().setShowPrimary(showIsPrimaryOption);
3824bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki
3834bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki        // Note a newly created raw contact gets some random negative ID, so any value is valid
3844bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki        // here. (i.e. don't check against -1 or anything.)
3854bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki        if (mRawContactIdRequestingPhoto == editor.getRawContactId()) {
3864bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki            mCurrentPhotoHandler = photoHandler;
3874bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki        }
388cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    }
389cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
3900353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan    private void saveDefaultAccountIfNecessary() {
3910353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan        // Verify that this is a newly created contact, that the contact is composed of only
3920353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan        // 1 raw contact, and that the contact is not a user profile.
3930353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan        if (!Intent.ACTION_INSERT.equals(mAction) && mState.size() == 1 &&
3940353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan                !isEditingUserProfile()) {
3950353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan            return;
3960353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan        }
3970353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan
3980353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan        // Find the associated account for this contact (retrieve it here because there are
3990353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan        // multiple paths to creating a contact and this ensures we always have the correct
4000353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan        // account).
401851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        final RawContactDelta rawContactDelta = mState.get(0);
402851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        String name = rawContactDelta.getAccountName();
403851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        String type = rawContactDelta.getAccountType();
404851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        String dataSet = rawContactDelta.getDataSet();
4050353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan
4060353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan        AccountWithDataSet account = (name == null || type == null) ? null :
4070353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan                new AccountWithDataSet(name, type, dataSet);
4080353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan        mEditorUtils.saveDefaultAndAllAccounts(account);
4090353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan    }
4100353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan
411d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    private void addAccountSwitcher(
412851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final RawContactDelta currentState, BaseRawContactEditorView editor) {
4132b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro        final AccountWithDataSet currentAccount = new AccountWithDataSet(
414851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                currentState.getAccountName(),
415851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                currentState.getAccountType(),
416851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                currentState.getDataSet());
417d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        final View accountView = editor.findViewById(R.id.account);
418daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        final View anchorView = editor.findViewById(R.id.account_selector_container);
419daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        if (accountView == null) {
420daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            return;
421daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        }
422daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        anchorView.setVisibility(View.VISIBLE);
423d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        accountView.setOnClickListener(new View.OnClickListener() {
424d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            @Override
425d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            public void onClick(View v) {
426d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                final ListPopupWindow popup = new ListPopupWindow(mContext, null);
427a6c8f2daa80f1816dd25237457d7f6287c6b1b7cDaisuke Miyakawa                final AccountsListAdapter adapter =
4286f74c0f3313cbb08ee8a8fbb79bfefc5b03fe215Makoto Onuki                        new AccountsListAdapter(mContext,
4296f74c0f3313cbb08ee8a8fbb79bfefc5b03fe215Makoto Onuki                        AccountListFilter.ACCOUNTS_CONTACT_WRITABLE, currentAccount);
430d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                popup.setWidth(anchorView.getWidth());
431d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                popup.setAnchorView(anchorView);
432d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                popup.setAdapter(adapter);
433d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                popup.setModal(true);
434d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                popup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
435d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                popup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
436d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    @Override
437d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    public void onItemClick(AdapterView<?> parent, View view, int position,
438d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                            long id) {
43986625158bdc52855c37e96bf098ba7a213c810d7Chiao Cheng                        UiClosables.closeQuietly(popup);
4402b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro                        AccountWithDataSet newAccount = adapter.getItem(position);
441d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        if (!newAccount.equals(currentAccount)) {
442d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                            rebindEditorsForNewContact(currentState, currentAccount, newAccount);
443d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        }
444d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    }
445d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                });
446d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                popup.show();
447d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            }
448d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        });
449d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
450d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
451b85b83ee4adc8b72fe68499f669ca530d58e6815Daniel Lehmann    @Override
452b55107303cc46906c265582a8931172f13d684b6Walter Jang    protected boolean doSaveAction(int saveMode) {
4530353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan        // Store account as default account, only if this is a new contact
4540353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan        saveDefaultAccountIfNecessary();
4550353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan
4560353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan        // Save contact
457ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus        Intent intent = ContactSaveService.createSaveContactIntent(mContext, mState,
458ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus                SAVE_MODE_EXTRA_KEY, saveMode, isEditingUserProfile(),
459ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus                ((Activity)mContext).getClass(), ContactEditorActivity.ACTION_SAVE_COMPLETED,
460ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus                mUpdatedPhotos);
461ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus        mContext.startService(intent);
46287270e1b58e669354bb1571ced686421c56deb7aJosh Gargus
46387270e1b58e669354bb1571ced686421c56deb7aJosh Gargus        // Don't try to save the same photos twice.
46487270e1b58e669354bb1571ced686421c56deb7aJosh Gargus        mUpdatedPhotos = new Bundle();
46587270e1b58e669354bb1571ced686421c56deb7aJosh Gargus
466f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        return true;
467f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann    }
468f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
469ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang    @Override
470f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann    public void onSaveInstanceState(Bundle outState) {
471daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        outState.putSerializable(KEY_EXPANDED_EDITORS, mExpandedEditors);
472cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang        outState.putLong(KEY_RAW_CONTACT_ID_REQUESTING_PHOTO, mRawContactIdRequestingPhoto);
473cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang        outState.putParcelable(KEY_CURRENT_PHOTO_URI, mCurrentPhotoUri);
474cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang        outState.putParcelable(KEY_UPDATED_PHOTOS, mUpdatedPhotos);
475f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        super.onSaveInstanceState(outState);
476f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann    }
477f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
478d364314c460152db7089b304beec81b3675893baDmitri Plotnikov    @Override
479f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann    public void onActivityResult(int requestCode, int resultCode, Intent data) {
480f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov        if (mStatus == Status.SUB_ACTIVITY) {
481f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov            mStatus = Status.EDITING;
482f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov        }
483f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov
4846fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        // See if the photo selection handler handles this result.
48591004b37683c15650eccde68ff04defcf94a1c84Maurice Chu        if (mCurrentPhotoHandler != null && mCurrentPhotoHandler.handlePhotoActivityResult(
4866fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                requestCode, resultCode, data)) {
4876fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            return;
4886fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        }
489f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
4903e9a62449b8ca3a38b1d51019c6ea13972263bc2Walter Jang        super.onActivityResult(requestCode, resultCode, data);
491cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    }
4929cd1708f333eda622dc6a4fed2a0df9058193a9dDmitri Plotnikov
493c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann    /**
494c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann     * Sets the photo stored in mPhoto and writes it to the RawContact with the given id
495c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann     */
496637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee    private void setPhoto(long rawContact, Bitmap photo, Uri photoUri) {
497bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov        BaseRawContactEditorView requestingEditor = getRawContactEditorView(rawContact);
498e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus
499e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus        if (photo == null || photo.getHeight() < 0 || photo.getWidth() < 0) {
500e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus            // This is unexpected.
501e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus            Log.w(TAG, "Invalid bitmap passed to setPhoto()");
502e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus        }
503e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus
5049302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov        if (requestingEditor != null) {
505c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell            requestingEditor.setPhotoEntry(photo);
5067e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            // Immediately set all other photos as non-primary. Otherwise the UI can display
5077e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            // multiple photos as "Primary photo".
5087e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            for (int i = 0; i < mContent.getChildCount(); i++) {
5097e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                final View childView = mContent.getChildAt(i);
5107e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                if (childView instanceof BaseRawContactEditorView
5117e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                        && childView != requestingEditor) {
5127e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                    final BaseRawContactEditorView rawContactEditor
5137e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                            = (BaseRawContactEditorView) childView;
5147e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                    rawContactEditor.getPhotoEditor().setSuperPrimary(false);
5157e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                }
5167e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            }
5179302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov        } else {
5189302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov            Log.w(TAG, "The contact that requested the photo is no longer present.");
5199302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov        }
520e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus
521637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee        mUpdatedPhotos.putParcelable(String.valueOf(rawContact), photoUri);
5229302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov    }
5239302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov
5249302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov    /**
5259302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov     * Finds raw contact editor view for the given rawContactId.
5269302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov     */
527bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov    public BaseRawContactEditorView getRawContactEditorView(long rawContactId) {
528c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann        for (int i = 0; i < mContent.getChildCount(); i++) {
529c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann            final View childView = mContent.getChildAt(i);
53072af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann            if (childView instanceof BaseRawContactEditorView) {
53172af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann                final BaseRawContactEditorView editor = (BaseRawContactEditorView) childView;
5329302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov                if (editor.getRawContactId() == rawContactId) {
5339302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov                    return editor;
534c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann                }
535c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann            }
536c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann        }
5379302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov        return null;
538c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann    }
539c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann
540fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann    /**
541fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann     * Returns true if there is currently more than one photo on screen.
542fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann     */
543fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann    private boolean hasMoreThanOnePhoto() {
544fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann        int countWithPicture = 0;
54591004b37683c15650eccde68ff04defcf94a1c84Maurice Chu        final int numEntities = mState.size();
54691004b37683c15650eccde68ff04defcf94a1c84Maurice Chu        for (int i = 0; i < numEntities; i++) {
547851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final RawContactDelta entity = mState.get(i);
548851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            if (entity.isVisible()) {
54991004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                final ValuesDelta primary = entity.getPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
550851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                if (primary != null && primary.getPhoto() != null) {
551fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann                    countWithPicture++;
55291004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                } else {
553851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                    final long rawContactId = entity.getRawContactId();
554637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                    final Uri uri = mUpdatedPhotos.getParcelable(String.valueOf(rawContactId));
555637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                    if (uri != null) {
556637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                        try {
557637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                            mContext.getContentResolver().openInputStream(uri);
55891004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                            countWithPicture++;
559637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                        } catch (FileNotFoundException e) {
56091004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                        }
56191004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                    }
56291004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                }
56391004b37683c15650eccde68ff04defcf94a1c84Maurice Chu
56491004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                if (countWithPicture > 1) {
56591004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                    return true;
566fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann                }
567fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann            }
568fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann        }
569fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann        return false;
5709cd1708f333eda622dc6a4fed2a0df9058193a9dDmitri Plotnikov    }
571222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann
5726fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro    /**
5736fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro     * Custom photo handler for the editor.  The inner listener that this creates also has a
5746fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro     * reference to the editor and acts as an {@link EditorListener}, and uses that editor to hold
5756fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro     * state information in several of the listener methods.
5766fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro     */
5776fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro    private final class PhotoHandler extends PhotoSelectionHandler {
57828eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus
57928eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus        final long mRawContactId;
580e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus        private final BaseRawContactEditorView mEditor;
5814bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki        private final PhotoActionListener mPhotoEditorListener;
58228eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus
5836fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        public PhotoHandler(Context context, BaseRawContactEditorView editor, int photoMode,
584851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                RawContactDeltaList state) {
5857e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            super(context, editor.getPhotoEditor().getChangeAnchorView(), photoMode, false, state);
586e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus            mEditor = editor;
58728eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus            mRawContactId = editor.getRawContactId();
5889a409d474b2b4f2e4261657f864eeb866fcb8816Daniel Lehmann            mPhotoEditorListener = new PhotoEditorListener();
589e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus        }
590e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus
591e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus        @Override
592e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus        public PhotoActionListener getListener() {
5939a409d474b2b4f2e4261657f864eeb866fcb8816Daniel Lehmann            return mPhotoEditorListener;
594e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus        }
595e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus
596e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus        @Override
597637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee        public void startPhotoActivity(Intent intent, int requestCode, Uri photoUri) {
5984bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki            mRawContactIdRequestingPhoto = mEditor.getRawContactId();
59991004b37683c15650eccde68ff04defcf94a1c84Maurice Chu            mCurrentPhotoHandler = this;
600e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus            mStatus = Status.SUB_ACTIVITY;
601637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee            mCurrentPhotoUri = photoUri;
602e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus            ContactEditorFragment.this.startActivityForResult(intent, requestCode);
6039442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann        }
6049442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann
6056fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        private final class PhotoEditorListener extends PhotoSelectionHandler.PhotoActionListener
6066fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                implements EditorListener {
607fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann
6086fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            @Override
6096fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            public void onRequest(int request) {
6106fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                if (!hasValidState()) return;
611a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann
6126fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                if (request == EditorListener.REQUEST_PICK_PHOTO) {
6136fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                    onClick(mEditor.getPhotoEditor());
6149442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann                }
6157e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                if (request == EditorListener.REQUEST_PICK_PRIMARY_PHOTO) {
6167e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                    useAsPrimaryChosen();
6177e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                }
6189442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann            }
619a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann
6206fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            @Override
6216fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            public void onDeleteRequested(Editor removedEditor) {
6226fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                // The picture cannot be deleted, it can only be removed, which is handled by
6236fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                // onRemovePictureChosen()
6246fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            }
625a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann
6266fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            /**
6276fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro             * User has chosen to set the selected photo as the (super) primary photo
6286fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro             */
6297e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            public void useAsPrimaryChosen() {
6306fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                // Set the IsSuperPrimary for each editor
6316fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                int count = mContent.getChildCount();
6326fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                for (int i = 0; i < count; i++) {
6336fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                    final View childView = mContent.getChildAt(i);
6346fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                    if (childView instanceof BaseRawContactEditorView) {
6356fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                        final BaseRawContactEditorView editor =
6366fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                                (BaseRawContactEditorView) childView;
6376fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                        final PhotoEditorView photoEditor = editor.getPhotoEditor();
6386fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                        photoEditor.setSuperPrimary(editor == mEditor);
6396fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                    }
6406fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                }
64191004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                bindEditors();
6426fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            }
6439442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann
6446fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            /**
6456fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro             * User has chosen to remove a picture
6466fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro             */
6476fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            @Override
6486fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            public void onRemovePictureChosen() {
649c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell                mEditor.setPhotoEntry(null);
65028eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus
65128eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus                // Prevent bitmap from being restored if rotate the device.
65228eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus                // (only if we first chose a new photo before removing it)
65328eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus                mUpdatedPhotos.remove(String.valueOf(mRawContactId));
65491004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                bindEditors();
6556fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            }
6566fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro
6576fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            @Override
658637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee            public void onPhotoSelected(Uri uri) throws FileNotFoundException {
659637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                final Bitmap bitmap = ContactPhotoUtils.getBitmapFromUri(mContext, uri);
660637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                setPhoto(mRawContactId, bitmap, uri);
66191004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                mCurrentPhotoHandler = null;
66291004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                bindEditors();
6636fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            }
6646fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro
6656fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            @Override
666637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee            public Uri getCurrentPhotoUri() {
667637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                return mCurrentPhotoUri;
6686fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            }
6696fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro
6706fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            @Override
6716fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            public void onPhotoSelectionDismissed() {
6726fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                // Nothing to do.
6739442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann            }
6744a62be4f5a365e5afde71becfd446381f2baa494Daniel Lehmann        }
6754a62be4f5a365e5afde71becfd446381f2baa494Daniel Lehmann    }
6762ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey}
677