From 3e76408e47ca135c092b5eee73ae49d8697b0a10 Mon Sep 17 00:00:00 2001 From: Walter Jang Date: Fri, 22 May 2015 09:38:42 -0700 Subject: Distinguish between editor back button presses and framework stopage We carry whether the editor fragment is being stopped because of a back button press or because the framework stopped the hosting Activity all the way through the various editor fragment callbacks and the ContactSaveService because it is not until ContactEditorBaseActivity.onSaveFinished where we start the next Intent -- starting it causes a "flash" if recents is clicked and follwed by an immediate starting of the next editor Activity, which is the bug that was filed. With this change, we only use the ContactSaveService resultIntent to go back to the compact editor on back presses. The expected behavior/tested scenarios are described at go/b21198041 Bug 21198041 Bug 19624360 Change-Id: Ic350e12aa447cff81747e003f504f25100bd5c60 --- src/com/android/contacts/ContactSaveService.java | 9 +- .../activities/CompactContactEditorActivity.java | 2 +- .../contacts/activities/ContactEditorActivity.java | 2 +- .../activities/ContactEditorBaseActivity.java | 19 +++-- .../editor/CompactContactEditorFragment.java | 8 +- .../contacts/editor/ContactEditorBaseFragment.java | 99 ++++++++++++---------- .../contacts/editor/ContactEditorFragment.java | 8 +- .../quickcontact/InvisibleContactUtil.java | 2 +- 8 files changed, 88 insertions(+), 61 deletions(-) (limited to 'src/com') diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java index 29a4a7b39..9944c77c6 100644 --- a/src/com/android/contacts/ContactSaveService.java +++ b/src/com/android/contacts/ContactSaveService.java @@ -54,6 +54,7 @@ import com.android.contacts.common.model.RawContactDelta; import com.android.contacts.common.model.RawContactDeltaList; import com.android.contacts.common.model.RawContactModifier; import com.android.contacts.common.model.account.AccountWithDataSet; +import com.android.contacts.editor.ContactEditorFragment; import com.android.contacts.util.ContactPhotoUtils; import com.google.common.collect.Lists; @@ -300,7 +301,7 @@ public class ContactSaveService extends IntentService { Bundle bundle = new Bundle(); bundle.putParcelable(String.valueOf(rawContactId), updatedPhotoPath); return createSaveContactIntent(context, state, saveModeExtraKey, saveMode, isProfile, - callbackActivity, callbackAction, bundle); + callbackActivity, callbackAction, bundle, /* backPressed =*/ false); } /** @@ -309,11 +310,13 @@ public class ContactSaveService extends IntentService { * This variant is used when multiple contacts' photos may be updated, as in the * Contact Editor. * @param updatedPhotos maps each raw-contact's ID to the file-path of the new photo. + * @param backPressed whether the save was initiated as a result of a back button press + * or because the framework stopped the editor Activity */ public static Intent createSaveContactIntent(Context context, RawContactDeltaList state, String saveModeExtraKey, int saveMode, boolean isProfile, Class callbackActivity, String callbackAction, - Bundle updatedPhotos) { + Bundle updatedPhotos, boolean backPressed) { Intent serviceIntent = new Intent( context, ContactSaveService.class); serviceIntent.setAction(ContactSaveService.ACTION_SAVE_CONTACT); @@ -333,6 +336,8 @@ public class ContactSaveService extends IntentService { if (updatedPhotos != null) { callbackIntent.putExtra(EXTRA_UPDATED_PHOTOS, (Parcelable) updatedPhotos); } + callbackIntent.putExtra(ContactEditorFragment.INTENT_EXTRA_SAVE_BACK_PRESSED, + backPressed); serviceIntent.putExtra(ContactSaveService.EXTRA_CALLBACK_INTENT, callbackIntent); } return serviceIntent; diff --git a/src/com/android/contacts/activities/CompactContactEditorActivity.java b/src/com/android/contacts/activities/CompactContactEditorActivity.java index fcbb70ee7..c45c261b3 100644 --- a/src/com/android/contacts/activities/CompactContactEditorActivity.java +++ b/src/com/android/contacts/activities/CompactContactEditorActivity.java @@ -60,7 +60,7 @@ public class CompactContactEditorActivity extends ContactEditorBaseActivity { @Override public void onBackPressed() { if (mFragment != null) { - mFragment.save(ContactEditor.SaveMode.CLOSE); + mFragment.save(ContactEditor.SaveMode.CLOSE, /* backPressed =*/ true); } } } diff --git a/src/com/android/contacts/activities/ContactEditorActivity.java b/src/com/android/contacts/activities/ContactEditorActivity.java index a9b75d989..800a26756 100644 --- a/src/com/android/contacts/activities/ContactEditorActivity.java +++ b/src/com/android/contacts/activities/ContactEditorActivity.java @@ -54,7 +54,7 @@ public class ContactEditorActivity extends ContactEditorBaseActivity @Override public void onBackPressed() { if (mFragment != null) { - mFragment.save(ContactEditor.SaveMode.COMPACT); + mFragment.save(ContactEditor.SaveMode.COMPACT, /* backPressed =*/ true); } } } diff --git a/src/com/android/contacts/activities/ContactEditorBaseActivity.java b/src/com/android/contacts/activities/ContactEditorBaseActivity.java index ec2f9b67b..41b0c6b67 100644 --- a/src/com/android/contacts/activities/ContactEditorBaseActivity.java +++ b/src/com/android/contacts/activities/ContactEditorBaseActivity.java @@ -153,14 +153,17 @@ abstract public class ContactEditorBaseActivity extends ContactsActivity /** * Saves or creates the contact based on the mode, and if successful * finishes the activity. + * + * @param backPressed whether the save was initiated as a result of a back button press + * or because the framework stopped the editor Activity */ - boolean save(int saveMode); + boolean save(int saveMode, boolean backPressed); /** * Invoked after the contact is saved. */ void onSaveCompleted(boolean hadChanges, int saveMode, boolean saveSucceeded, - Uri contactLookupUri, Bundle updatedPhotos); + Uri contactLookupUri, Bundle updatedPhotos, boolean backPressed); /** * Invoked after the contact is joined. @@ -238,7 +241,9 @@ abstract public class ContactEditorBaseActivity extends ContactsActivity ContactEditor.SaveMode.CLOSE), intent.getBooleanExtra(ContactSaveService.EXTRA_SAVE_SUCCEEDED, false), intent.getData(), - (Bundle) intent.getParcelableExtra(ContactSaveService.EXTRA_UPDATED_PHOTOS)); + (Bundle) intent.getParcelableExtra(ContactSaveService.EXTRA_UPDATED_PHOTOS), + intent.getBooleanExtra(ContactEditorFragment.INTENT_EXTRA_SAVE_BACK_PRESSED, + false)); } else if (ACTION_JOIN_COMPLETED.equals(action)) { mFragment.onJoinCompleted(intent.getData()); } @@ -268,11 +273,15 @@ abstract public class ContactEditorBaseActivity extends ContactsActivity @Override public void onSaveFinished(Intent resultIntent) { + final boolean backPressed = resultIntent == null ? false : resultIntent.getBooleanExtra( + ContactEditorBaseFragment.INTENT_EXTRA_SAVE_BACK_PRESSED, false); if (mFinishActivityOnSaveCompleted) { setResult(resultIntent == null ? RESULT_CANCELED : RESULT_OK, resultIntent); } else if (resultIntent != null) { - ImplicitIntentsUtil.startActivityInApp(ContactEditorBaseActivity.this, - resultIntent); + if (backPressed) { + ImplicitIntentsUtil.startActivityInApp(ContactEditorBaseActivity.this, + resultIntent); + } } finish(); } diff --git a/src/com/android/contacts/editor/CompactContactEditorFragment.java b/src/com/android/contacts/editor/CompactContactEditorFragment.java index c7d7cac83..10efe1008 100644 --- a/src/com/android/contacts/editor/CompactContactEditorFragment.java +++ b/src/com/android/contacts/editor/CompactContactEditorFragment.java @@ -188,7 +188,7 @@ public class CompactContactEditorFragment extends ContactEditorBaseFragment impl // If anything was left unsaved, save it now if (!getActivity().isChangingConfigurations() && mStatus == Status.EDITING) { - save(SaveMode.RELOAD); + save(SaveMode.RELOAD, /* backPressed =*/ false); } } @@ -297,12 +297,12 @@ public class CompactContactEditorFragment extends ContactEditorBaseFragment impl } @Override - protected boolean doSaveAction(int saveMode) { + protected boolean doSaveAction(int saveMode, boolean backPressed) { // Save contact. No need to pass the palette since we are finished editing after the save. final Intent intent = ContactSaveService.createSaveContactIntent(mContext, mState, SAVE_MODE_EXTRA_KEY, saveMode, isEditingUserProfile(), ((Activity) mContext).getClass(), - CompactContactEditorActivity.ACTION_SAVE_COMPLETED, mUpdatedPhotos); + CompactContactEditorActivity.ACTION_SAVE_COMPLETED, mUpdatedPhotos, backPressed); mContext.startService(intent); return true; @@ -350,7 +350,7 @@ public class CompactContactEditorFragment extends ContactEditorBaseFragment impl mShowToastAfterSave = false; // Save whatever is in the form - save(SaveMode.RELOAD); + save(SaveMode.RELOAD, /* backPressed =*/ false); } // Prepare an Intent to start the expanded editor diff --git a/src/com/android/contacts/editor/ContactEditorBaseFragment.java b/src/com/android/contacts/editor/ContactEditorBaseFragment.java index 529bc4ee0..52076f78f 100644 --- a/src/com/android/contacts/editor/ContactEditorBaseFragment.java +++ b/src/com/android/contacts/editor/ContactEditorBaseFragment.java @@ -177,6 +177,12 @@ abstract public class ContactEditorBaseFragment extends Fragment implements */ public static final String SAVE_MODE_EXTRA_KEY = "saveMode"; + /** + * Intent extra to specify whether the save was initiated as a result of a back button press + * or because the framework stopped the editor Activity. + */ + public static final String INTENT_EXTRA_SAVE_BACK_PRESSED = "saveBackPressed"; + /** * Callbacks for Activities that host contact editors Fragments. */ @@ -775,7 +781,7 @@ abstract public class ContactEditorBaseFragment extends Fragment implements switch (item.getItemId()) { case android.R.id.home: case R.id.menu_done: - return save(SaveMode.CLOSE); + return save(SaveMode.CLOSE, /* backPressed =*/ true); case R.id.menu_discard: return revert(); case R.id.menu_delete: @@ -831,7 +837,7 @@ abstract public class ContactEditorBaseFragment extends Fragment implements } mState.markRawContactsForSplitting(); - save(SaveMode.SPLIT);; + save(SaveMode.SPLIT, /* backPressed =*/ false); } private boolean doSplitContactAction() { @@ -854,7 +860,7 @@ abstract public class ContactEditorBaseFragment extends Fragment implements return true; } - return save(SaveMode.JOIN); + return save(SaveMode.JOIN, /* backPressed =*/ false); } private void doPickRingtone() { @@ -886,7 +892,7 @@ abstract public class ContactEditorBaseFragment extends Fragment implements } @Override - public boolean save(int saveMode) { + public boolean save(int saveMode, boolean backPressed) { if (!hasValidState() || mStatus != Status.EDITING) { return false; } @@ -908,7 +914,7 @@ abstract public class ContactEditorBaseFragment extends Fragment implements } onSaveCompleted(/* hadChanges =*/ false, saveMode, /* saveSucceeded =*/ mLookupUri != null, mLookupUri, - /* updatedPhotos =*/ null); + /* updatedPhotos =*/ null, backPressed); return true; } @@ -917,23 +923,24 @@ abstract public class ContactEditorBaseFragment extends Fragment implements // Store account as default account, only if this is a new contact saveDefaultAccountIfNecessary(); - if (isInsert(getActivity().getIntent()) - && saveMode == SaveMode.COMPACT && mListener != null) { + if (isInsert(getActivity().getIntent()) && saveMode == SaveMode.COMPACT + && mListener != null && backPressed) { // If we're coming back from the fully expanded editor and this is an insert, just // pass any values entered by the user back to the compact editor without doing a save final Intent resultIntent = EditorIntents.createCompactInsertContactIntent( mState, getDisplayName(), getPhoneticName(), mUpdatedPhotos); + resultIntent.putExtra(INTENT_EXTRA_SAVE_BACK_PRESSED, backPressed); mListener.onSaveFinished(resultIntent); return true; } // Otherwise this is an edit or a back press so do an actual save - return doSaveAction(saveMode); + return doSaveAction(saveMode, backPressed); } /** * Persist the accumulated editor deltas. */ - abstract protected boolean doSaveAction(int saveMode); + abstract protected boolean doSaveAction(int saveMode, boolean backPressed); // // State accessor methods @@ -1326,12 +1333,13 @@ abstract public class ContactEditorBaseFragment extends Fragment implements @Override public void onJoinCompleted(Uri uri) { - onSaveCompleted(false, SaveMode.RELOAD, uri != null, uri, /* updatedPhotos =*/ null); + onSaveCompleted(false, SaveMode.RELOAD, uri != null, uri, /* updatedPhotos =*/ null, + /* backPressed =*/ false); } @Override public void onSaveCompleted(boolean hadChanges, int saveMode, boolean saveSucceeded, - Uri contactLookupUri, Bundle updatedPhotos) { + Uri contactLookupUri, Bundle updatedPhotos, boolean backPressed) { if (hadChanges) { if (saveSucceeded) { if (saveMode != SaveMode.JOIN && mShowToastAfterSave) { @@ -1342,36 +1350,41 @@ abstract public class ContactEditorBaseFragment extends Fragment implements } } switch (saveMode) { - case SaveMode.CLOSE: - case SaveMode.COMPACT: + case SaveMode.CLOSE: { final Intent resultIntent; - if (!saveSucceeded || contactLookupUri == null) { - resultIntent = saveMode == SaveMode.COMPACT - ? EditorIntents.createCompactInsertContactIntent( - mState, getDisplayName(), getPhoneticName(), updatedPhotos) - : null; - } else { + if (saveSucceeded && contactLookupUri != null) { final Uri lookupUri = maybeConvertToLegacyLookupUri( mContext, contactLookupUri, mLookupUri); - if (saveMode == SaveMode.CLOSE) { - resultIntent = ImplicitIntentsUtil.composeQuickContactIntent(lookupUri, - QuickContactActivity.MODE_FULLY_EXPANDED); - } else if (saveMode == SaveMode.COMPACT) { - resultIntent = isInsert(getActivity().getIntent()) - ? EditorIntents.createCompactInsertContactIntent( - mState, getDisplayName(), getPhoneticName(), updatedPhotos) - : EditorIntents.createCompactEditContactIntent( - lookupUri, getMaterialPalette(), updatedPhotos); - } else { - resultIntent = null; - } + resultIntent = ImplicitIntentsUtil.composeQuickContactIntent(lookupUri, + QuickContactActivity.MODE_FULLY_EXPANDED); + resultIntent.putExtra(INTENT_EXTRA_SAVE_BACK_PRESSED, backPressed); + } else { + resultIntent = null; } - - // It is already saved, so prevent that it is saved again mStatus = Status.CLOSING; if (mListener != null) mListener.onSaveFinished(resultIntent); break; - + } + case SaveMode.COMPACT: { + if (!hadChanges && !backPressed && isInsert(getActivity().getIntent())) { + // Reload the empty editor when the Contacts app is resumed + mStatus = Status.EDITING; + } else if (backPressed) { + final Uri lookupUri = maybeConvertToLegacyLookupUri( + mContext, contactLookupUri, mLookupUri); + final Intent resultIntent = isInsert(getActivity().getIntent()) + ? EditorIntents.createCompactInsertContactIntent( + mState, getDisplayName(), getPhoneticName(), updatedPhotos) + : EditorIntents.createCompactEditContactIntent( + lookupUri, getMaterialPalette(), updatedPhotos); + resultIntent.putExtra(INTENT_EXTRA_SAVE_BACK_PRESSED, true); + mStatus = Status.CLOSING; + if (mListener != null) mListener.onSaveFinished(resultIntent); + } else { + reloadFullEditor(contactLookupUri); + } + break; + } case SaveMode.RELOAD: case SaveMode.JOIN: if (saveSucceeded && contactLookupUri != null) { @@ -1379,14 +1392,7 @@ abstract public class ContactEditorBaseFragment extends Fragment implements if (saveMode == SaveMode.JOIN && hasValidState()) { showJoinAggregateActivity(contactLookupUri); } - - // If this was in INSERT, we are changing into an EDIT now. - // If it already was an EDIT, we are changing to the new Uri now - // Either way, open the editor with all input fields displayed. - mState = new RawContactDeltaList(); - load(ContactEditorBaseActivity.ACTION_EDIT, contactLookupUri, null); - mStatus = Status.LOADING; - getLoaderManager().restartLoader(LOADER_DATA, null, mDataLoaderListener); + reloadFullEditor(contactLookupUri); } break; @@ -1401,6 +1407,13 @@ abstract public class ContactEditorBaseFragment extends Fragment implements } } + private void reloadFullEditor(Uri contactLookupUri) { + mState = new RawContactDeltaList(); + load(ContactEditorBaseActivity.ACTION_EDIT, contactLookupUri, null); + mStatus = Status.LOADING; + getLoaderManager().restartLoader(LOADER_DATA, null, mDataLoaderListener); + } + /** * Shows a list of aggregates that can be joined into the currently viewed aggregate. * @@ -1536,7 +1549,7 @@ abstract public class ContactEditorBaseFragment extends Fragment implements } mState.setJoinWithRawContacts(rawContactIds); - save(SaveMode.RELOAD); + save(SaveMode.RELOAD, /* backPressed =*/ false); } @Override diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java index 4cda73d93..e9b371503 100644 --- a/src/com/android/contacts/editor/ContactEditorFragment.java +++ b/src/com/android/contacts/editor/ContactEditorFragment.java @@ -118,7 +118,7 @@ public class ContactEditorFragment extends ContactEditorBaseFragment implements // If anything was left unsaved, save it now and return to the compact editor. if (!getActivity().isChangingConfigurations() && mStatus == Status.EDITING) { - save(SaveMode.COMPACT); + save(SaveMode.COMPACT, /* backPressed =*/ false); } } @@ -133,7 +133,7 @@ public class ContactEditorFragment extends ContactEditorBaseFragment implements public boolean onOptionsItemSelected(MenuItem item) { // Override the home/done options to return to the compact editor if (item.getItemId() == android.R.id.home || item.getItemId() == R.id.menu_done) { - return save(SaveMode.COMPACT); + return save(SaveMode.COMPACT, /* backPressed =*/ true); } return super.onOptionsItemSelected(item); } @@ -539,7 +539,7 @@ public class ContactEditorFragment extends ContactEditorBaseFragment implements } @Override - protected boolean doSaveAction(int saveMode) { + protected boolean doSaveAction(int saveMode, boolean backPressed) { // Save contact and reload the compact editor after saving. // Note, the full resolution photos Bundle must be passed to the ContactSaveService // and then passed along in the result Intent in order for the compact editor to @@ -548,7 +548,7 @@ public class ContactEditorFragment extends ContactEditorBaseFragment implements Intent intent = ContactSaveService.createSaveContactIntent(mContext, mState, SAVE_MODE_EXTRA_KEY, saveMode, isEditingUserProfile(), ((Activity) mContext).getClass(), ContactEditorActivity.ACTION_SAVE_COMPLETED, - mUpdatedPhotos); + mUpdatedPhotos, backPressed); mContext.startService(intent); // Don't try to save the same photos twice. diff --git a/src/com/android/contacts/quickcontact/InvisibleContactUtil.java b/src/com/android/contacts/quickcontact/InvisibleContactUtil.java index 3609fbcb4..de7042480 100644 --- a/src/com/android/contacts/quickcontact/InvisibleContactUtil.java +++ b/src/com/android/contacts/quickcontact/InvisibleContactUtil.java @@ -94,7 +94,7 @@ public class InvisibleContactUtil { final Intent intent = ContactSaveService.createSaveContactIntent( context, contactDeltaList, "", 0, false, QuickContactActivity.class, - Intent.ACTION_VIEW, null); + Intent.ACTION_VIEW, null, /* backPressed =*/ false); context.startService(intent); } -- cgit v1.2.3