ContactEditorBaseActivity.java revision 5d1c571dbe5b4a60aec6cb81d69e9e595813268e
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.contacts.activities;
18
19import com.android.contacts.ContactSaveService;
20import com.android.contacts.ContactsActivity;
21import com.android.contacts.R;
22import com.android.contacts.common.model.AccountTypeManager;
23import com.android.contacts.common.model.account.AccountType;
24import com.android.contacts.common.model.account.AccountWithDataSet;
25import com.android.contacts.editor.ContactEditorBaseFragment;
26import com.android.contacts.editor.ContactEditorFragment;
27import com.android.contacts.interactions.ContactDeletionInteraction;
28import com.android.contacts.util.DialogManager;
29
30import android.app.ActionBar;
31import android.app.Dialog;
32import android.content.ContentValues;
33import android.content.Intent;
34import android.net.Uri;
35import android.os.Bundle;
36import android.provider.ContactsContract;
37import android.provider.ContactsContract.Contacts;
38import android.provider.ContactsContract.RawContacts;
39import android.util.Log;
40
41import java.util.ArrayList;
42
43/**
44 * Base Activity for contact editors.
45 */
46abstract public class ContactEditorBaseActivity extends ContactsActivity
47        implements DialogManager.DialogShowingViewActivity {
48    protected static final String TAG = "ContactEditorActivity";
49
50    public static final String ACTION_JOIN_COMPLETED = "joinCompleted";
51    public static final String ACTION_SAVE_COMPLETED = "saveCompleted";
52
53    /**
54     * Contract for contact editors Fragments that are managed by this Activity.
55     */
56    public interface ContactEditor {
57
58        /**
59         * Modes that specify what the AsyncTask has to perform after saving
60         */
61        public interface SaveMode {
62            /**
63             * Close the editor after saving
64             */
65            public static final int CLOSE = 0;
66
67            /**
68             * Reload the data so that the user can continue editing
69             */
70            public static final int RELOAD = 1;
71
72            /**
73             * Split the contact after saving
74             */
75            public static final int SPLIT = 2;
76
77            /**
78             * Join another contact after saving
79             */
80            public static final int JOIN = 3;
81
82            /**
83             * Navigate to Contacts Home activity after saving.
84             */
85            public static final int HOME = 4;
86        }
87
88        /**
89         * The status of the contact editor.
90         */
91        public interface Status {
92            /**
93             * The loader is fetching data
94             */
95            public static final int LOADING = 0;
96
97            /**
98             * Not currently busy. We are waiting for the user to enter data
99             */
100            public static final int EDITING = 1;
101
102            /**
103             * The data is currently being saved. This is used to prevent more
104             * auto-saves (they shouldn't overlap)
105             */
106            public static final int SAVING = 2;
107
108            /**
109             * Prevents any more saves. This is used if in the following cases:
110             * - After Save/Close
111             * - After Revert
112             * - After the user has accepted an edit suggestion
113             */
114            public static final int CLOSING = 3;
115
116            /**
117             * Prevents saving while running a child activity.
118             */
119            public static final int SUB_ACTIVITY = 4;
120        }
121
122        /**
123         * Sets the hosting Activity that will receive callbacks from the contact editor.
124         */
125        void setListener(ContactEditorBaseFragment.Listener listener);
126
127        /**
128         * Initialize the contact editor.
129         */
130        void load(String action, Uri lookupUri, Bundle intentExtras);
131
132        /**
133         * Merges extras from the intent.
134         */
135        void setIntentExtras(Bundle extras);
136
137        /**
138         * Saves or creates the contact based on the mode, and if successful
139         * finishes the activity.
140         */
141        boolean save(int saveMode);
142
143        /**
144         * Invoked after the contact is saved.
145         */
146        void onSaveCompleted(boolean hadChanges, int saveMode, boolean saveSucceeded,
147                Uri contactLookupUri);
148
149        /**
150         * Invoked after the contact is joined.
151         */
152        void onJoinCompleted(Uri uri);
153    }
154
155    /**
156     * Boolean intent key that specifies that this activity should finish itself
157     * (instead of launching a new view intent) after the editor changes have been
158     * saved.
159     */
160    public static final String INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED =
161            "finishActivityOnSaveCompleted";
162
163    protected ContactEditor mFragment;
164    private boolean mFinishActivityOnSaveCompleted;
165
166    private DialogManager mDialogManager = new DialogManager(this);
167
168    @Override
169    public void onCreate(Bundle savedState) {
170        super.onCreate(savedState);
171
172        final Intent intent = getIntent();
173        final String action = intent.getAction();
174
175        // Determine whether or not this activity should be finished after the user is done
176        // editing the contact or if this activity should launch another activity to view the
177        // contact's details.
178        mFinishActivityOnSaveCompleted = intent.getBooleanExtra(
179                INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED, false);
180
181        // The only situation where action could be ACTION_JOIN_COMPLETED is if the
182        // user joined the contact with another and closed the activity before
183        // the save operation was completed.  The activity should remain closed then.
184        if (ACTION_JOIN_COMPLETED.equals(action)) {
185            finish();
186            return;
187        }
188
189        if (ACTION_SAVE_COMPLETED.equals(action)) {
190            finish();
191            return;
192        }
193
194        ActionBar actionBar = getActionBar();
195        if (actionBar != null) {
196            if (Intent.ACTION_EDIT.equals(action)) {
197                actionBar.setTitle(getResources().getString(
198                        R.string.contact_editor_title_existing_contact));
199            } else {
200                actionBar.setTitle(getResources().getString(
201                        R.string.contact_editor_title_new_contact));
202            }
203            actionBar.setDisplayShowHomeEnabled(true);
204            actionBar.setDisplayHomeAsUpEnabled(true);
205        }
206    }
207
208    @Override
209    protected void onNewIntent(Intent intent) {
210        super.onNewIntent(intent);
211
212        if (mFragment == null) {
213            return;
214        }
215
216        String action = intent.getAction();
217        if (Intent.ACTION_EDIT.equals(action)) {
218            mFragment.setIntentExtras(intent.getExtras());
219        } else if (ACTION_SAVE_COMPLETED.equals(action)) {
220            mFragment.onSaveCompleted(true,
221                    intent.getIntExtra(ContactEditorFragment.SAVE_MODE_EXTRA_KEY,
222                            ContactEditor.SaveMode.CLOSE),
223                    intent.getBooleanExtra(ContactSaveService.EXTRA_SAVE_SUCCEEDED, false),
224                    intent.getData());
225        } else if (ACTION_JOIN_COMPLETED.equals(action)) {
226            mFragment.onJoinCompleted(intent.getData());
227        }
228    }
229
230    @Override
231    protected Dialog onCreateDialog(int id, Bundle args) {
232        if (DialogManager.isManagedId(id)) return mDialogManager.onCreateDialog(id, args);
233
234        // Nobody knows about the Dialog
235        Log.w(TAG, "Unknown dialog requested, id: " + id + ", args: " + args);
236        return null;
237    }
238
239    @Override
240    public void onBackPressed() {
241        if (mFragment != null) {
242            mFragment.save(ContactEditor.SaveMode.CLOSE);
243        }
244    }
245
246    protected final ContactEditorBaseFragment.Listener  mFragmentListener =
247            new ContactEditorBaseFragment.Listener() {
248
249        @Override
250        public void onDeleteRequested(Uri contactUri) {
251            ContactDeletionInteraction.start(ContactEditorBaseActivity.this, contactUri, true);
252        }
253
254        @Override
255        public void onReverted() {
256            finish();
257        }
258
259        @Override
260        public void onSaveFinished(Intent resultIntent) {
261            if (mFinishActivityOnSaveCompleted) {
262                setResult(resultIntent == null ? RESULT_CANCELED : RESULT_OK, resultIntent);
263            } else if (resultIntent != null) {
264                startActivity(resultIntent);
265            }
266            finish();
267        }
268
269        @Override
270        public void onContactSplit(Uri newLookupUri) {
271            finish();
272        }
273
274        @Override
275        public void onContactNotFound() {
276            finish();
277        }
278
279        @Override
280        public void onEditOtherContactRequested(
281                Uri contactLookupUri, ArrayList<ContentValues> values) {
282            Intent intent = new Intent(Intent.ACTION_EDIT, contactLookupUri);
283            intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
284                    | Intent.FLAG_ACTIVITY_FORWARD_RESULT);
285            intent.putExtra(ContactEditorFragment.INTENT_EXTRA_ADD_TO_DEFAULT_DIRECTORY, "");
286
287            // Pass on all the data that has been entered so far
288            if (values != null && values.size() != 0) {
289                intent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, values);
290            }
291
292            startActivity(intent);
293            finish();
294        }
295
296        @Override
297        public void onCustomCreateContactActivityRequested(AccountWithDataSet account,
298                Bundle intentExtras) {
299            final AccountTypeManager accountTypes =
300                    AccountTypeManager.getInstance(ContactEditorBaseActivity.this);
301            final AccountType accountType = accountTypes.getAccountType(
302                    account.type, account.dataSet);
303
304            Intent intent = new Intent();
305            intent.setClassName(accountType.syncAdapterPackageName,
306                    accountType.getCreateContactActivityClassName());
307            intent.setAction(Intent.ACTION_INSERT);
308            intent.setType(Contacts.CONTENT_ITEM_TYPE);
309            if (intentExtras != null) {
310                intent.putExtras(intentExtras);
311            }
312            intent.putExtra(RawContacts.ACCOUNT_NAME, account.name);
313            intent.putExtra(RawContacts.ACCOUNT_TYPE, account.type);
314            intent.putExtra(RawContacts.DATA_SET, account.dataSet);
315            intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
316                    | Intent.FLAG_ACTIVITY_FORWARD_RESULT);
317            startActivity(intent);
318            finish();
319        }
320
321        @Override
322        public void onCustomEditContactActivityRequested(AccountWithDataSet account,
323                Uri rawContactUri, Bundle intentExtras, boolean redirect) {
324            final AccountTypeManager accountTypes =
325                    AccountTypeManager.getInstance(ContactEditorBaseActivity.this);
326            final AccountType accountType = accountTypes.getAccountType(
327                    account.type, account.dataSet);
328
329            Intent intent = new Intent();
330            intent.setClassName(accountType.syncAdapterPackageName,
331                    accountType.getEditContactActivityClassName());
332            intent.setAction(Intent.ACTION_EDIT);
333            intent.setData(rawContactUri);
334            if (intentExtras != null) {
335                intent.putExtras(intentExtras);
336            }
337
338            if (redirect) {
339                intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
340                        | Intent.FLAG_ACTIVITY_FORWARD_RESULT);
341                startActivity(intent);
342                finish();
343            } else {
344                startActivity(intent);
345            }
346        }
347    };
348
349    @Override
350    public DialogManager getDialogManager() {
351        return mDialogManager;
352    }
353}
354