Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d45cdbd authored by Walter Jang's avatar Walter Jang
Browse files

Merge base and compact editor activities (1/2)

* The ContactEditorBaseActivity.ContactEditor interface
  and subinterfaces are moved w/o modification except
  ununecassay modifiers (public, public final static)
  were removed.

* Base class members were moved w/o only visibilty
  changed to private.  The ContactEditorBaseFragment.Listener
  mFragmentListener implementation was unchanged.

* Base class Methods were moved directly over with only
  slight changes (a few finals added).  onCreate and
  onBackPressed were just moved inline into the corresponding
  CompactContactEditorActivity where the super method
  was being invoked.

Test: Manually tested the following editor scenarios:
  1) new contact
  2) edit other contact
  3) edit writable raw contact
  4) edit read-only raw contact (joins a new writable raw contact to it)
  5) edit aggregate w/ 1 writable and 1 read-only raw contact
  6) edit aggregate w/ 2 writable raw contacts
  7) edit local me raw contact
  8) edit local me raw contact joined with a read-only raw contact

Test: Also tested that duplicate culusters are updated are after a
  quick contact edit

Bug: 31088704
Change-Id: I620c345fc6339b6b0807a44bafbac3201ca7b81f
parent 86b351d0
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ import android.support.v4.os.ResultReceiver;
import android.util.Log;
import android.widget.Toast;

import com.android.contacts.activities.ContactEditorBaseActivity;
import com.android.contacts.activities.CompactContactEditorActivity;
import com.android.contacts.common.compat.CompatUtils;
import com.android.contacts.common.database.ContactUpdateUtils;
import com.android.contacts.common.model.AccountTypeManager;
@@ -215,13 +215,13 @@ public class ContactSaveService extends IntentService {
        } catch (Exception exception) {
            final int resId;
            switch (saveMode) {
                case ContactEditorBaseActivity.ContactEditor.SaveMode.SPLIT:
                case CompactContactEditorActivity.ContactEditor.SaveMode.SPLIT:
                    resId = R.string.contactUnlinkErrorToast;
                    break;
                case ContactEditorBaseActivity.ContactEditor.SaveMode.RELOAD:
                case CompactContactEditorActivity.ContactEditor.SaveMode.RELOAD:
                    resId = R.string.contactJoinErrorToast;
                    break;
                case ContactEditorBaseActivity.ContactEditor.SaveMode.CLOSE:
                case CompactContactEditorActivity.ContactEditor.SaveMode.CLOSE:
                    resId = R.string.contactSavedErrorToast;
                    break;
                default:
+335 −5
Original line number Diff line number Diff line
@@ -16,18 +16,36 @@

package com.android.contacts.activities;

import com.android.contacts.ContactSaveService;
import com.android.contacts.ContactsActivity;
import com.android.contacts.R;
import com.android.contacts.common.activity.RequestPermissionsActivity;
import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.model.RawContactDeltaList;
import com.android.contacts.common.model.account.AccountType;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.util.ImplicitIntentsUtil;
import com.android.contacts.detail.PhotoSelectionHandler;
import com.android.contacts.editor.CompactContactEditorFragment;
import com.android.contacts.editor.CompactPhotoSelectionFragment;
import com.android.contacts.editor.ContactEditorBaseFragment;
import com.android.contacts.editor.EditorIntents;
import com.android.contacts.editor.PhotoSourceDialogFragment;
import com.android.contacts.interactions.ContactDeletionInteraction;
import com.android.contacts.util.DialogManager;

import android.app.ActionBar;
import android.app.Dialog;
import android.app.FragmentTransaction;
import android.content.ContentValues;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.RawContacts;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;

import java.io.FileNotFoundException;
import java.util.ArrayList;
@@ -35,8 +53,17 @@ import java.util.ArrayList;
/**
 * Contact editor with only the most important fields displayed initially.
 */
public class CompactContactEditorActivity extends ContactEditorBaseActivity implements
        PhotoSourceDialogFragment.Listener, CompactPhotoSelectionFragment.Listener {
public class CompactContactEditorActivity extends ContactsActivity implements
        PhotoSourceDialogFragment.Listener, CompactPhotoSelectionFragment.Listener,
        DialogManager.DialogShowingViewActivity {
    private static final String TAG = "ContactEditorActivity";

    public static final String ACTION_JOIN_COMPLETED = "joinCompleted";
    public static final String ACTION_SAVE_COMPLETED = "saveCompleted";

    public static final int RESULT_CODE_SPLIT = 2;
    // 3 used for ContactDeletionInteraction.RESULT_CODE_DELETED
    public static final int RESULT_CODE_EDITED = 4;

    private static final String TAG_COMPACT_EDITOR = "compact_editor";
    private static final String TAG_PHOTO_SELECTION = "photo_selector";
@@ -46,6 +73,123 @@ public class CompactContactEditorActivity extends ContactEditorBaseActivity impl
    private static final String STATE_ACTION_BAR_TITLE = "action_bar_title";
    private static final String STATE_PHOTO_URI = "photo_uri";

    /**
     * Boolean intent key that specifies that this activity should finish itself
     * (instead of launching a new view intent) after the editor changes have been
     * saved.
     */
    public static final String INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED =
            "finishActivityOnSaveCompleted";

    /**
     * Contract for contact editors Fragments that are managed by this Activity.
     */
    public interface ContactEditor {

        /**
         * Modes that specify what the AsyncTask has to perform after saving
         */
        interface SaveMode {
            /**
             * Close the editor after saving
             */
            int CLOSE = 0;

            /**
             * Reload the data so that the user can continue editing
             */
            int RELOAD = 1;

            /**
             * Split the contact after saving
             */
            int SPLIT = 2;

            /**
             * Join another contact after saving
             */
            int JOIN = 3;

            /**
             * Navigate to the compact editor view after saving.
             */
            int COMPACT = 4;
        }

        /**
         * The status of the contact editor.
         */
        interface Status {
            /**
             * The loader is fetching data
             */
            int LOADING = 0;

            /**
             * Not currently busy. We are waiting for the user to enter data
             */
            int EDITING = 1;

            /**
             * The data is currently being saved. This is used to prevent more
             * auto-saves (they shouldn't overlap)
             */
            int SAVING = 2;

            /**
             * Prevents any more saves. This is used if in the following cases:
             * - After Save/Close
             * - After Revert
             * - After the user has accepted an edit suggestion
             * - After the user chooses to expand the compact editor
             */
            int CLOSING = 3;

            /**
             * Prevents saving while running a child activity.
             */
            int SUB_ACTIVITY = 4;
        }

        /**
         * Sets the hosting Activity that will receive callbacks from the contact editor.
         */
        void setListener(ContactEditorBaseFragment.Listener listener);

        /**
         * Initialize the contact editor.
         */
        void load(String action, Uri lookupUri, Bundle intentExtras);

        /**
         * Applies extras from the hosting Activity to the first writable raw contact.
         */
        void setIntentExtras(Bundle extras);

        /**
         * Saves or creates the contact based on the mode, and if successful
         * finishes the activity.
         */
        boolean save(int saveMode);

        /**
         * If there are no unsaved changes, just close the editor, otherwise the user is prompted
         * before discarding unsaved changes.
         */
        boolean revert();

        /**
         * Invoked after the contact is saved.
         */
        void onSaveCompleted(boolean hadChanges, int saveMode, boolean saveSucceeded,
                Uri contactLookupUri, Long joinContactId);

        /**
         * Invoked after the contact is joined.
         */
        void onJoinCompleted(Uri uri);
    }

    /**
     * Displays a PopupWindow with photo edit options.
     */
@@ -118,12 +262,116 @@ public class CompactContactEditorActivity extends ContactEditorBaseActivity impl
        }
    }

    private int mActionBarTitleResId;
    private ContactEditor mFragment;
    private boolean mFinishActivityOnSaveCompleted;
    private DialogManager mDialogManager = new DialogManager(this);

    private CompactPhotoSelectionFragment mPhotoSelectionFragment;
    private CompactPhotoSelectionHandler mPhotoSelectionHandler;
    private Uri mPhotoUri;
    private int mPhotoMode;
    private boolean mIsPhotoSelection;

    private final ContactEditorBaseFragment.Listener  mFragmentListener =
            new ContactEditorBaseFragment.Listener() {

                @Override
                public void onDeleteRequested(Uri contactUri) {
                    ContactDeletionInteraction.start(
                            CompactContactEditorActivity.this, contactUri, true);
                }

                @Override
                public void onReverted() {
                    finish();
                }

                @Override
                public void onSaveFinished(Intent resultIntent) {
                    if (mFinishActivityOnSaveCompleted) {
                        setResult(resultIntent == null ? RESULT_CANCELED : RESULT_OK, resultIntent);
                    } else if (resultIntent != null) {
                        ImplicitIntentsUtil.startActivityInApp(
                                CompactContactEditorActivity.this, resultIntent);
                    }
                    finish();
                }

                @Override
                public void onContactSplit(Uri newLookupUri) {
                    setResult(RESULT_CODE_SPLIT, /* data */ null);
                    finish();
                }

                @Override
                public void onContactNotFound() {
                    finish();
                }

                @Override
                public void onEditOtherContactRequested(
                        Uri contactLookupUri, ArrayList<ContentValues> values) {
                    final Intent intent = EditorIntents.createEditOtherContactIntent(
                            CompactContactEditorActivity.this, contactLookupUri, values);
                    ImplicitIntentsUtil.startActivityInApp(
                            CompactContactEditorActivity.this, intent);
                    finish();
                }

                @Override
                public void onCustomCreateContactActivityRequested(AccountWithDataSet account,
                        Bundle intentExtras) {
                    final AccountTypeManager accountTypes =
                            AccountTypeManager.getInstance(CompactContactEditorActivity.this);
                    final AccountType accountType = accountTypes.getAccountType(
                            account.type, account.dataSet);

                    Intent intent = new Intent();
                    intent.setClassName(accountType.syncAdapterPackageName,
                            accountType.getCreateContactActivityClassName());
                    intent.setAction(Intent.ACTION_INSERT);
                    intent.setType(Contacts.CONTENT_ITEM_TYPE);
                    if (intentExtras != null) {
                        intent.putExtras(intentExtras);
                    }
                    intent.putExtra(RawContacts.ACCOUNT_NAME, account.name);
                    intent.putExtra(RawContacts.ACCOUNT_TYPE, account.type);
                    intent.putExtra(RawContacts.DATA_SET, account.dataSet);
                    intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
                            | Intent.FLAG_ACTIVITY_FORWARD_RESULT);
                    startActivity(intent);
                    finish();
                }

                @Override
                public void onCustomEditContactActivityRequested(AccountWithDataSet account,
                        Uri rawContactUri, Bundle intentExtras, boolean redirect) {
                    final AccountTypeManager accountTypes =
                            AccountTypeManager.getInstance(CompactContactEditorActivity.this);
                    final AccountType accountType = accountTypes.getAccountType(
                            account.type, account.dataSet);

                    Intent intent = new Intent();
                    intent.setClassName(accountType.syncAdapterPackageName,
                            accountType.getEditContactActivityClassName());
                    intent.setAction(Intent.ACTION_EDIT);
                    intent.setData(rawContactUri);
                    if (intentExtras != null) {
                        intent.putExtras(intentExtras);
                    }

                    if (redirect) {
                        intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
                                | Intent.FLAG_ACTIVITY_FORWARD_RESULT);
                        startActivity(intent);
                        finish();
                    } else {
                        startActivity(intent);
                    }
                }
            };

    @Override
    public void onCreate(Bundle savedState) {
        super.onCreate(savedState);
@@ -132,6 +380,41 @@ public class CompactContactEditorActivity extends ContactEditorBaseActivity impl
            return;
        }

        final Intent intent = getIntent();
        final String action = intent.getAction();

        // Determine whether or not this activity should be finished after the user is done
        // editing the contact or if this activity should launch another activity to view the
        // contact's details.
        mFinishActivityOnSaveCompleted = intent.getBooleanExtra(
                INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED, false);

        // The only situation where action could be ACTION_JOIN_COMPLETED is if the
        // user joined the contact with another and closed the activity before
        // the save operation was completed.  The activity should remain closed then.
        if (ACTION_JOIN_COMPLETED.equals(action)) {
            finish();
            return;
        }

        if (ACTION_SAVE_COMPLETED.equals(action)) {
            finish();
            return;
        }

        final ActionBar actionBar = getActionBar();
        if (actionBar != null) {
            if (Intent.ACTION_EDIT.equals(action)) {
                mActionBarTitleResId = R.string.contact_editor_title_existing_contact;
            } else {
                mActionBarTitleResId = R.string.contact_editor_title_new_contact;
            }
            actionBar.setTitle(getResources().getString(mActionBarTitleResId));
            actionBar.setDisplayShowHomeEnabled(true);
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeAsUpIndicator(R.drawable.ic_close_dk);
        }

        setContentView(R.layout.compact_contact_editor_activity);

        if (savedState == null) {
@@ -171,11 +454,58 @@ public class CompactContactEditorActivity extends ContactEditorBaseActivity impl
        mPhotoSelectionFragment.setListener(this);

        // Load editor data (even if it's hidden)
        final String action = getIntent().getAction();
        final Uri uri = Intent.ACTION_EDIT.equals(action) ? getIntent().getData() : null;
        mFragment.load(action, uri, getIntent().getExtras());
    }

    @Override
    protected void onPause() {
        super.onPause();
        final InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
        final View currentFocus = getCurrentFocus();
        if (imm != null && currentFocus != null) {
            imm.hideSoftInputFromWindow(currentFocus.getWindowToken(), 0);
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        if (mFragment == null) {
            return;
        }

        final String action = intent.getAction();
        if (Intent.ACTION_EDIT.equals(action)) {
            mFragment.setIntentExtras(intent.getExtras());
        } else if (ACTION_SAVE_COMPLETED.equals(action)) {
            mFragment.onSaveCompleted(true,
                    intent.getIntExtra(ContactEditorBaseFragment.SAVE_MODE_EXTRA_KEY,
                            ContactEditor.SaveMode.CLOSE),
                    intent.getBooleanExtra(ContactSaveService.EXTRA_SAVE_SUCCEEDED, false),
                    intent.getData(),
                    intent.getLongExtra(ContactEditorBaseFragment.JOIN_CONTACT_ID_EXTRA_KEY, -1));
        } else if (ACTION_JOIN_COMPLETED.equals(action)) {
            mFragment.onJoinCompleted(intent.getData());
        }
    }

    @Override
    protected Dialog onCreateDialog(int id, Bundle args) {
        if (DialogManager.isManagedId(id)) return mDialogManager.onCreateDialog(id, args);

        // Nobody knows about the Dialog
        Log.w(TAG, "Unknown dialog requested, id: " + id + ", args: " + args);
        return null;
    }

    @Override
    public DialogManager getDialogManager() {
        return mDialogManager;
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(STATE_PHOTO_MODE, mPhotoMode);
@@ -201,8 +531,8 @@ public class CompactContactEditorActivity extends ContactEditorBaseActivity impl
        if (mIsPhotoSelection) {
            mIsPhotoSelection = false;
            showEditorFragment();
        } else {
            super.onBackPressed();
        } else if (mFragment != null) {
            mFragment.revert();
        }
    }

+0 −373

File deleted.

Preview size limit exceeded, changes collapsed.

+2 −2
Original line number Diff line number Diff line
@@ -658,8 +658,8 @@ public class ContactSelectionActivity extends AppCompatContactsActivity implemen

    private void startCreateNewContactActivity() {
        Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
        intent.putExtra(
                ContactEditorBaseActivity.INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED, true);
        intent.putExtra(CompactContactEditorActivity.
                INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED, true);
        startActivityAndForwardResult(intent);
    }

+4 −7
Original line number Diff line number Diff line
@@ -58,9 +58,9 @@ import android.widget.Toast;
import com.android.contacts.ContactSaveService;
import com.android.contacts.GroupMetaDataLoader;
import com.android.contacts.R;
import com.android.contacts.activities.CompactContactEditorActivity;
import com.android.contacts.activities.CompactContactEditorActivity.ContactEditor;
import com.android.contacts.activities.ContactEditorAccountsChangedActivity;
import com.android.contacts.activities.ContactEditorBaseActivity;
import com.android.contacts.activities.ContactEditorBaseActivity.ContactEditor;
import com.android.contacts.activities.ContactSelectionActivity;
import com.android.contacts.common.logging.ScreenEvent.ScreenType;
import com.android.contacts.common.model.AccountTypeManager;
@@ -81,19 +81,16 @@ import com.android.contacts.quickcontact.QuickContactActivity;
import com.android.contacts.util.HelpUtils;
import com.android.contacts.util.PhoneCapabilityTester;
import com.android.contacts.util.UiClosables;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.UnmodifiableIterator;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;

import javax.annotation.Nullable;

/**
 * Base Fragment for contact editors.
 */
@@ -111,7 +108,7 @@ abstract public class ContactEditorBaseFragment extends Fragment implements
    private static final List<String> VALID_INTENT_ACTIONS = new ArrayList<String>() {{
        add(Intent.ACTION_EDIT);
        add(Intent.ACTION_INSERT);
        add(ContactEditorBaseActivity.ACTION_SAVE_COMPLETED);
        add(CompactContactEditorActivity.ACTION_SAVE_COMPLETED);
    }};

    private static final String KEY_ACTION = "action";
Loading