1/*
2 * Copyright (C) 2010 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.tests.allintents;
18
19import android.accounts.Account;
20import android.app.ListActivity;
21import android.app.SearchManager;
22import android.content.ComponentName;
23import android.content.ContentUris;
24import android.content.ContentValues;
25import android.content.Intent;
26import android.database.Cursor;
27import android.net.Uri;
28import android.os.Bundle;
29import android.provider.Contacts.ContactMethods;
30import android.provider.Contacts.People;
31import android.provider.Contacts.Phones;
32import android.provider.ContactsContract.CommonDataKinds.Email;
33import android.provider.ContactsContract.CommonDataKinds.Organization;
34import android.provider.ContactsContract.CommonDataKinds.Phone;
35import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
36import android.provider.ContactsContract.Contacts;
37import android.provider.ContactsContract.Data;
38import android.provider.ContactsContract.Intents;
39import android.provider.ContactsContract.Intents.Insert;
40import android.provider.ContactsContract.RawContacts;
41import android.view.View;
42import android.widget.ArrayAdapter;
43import android.widget.ListView;
44import android.widget.Toast;
45
46import com.android.contacts.tests.R;
47import com.android.contacts.tests.quickcontact.QuickContactTestsActivity;
48
49import java.util.ArrayList;
50
51/**
52 * An activity that provides access to various modes of the contacts application.
53 * Useful for manual and scripted tests.
54 * <p>
55 * Note: this class cannot depend (directly on indirectly) on anything outside the test package.
56 */
57@SuppressWarnings("deprecation")
58public class AllIntentsActivity extends ListActivity
59        implements SelectAccountDialogFragment.Listener {
60
61    /** The name of the package of the contacts application. */
62    private String mContactsPackageName;
63
64    private static final String CONTACT_LIST_ACTIVITY_CLASS_NAME =
65            "com.android.contacts.activities.PeopleActivity";
66
67    public enum ContactsIntent {
68        VIEW_CONTACT_WITHOUT_ID,
69        ACTION_PICK_CONTACT,
70        ACTION_PICK_CONTACT_LEGACY,
71        ACTION_PICK_PHONE,
72        ACTION_PICK_PHONE_LEGACY,
73        ACTION_PICK_POSTAL,
74        ACTION_PICK_POSTAL_LEGACY,
75        ACTION_PICK_EMAIL,
76        ACTION_CREATE_SHORTCUT_CONTACT,
77        ACTION_CREATE_SHORTCUT_DIAL,
78        ACTION_CREATE_SHORTCUT_MESSAGE,
79        ACTION_GET_CONTENT_CONTACT,
80        ACTION_GET_CONTENT_CONTACT_LEGACY,
81        ACTION_GET_CONTENT_PHONE,
82        ACTION_GET_CONTENT_PHONE_LEGACY,
83        ACTION_GET_CONTENT_POSTAL,
84        ACTION_GET_CONTENT_POSTAL_LEGACY,
85        ACTION_INSERT_OR_EDIT,
86        ACTION_INSERT_OR_EDIT_PHONE_NUMBER,
87        ACTION_INSERT_OR_EDIT_EMAIL_ADDRESS,
88        ACTION_SEARCH_CALL,
89        ACTION_SEARCH_CONTACT,
90        ACTION_SEARCH_EMAIL,
91        ACTION_SEARCH_PHONE,
92        SEARCH_SUGGESTION_CLICKED_CONTACT,
93        EDIT_CONTACT,
94        EDIT_CONTACT_LOOKUP,
95        EDIT_CONTACT_LOOKUP_ID,
96        EDIT_RAW_CONTACT,
97        EDIT_LEGACY,
98        EDIT_NEW_CONTACT,
99        EDIT_NEW_CONTACT_WITH_DATA,
100        EDIT_NEW_CONTACT_FOR_ACCOUNT,
101        EDIT_NEW_CONTACT_FOR_ACCOUNT_WITH_DATA,
102        EDIT_NEW_RAW_CONTACT,
103        EDIT_NEW_LEGACY,
104        VIEW_CONTACT,
105        VIEW_CONTACT_LOOKUP,
106        VIEW_CONTACT_LOOKUP_ID,
107        VIEW_RAW_CONTACT,
108        VIEW_LEGACY,
109        QUICK_CONTACT_TESTS_ACTIVITY;
110
111        public static ContactsIntent get(int ordinal) {
112            return values()[ordinal];
113        }
114    }
115
116    @Override
117    protected void onCreate(Bundle savedInstanceState) {
118        super.onCreate(savedInstanceState);
119
120        setListAdapter(new ArrayAdapter<String>(this, R.layout.intent_list_item,
121                getResources().getStringArray(R.array.allIntents)));
122        mContactsPackageName = getResources().getString(
123                R.string.target_package_name);
124    }
125
126    @Override
127    protected void onListItemClick(ListView l, View v, int position, long id) {
128        super.onListItemClick(l, v, position, id);
129
130        switch (ContactsIntent.get(position)) {
131            case ACTION_PICK_CONTACT: {
132                startContactSelectionActivityForResult(
133                        new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI));
134                break;
135            }
136            case ACTION_PICK_CONTACT_LEGACY: {
137                startContactSelectionActivityForResult(
138                        new Intent(Intent.ACTION_PICK, People.CONTENT_URI));
139                break;
140            }
141            case ACTION_PICK_PHONE: {
142                startContactSelectionActivityForResult(
143                        new Intent(Intent.ACTION_PICK, Phone.CONTENT_URI));
144                break;
145            }
146            case ACTION_PICK_PHONE_LEGACY: {
147                startContactSelectionActivityForResult(
148                        new Intent(Intent.ACTION_PICK, Phones.CONTENT_URI));
149                break;
150            }
151            case ACTION_PICK_POSTAL: {
152                startContactSelectionActivityForResult(
153                        new Intent(Intent.ACTION_PICK, StructuredPostal.CONTENT_URI));
154                break;
155            }
156            case ACTION_PICK_POSTAL_LEGACY: {
157                Intent intent = new Intent(Intent.ACTION_PICK);
158                intent.setType(ContactMethods.CONTENT_POSTAL_TYPE);
159                startContactSelectionActivityForResult(intent);
160                break;
161            }
162            case ACTION_PICK_EMAIL: {
163                startContactSelectionActivityForResult(
164                        new Intent(Intent.ACTION_PICK, Email.CONTENT_URI));
165                break;
166            }
167            case ACTION_CREATE_SHORTCUT_CONTACT: {
168                Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
169                startContactSelectionActivityForResult(intent);
170                break;
171            }
172            case ACTION_CREATE_SHORTCUT_DIAL: {
173                Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
174                bindIntentToClass(intent, "alias.DialShortcut");
175                startActivityForResult(intent, 0);
176                break;
177            }
178            case ACTION_CREATE_SHORTCUT_MESSAGE: {
179                Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
180                bindIntentToClass(intent, "alias.MessageShortcut");
181                startActivityForResult(intent, 0);
182                break;
183            }
184            case ACTION_GET_CONTENT_CONTACT: {
185                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
186                intent.setType(Contacts.CONTENT_ITEM_TYPE);
187                startContactSelectionActivityForResult(intent);
188                break;
189            }
190            case ACTION_GET_CONTENT_CONTACT_LEGACY: {
191                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
192                intent.setType(People.CONTENT_ITEM_TYPE);
193                startContactSelectionActivityForResult(intent);
194                break;
195            }
196            case ACTION_GET_CONTENT_PHONE: {
197                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
198                intent.setType(Phone.CONTENT_ITEM_TYPE);
199                startContactSelectionActivityForResult(intent);
200                break;
201            }
202            case ACTION_GET_CONTENT_PHONE_LEGACY: {
203                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
204                intent.setType(Phones.CONTENT_ITEM_TYPE);
205                startContactSelectionActivityForResult(intent);
206                break;
207            }
208            case ACTION_GET_CONTENT_POSTAL: {
209                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
210                intent.setType(StructuredPostal.CONTENT_ITEM_TYPE);
211                startContactSelectionActivityForResult(intent);
212                break;
213            }
214            case ACTION_GET_CONTENT_POSTAL_LEGACY: {
215                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
216                intent.setType(ContactMethods.CONTENT_POSTAL_ITEM_TYPE);
217                startContactSelectionActivityForResult(intent);
218                break;
219            }
220            case ACTION_INSERT_OR_EDIT: {
221                Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
222                intent.setType(Contacts.CONTENT_ITEM_TYPE);
223                putDataExtra(intent);
224                startActivity(intent);
225                break;
226            }
227            case ACTION_INSERT_OR_EDIT_PHONE_NUMBER: {
228                Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
229                intent.setType(Contacts.CONTENT_ITEM_TYPE);
230                intent.putExtra(Insert.PHONE, "5123456789");
231                startActivity(intent);
232                break;
233            }
234            case ACTION_INSERT_OR_EDIT_EMAIL_ADDRESS: {
235                Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
236                intent.setType(Contacts.CONTENT_ITEM_TYPE);
237                intent.putExtra(Insert.EMAIL, "android@android.com");
238                startActivity(intent);
239                break;
240            }
241            case ACTION_SEARCH_CALL: {
242                Intent intent = new Intent(Intent.ACTION_SEARCH);
243                intent.putExtra(SearchManager.ACTION_MSG, "call");
244                intent.putExtra(SearchManager.QUERY, "800-4664-411");
245                startSearchResultActivity(intent);
246                break;
247            }
248            case ACTION_SEARCH_CONTACT: {
249                Intent intent = new Intent(Intent.ACTION_SEARCH);
250                intent.putExtra(SearchManager.QUERY, "a");
251                intent.setType(Contacts.CONTENT_TYPE);
252                startSearchResultActivity(intent);
253                break;
254            }
255            case ACTION_SEARCH_EMAIL: {
256                Intent intent = new Intent(Intent.ACTION_SEARCH);
257                intent.putExtra(Insert.EMAIL, "a");
258                startSearchResultActivity(intent);
259                break;
260            }
261            case ACTION_SEARCH_PHONE: {
262                Intent intent = new Intent(Intent.ACTION_SEARCH);
263                intent.putExtra(Insert.PHONE, "800");
264                startSearchResultActivity(intent);
265                break;
266            }
267            case SEARCH_SUGGESTION_CLICKED_CONTACT: {
268                long contactId = findArbitraryContactWithPhoneNumber();
269                if (contactId != -1) {
270                    Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
271                    Intent intent = new Intent(Intents.SEARCH_SUGGESTION_CLICKED);
272                    intent.setData(contactUri);
273                    startContactListActivity(intent);
274                }
275                break;
276            }
277            case EDIT_CONTACT: {
278                final long contactId = findArbitraryContactWithPhoneNumber();
279                if (contactId != -1) {
280                    final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
281                    final Intent intent = new Intent(Intent.ACTION_EDIT, uri);
282                    startActivity(intent);
283                }
284                break;
285            }
286            case EDIT_CONTACT_LOOKUP: {
287                final long contactId = findArbitraryContactWithPhoneNumber();
288                if (contactId != -1) {
289                    final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
290                    final Uri lookupUri = Contacts.getLookupUri(getContentResolver(), uri);
291                    final String lookupKey = lookupUri.getPathSegments().get(2);
292                    final Uri lookupWithoutIdUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
293                            lookupKey);
294                    final Intent intent = new Intent(Intent.ACTION_EDIT, lookupWithoutIdUri);
295                    startActivity(intent);
296                }
297                break;
298            }
299            case EDIT_CONTACT_LOOKUP_ID: {
300                final long contactId = findArbitraryContactWithPhoneNumber();
301                if (contactId != -1) {
302                    final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
303                    final Uri lookupUri = Contacts.getLookupUri(getContentResolver(), uri);
304                    final Intent intent = new Intent(Intent.ACTION_EDIT, lookupUri);
305                    startActivity(intent);
306                }
307                break;
308            }
309            case EDIT_RAW_CONTACT: {
310                final long contactId = findArbitraryContactWithPhoneNumber();
311                if (contactId != -1) {
312                    final long rawContactId = findArbitraryRawContactOfContact(contactId);
313                    if (rawContactId != -1) {
314                        final Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI,
315                                rawContactId);
316                        final Intent intent = new Intent(Intent.ACTION_EDIT, uri);
317                        startActivity(intent);
318                    }
319                }
320                break;
321            }
322            case EDIT_LEGACY: {
323                final long contactId = findArbitraryContactWithPhoneNumber();
324                if (contactId != -1) {
325                    final long rawContactId = findArbitraryRawContactOfContact(contactId);
326                    if (rawContactId != -1) {
327                        final Uri legacyContentUri = Uri.parse("content://contacts/people");
328                        final Uri uri = ContentUris.withAppendedId(legacyContentUri, rawContactId);
329                        final Intent intent = new Intent(Intent.ACTION_EDIT, uri);
330                        startActivity(intent);
331                    }
332                }
333                break;
334            }
335            case EDIT_NEW_CONTACT: {
336                startActivity(new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
337                break;
338            }
339            case EDIT_NEW_CONTACT_WITH_DATA: {
340                Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
341                putDataExtra(intent);
342                startActivity(intent);
343                break;
344            }
345            case EDIT_NEW_CONTACT_FOR_ACCOUNT:
346            case EDIT_NEW_CONTACT_FOR_ACCOUNT_WITH_DATA: {
347                final SelectAccountDialogFragment dialog = new SelectAccountDialogFragment();
348                dialog.setArguments(SelectAccountDialogFragment.createBundle(position));
349                dialog.show(getFragmentManager(), SelectAccountDialogFragment.TAG);
350                break;
351            }
352            case EDIT_NEW_RAW_CONTACT: {
353                startActivity(new Intent(Intent.ACTION_INSERT, RawContacts.CONTENT_URI));
354                break;
355            }
356            case EDIT_NEW_LEGACY: {
357                final Uri legacyContentUri = Uri.parse("content://contacts/people");
358                startActivity(new Intent(Intent.ACTION_INSERT, legacyContentUri));
359                break;
360            }
361            case VIEW_CONTACT: {
362                final long contactId = findArbitraryContactWithPhoneNumber();
363                if (contactId != -1) {
364                    final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
365                    final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
366                    startActivity(intent);
367                }
368                break;
369            }
370            case VIEW_CONTACT_WITHOUT_ID: {
371                startActivity(new Intent(Intent.ACTION_VIEW, Contacts.CONTENT_URI));
372                break;
373            }
374            case VIEW_CONTACT_LOOKUP: {
375                final long contactId = findArbitraryContactWithPhoneNumber();
376                if (contactId != -1) {
377                    final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
378                    final Uri lookupUri = Contacts.getLookupUri(getContentResolver(), uri);
379                    final String lookupKey = lookupUri.getPathSegments().get(2);
380                    final Uri lookupWithoutIdUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
381                            lookupKey);
382                    final Intent intent = new Intent(Intent.ACTION_VIEW, lookupWithoutIdUri);
383                    startActivity(intent);
384                }
385                break;
386            }
387            case VIEW_CONTACT_LOOKUP_ID: {
388                final long contactId = findArbitraryContactWithPhoneNumber();
389                if (contactId != -1) {
390                    final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
391                    final Uri lookupUri = Contacts.getLookupUri(getContentResolver(), uri);
392                    final Intent intent = new Intent(Intent.ACTION_VIEW, lookupUri);
393                    startActivity(intent);
394                }
395                break;
396            }
397            case VIEW_RAW_CONTACT: {
398                final long contactId = findArbitraryContactWithPhoneNumber();
399                if (contactId != -1) {
400                    final long rawContactId = findArbitraryRawContactOfContact(contactId);
401                    if (rawContactId != -1) {
402                        final Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI,
403                                rawContactId);
404                        final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
405                        startActivity(intent);
406                    }
407                }
408                break;
409            }
410            case VIEW_LEGACY: {
411                final long contactId = findArbitraryContactWithPhoneNumber();
412                if (contactId != -1) {
413                    final long rawContactId = findArbitraryRawContactOfContact(contactId);
414                    if (rawContactId != -1) {
415                        final Uri legacyContentUri = Uri.parse("content://contacts/people");
416                        final Uri uri = ContentUris.withAppendedId(legacyContentUri, rawContactId);
417                        final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
418                        startActivity(intent);
419                    }
420                }
421                break;
422            }
423            case QUICK_CONTACT_TESTS_ACTIVITY: {
424                startActivity(new Intent(this, QuickContactTestsActivity.class));
425                break;
426            }
427
428            default: {
429                Toast.makeText(this, "Sorry, we forgot to write this...", Toast.LENGTH_LONG).show();
430            }
431        }
432    }
433
434    /** Creates an intent that is bound to a specific activity by name. */
435    private Intent bindIntentToClass(Intent intent, String activityClassName) {
436        intent.setComponent(new ComponentName(mContactsPackageName,
437                    activityClassName));
438        return intent;
439    }
440
441    private void startContactListActivity(Intent intent) {
442        bindIntentToClass(intent, CONTACT_LIST_ACTIVITY_CLASS_NAME);
443        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
444        startActivity(intent);
445    }
446
447    private void startContactSelectionActivityForResult(Intent intent) {
448        startActivityForResult(intent, 12);
449    }
450
451    private void startSearchResultActivity(Intent intent) {
452        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
453        startActivity(intent);
454    }
455
456    @Override
457    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
458        Intent intent = new Intent(this, ResultActivity.class);
459        intent.putExtra("resultCode", resultCode);
460        intent.putExtra("data", data);
461        startActivity(intent);
462    }
463
464    private long findArbitraryContactWithPhoneNumber() {
465        final Cursor cursor = getContentResolver().query(Contacts.CONTENT_URI,
466                new String[] { Contacts._ID },
467                Contacts.HAS_PHONE_NUMBER + "!=0",
468                null, "RANDOM() LIMIT 1");
469        try {
470            if (cursor.moveToFirst()) {
471                return cursor.getLong(0);
472            }
473        } finally {
474            cursor.close();
475        }
476        Toast.makeText(this, "Failed to find a contact with a phone number. Aborting.",
477                Toast.LENGTH_SHORT).show();
478        return -1;
479    }
480
481    private long findArbitraryRawContactOfContact(long contactId) {
482        final Cursor cursor = getContentResolver().query(RawContacts.CONTENT_URI,
483                new String[] { RawContacts._ID },
484                RawContacts.CONTACT_ID + "=?",
485                new String[] { String.valueOf(contactId) },
486                RawContacts._ID + " LIMIT 1");
487        try {
488            if (cursor.moveToFirst()) {
489                return cursor.getLong(0);
490            }
491        } finally {
492            cursor.close();
493        }
494        Toast.makeText(this, "Failed to find a raw contact of contact with ID " + contactId +
495                ". Aborting", Toast.LENGTH_SHORT).show();
496        return -1;
497    }
498
499    @Override
500    public void onAccountChosen(Account account, String dataSet, int tag) {
501        switch (ContactsIntent.get(tag)) {
502            case EDIT_NEW_CONTACT_FOR_ACCOUNT: {
503                final Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
504                intent.putExtra(Insert.EXTRA_ACCOUNT, account);
505                intent.putExtra(Insert.EXTRA_DATA_SET, dataSet);
506                startActivity(intent);
507                break;
508            }
509            case EDIT_NEW_CONTACT_FOR_ACCOUNT_WITH_DATA: {
510                final Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
511
512                intent.putExtra(Insert.EXTRA_ACCOUNT, account);
513                intent.putExtra(Insert.EXTRA_DATA_SET, dataSet);
514                putDataExtra(intent);
515
516                startActivity(intent);
517                break;
518            }
519            default:
520                break;
521        }
522    }
523
524    public void putDataExtra(final Intent intent) {
525        ContentValues row1 = new ContentValues();
526        row1.put(Data.MIMETYPE, Organization.CONTENT_ITEM_TYPE);
527        row1.put(Organization.COMPANY, "Android");
528
529        ContentValues row2 = new ContentValues();
530        row2.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
531        row2.put(Email.TYPE, Email.TYPE_CUSTOM);
532        row2.put(Email.LABEL, "Green Bot");
533        row2.put(Email.ADDRESS, "android@android.com");
534
535        final ArrayList<ContentValues> rows = new ArrayList<>();
536        rows.add(row1);
537        rows.add(row2);
538
539        intent.putParcelableArrayListExtra(Insert.DATA, rows);
540    }
541}
542