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