1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/*
2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project
3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License");
5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License.
6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at
7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *      http://www.apache.org/licenses/LICENSE-2.0
9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software
11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS,
12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and
14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License.
15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging.ui;
17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.app.Activity;
19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.app.Fragment;
20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.app.PendingIntent;
21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.appwidget.AppWidgetManager;
22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.ActivityNotFoundException;
23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.ClipData;
24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.ComponentName;
25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.ContentValues;
26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Context;
27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Intent;
28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.graphics.Point;
29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.graphics.Rect;
30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.media.RingtoneManager;
31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.net.Uri;
32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Bundle;
33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.provider.ContactsContract.Contacts;
34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.provider.ContactsContract.Intents;
35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.provider.MediaStore;
36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.provider.Telephony;
37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.annotation.Nullable;
38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v4.app.TaskStackBuilder;
39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v4.content.LocalBroadcastManager;
40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.text.TextUtils;
41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.ex.photo.Intents.PhotoViewIntentBuilder;
43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.R;
44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.ConversationImagePartsView;
45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.MediaScratchFileProvider;
46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.MessagingContentProvider;
47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.MessageData;
48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.MessagePartData;
49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.ParticipantData;
50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.receiver.NotificationReceiver;
51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.sms.MmsSmsUtils;
52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.appsettings.ApnEditorActivity;
53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.appsettings.ApnSettingsActivity;
54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.appsettings.ApplicationSettingsActivity;
55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.appsettings.PerSubscriptionSettingsActivity;
56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.appsettings.SettingsActivity;
57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.attachmentchooser.AttachmentChooserActivity;
58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.conversation.ConversationActivity;
59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.conversation.LaunchConversationActivity;
60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.conversationlist.ArchivedConversationListActivity;
61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.conversationlist.ConversationListActivity;
62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.conversationlist.ForwardMessageActivity;
63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.conversationsettings.PeopleAndOptionsActivity;
64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.debug.DebugMmsConfigActivity;
65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.photoviewer.BuglePhotoViewActivity;
66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.Assert;
67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.ContentType;
68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.ConversationIdSet;
69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.LogUtil;
70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.UiUtils;
71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.UriUtil;
72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/**
74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * A central repository of Intents used to start activities.
75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class UIIntentsImpl extends UIIntents {
77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final String CELL_BROADCAST_LIST_ACTIVITY =
78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            "com.android.cellbroadcastreceiver.CellBroadcastListActivity";
79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final String CALL_TARGET_CLICK_KEY = "touchPoint";
80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final String CALL_TARGET_CLICK_EXTRA_KEY =
81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            "android.telecom.extra.OUTGOING_CALL_EXTRAS";
82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final String MEDIA_SCANNER_CLASS =
83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            "com.android.providers.media.MediaScannerService";
84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final String MEDIA_SCANNER_PACKAGE = "com.android.providers.media";
85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final String MEDIA_SCANNER_SCAN_ACTION = "android.media.IMediaScannerService";
86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * Get an intent which takes you to a conversation
89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private Intent getConversationActivityIntent(final Context context,
91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String conversationId, final MessageData draft,
92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final boolean withCustomTransition) {
93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(context, ConversationActivity.class);
94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // Always try to reuse the same ConversationActivity in the current task so that we don't
96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // have two conversation activities in the back stack.
97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // Otherwise we're starting a new conversation
100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (conversationId != null) {
101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            intent.putExtra(UI_INTENT_EXTRA_CONVERSATION_ID, conversationId);
102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (draft != null) {
104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            intent.putExtra(UI_INTENT_EXTRA_DRAFT_DATA, draft);
105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // If draft attachments came from an external content provider via a share intent, we
107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // need to propagate the URI permissions through to ConversationActivity. This requires
108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // putting the URIs into the ClipData (setData also works, but accepts only one URI).
109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            ClipData clipData = null;
110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            for (final MessagePartData partData : draft.getParts()) {
111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (partData.isAttachment()) {
112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    final Uri uri = partData.getContentUri();
113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (clipData == null) {
114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        clipData = ClipData.newRawUri("Attachments", uri);
115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    } else {
116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        clipData.addItem(new ClipData.Item(uri));
117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (clipData != null) {
121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                intent.setClipData(clipData);
122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (withCustomTransition) {
126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            intent.putExtra(UI_INTENT_EXTRA_WITH_CUSTOM_TRANSITION, true);
127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (!(context instanceof Activity)) {
130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // If the caller supplies an application context, and not an activity context, we must
131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // include this flag
132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return intent;
135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchPermissionCheckActivity(final Context context) {
139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(context, PermissionCheckActivity.class);
140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startActivity(intent);
141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * Get an intent which takes you to the conversation list
145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private Intent getConversationListActivityIntent(final Context context) {
147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return new Intent(context, ConversationListActivity.class);
148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchConversationListActivity(final Context context) {
152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = getConversationListActivityIntent(context);
153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startActivity(intent);
154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * Get an intent which shows the low storage warning activity.
158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private Intent getSmsStorageLowWarningActivityIntent(final Context context) {
160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return new Intent(context, SmsStorageLowWarningActivity.class);
161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchConversationActivity(final Context context,
165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String conversationId, final MessageData draft, final Bundle activityOptions,
166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final boolean withCustomTransition) {
167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        Assert.isTrue(!withCustomTransition || activityOptions != null);
168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = getConversationActivityIntent(context, conversationId, draft,
169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                withCustomTransition);
170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startActivity(intent, activityOptions);
171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchConversationActivityNewTask(
175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final Context context, final String conversationId) {
176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = getConversationActivityIntent(context, conversationId, null,
177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                false /* withCustomTransition */);
178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startActivity(intent);
180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchConversationActivityWithParentStack(final Context context,
184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final String conversationId, final String smsBody) {
185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final MessageData messageData = TextUtils.isEmpty(smsBody)
186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                ? null
187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                : MessageData.createDraftSmsMessage(conversationId, null, smsBody);
188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        TaskStackBuilder.create(context)
189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .addNextIntentWithParentStack(
190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        getConversationActivityIntent(context, conversationId, messageData,
191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                false /* withCustomTransition */))
192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .startActivities();
193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchCreateNewConversationActivity(final Context context,
197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final MessageData draft) {
198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = getConversationActivityIntent(context, null, draft,
199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                false /* withCustomTransition */);
200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startActivity(intent);
201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchDebugMmsConfigActivity(final Context context) {
205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startActivity(new Intent(context, DebugMmsConfigActivity.class));
206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchAddContactActivity(final Context context, final String destination) {
210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final String destinationType = MmsSmsUtils.isEmailAddress(destination) ?
212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                Intents.Insert.EMAIL : Intents.Insert.PHONE;
213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setType(Contacts.CONTENT_ITEM_TYPE);
214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(destinationType, destination);
215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        startExternalActivity(context, intent);
216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchSettingsActivity(final Context context) {
220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(context, SettingsActivity.class);
221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startActivity(intent);
222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchArchivedConversationsActivity(final Context context) {
226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(context, ArchivedConversationListActivity.class);
227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startActivity(intent);
228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchBlockedParticipantsActivity(final Context context) {
232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(context, BlockedParticipantsActivity.class);
233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startActivity(intent);
234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchDocumentImagePicker(final Fragment fragment) {
238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(Intent.EXTRA_MIME_TYPES, MessagePartData.ACCEPTABLE_IMAGE_TYPES);
240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.addCategory(Intent.CATEGORY_OPENABLE);
241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setType(ContentType.IMAGE_UNSPECIFIED);
242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        fragment.startActivityForResult(intent, REQUEST_PICK_IMAGE_FROM_DOCUMENT_PICKER);
244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchPeopleAndOptionsActivity(final Activity activity,
248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String conversationId) {
249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(activity, PeopleAndOptionsActivity.class);
250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(UI_INTENT_EXTRA_CONVERSATION_ID, conversationId);
251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        activity.startActivityForResult(intent, 0);
252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchPhoneCallActivity(final Context context, final String phoneNumber,
256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                        final Point clickPosition) {
257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(Intent.ACTION_CALL,
258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                Uri.parse(UriUtil.SCHEME_TEL + phoneNumber));
259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Bundle extras = new Bundle();
260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        extras.putParcelable(CALL_TARGET_CLICK_KEY, clickPosition);
261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(CALL_TARGET_CLICK_EXTRA_KEY, extras);
262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        startExternalActivity(context, intent);
263d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
264d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
265d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
266d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchClassZeroActivity(final Context context, final ContentValues messageValues) {
267d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent classZeroIntent = new Intent(context, ClassZeroActivity.class)
268d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .putExtra(UI_INTENT_EXTRA_MESSAGE_VALUES, messageValues)
269d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
270d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startActivity(classZeroIntent);
271d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
272d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
273d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
274d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchForwardMessageActivity(final Context context, final MessageData message) {
275d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent forwardMessageIntent = new Intent(context, ForwardMessageActivity.class)
276d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .putExtra(UI_INTENT_EXTRA_DRAFT_DATA, message);
277d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startActivity(forwardMessageIntent);
278d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
279d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
280d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
281d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchVCardDetailActivity(final Context context, final Uri vcardUri) {
282d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent vcardDetailIntent = new Intent(context, VCardDetailActivity.class)
283d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .putExtra(UI_INTENT_EXTRA_VCARD_URI, vcardUri);
284d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startActivity(vcardDetailIntent);
285d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
286d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
287d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
288d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchSaveVCardToContactsActivity(final Context context, final Uri vcardUri) {
289d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        Assert.isTrue(MediaScratchFileProvider.isMediaScratchSpaceUri(vcardUri));
290d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent();
291d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setAction(Intent.ACTION_VIEW);
292d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setDataAndType(vcardUri, ContentType.TEXT_VCARD.toLowerCase());
293d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
294d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        startExternalActivity(context, intent);
295d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
296d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
297d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
298d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchAttachmentChooserActivity(final Activity activity,
299d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String conversationId, final int requestCode) {
300d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(activity, AttachmentChooserActivity.class);
301d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(UI_INTENT_EXTRA_CONVERSATION_ID, conversationId);
302d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        activity.startActivityForResult(intent, requestCode);
303d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
304d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
305d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
306d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchFullScreenVideoViewer(final Context context, final Uri videoUri) {
307d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(Intent.ACTION_VIEW);
308d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
309d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
310d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // So we don't see "surrounding" images in Gallery
311d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra("SingleItemOnly", true);
312d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setDataAndType(videoUri, ContentType.VIDEO_UNSPECIFIED);
313d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        startExternalActivity(context, intent);
314d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
315d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
316d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
317d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchFullScreenPhotoViewer(final Activity activity, final Uri initialPhoto,
318d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final Rect initialPhotoBounds, final Uri photosUri) {
319d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final PhotoViewIntentBuilder builder =
320d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                com.android.ex.photo.Intents.newPhotoViewIntentBuilder(
321d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        activity, BuglePhotoViewActivity.class);
322d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        builder.setPhotosUri(photosUri.toString());
323d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        builder.setInitialPhotoUri(initialPhoto.toString());
324d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        builder.setProjection(ConversationImagePartsView.PhotoViewQuery.PROJECTION);
325d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
326d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // Set the location of the imageView so that the photoviewer can animate from that location
327d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // to full screen.
328d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        builder.setScaleAnimation(initialPhotoBounds.left, initialPhotoBounds.top,
329d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                initialPhotoBounds.width(), initialPhotoBounds.height());
330d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
331d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        builder.setDisplayThumbsFullScreen(false);
332d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        builder.setMaxInitialScale(8);
333d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        activity.startActivity(builder.build());
334d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        activity.overridePendingTransition(0, 0);
335d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
336d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
337d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
338d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchApplicationSettingsActivity(final Context context, final boolean topLevel) {
339d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(context, ApplicationSettingsActivity.class);
340d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(UI_INTENT_EXTRA_TOP_LEVEL_SETTINGS, topLevel);
341d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startActivity(intent);
342d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
343d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
344d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
345d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchPerSubscriptionSettingsActivity(final Context context, final int subId,
346d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String settingTitle) {
347d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = getPerSubscriptionSettingsIntent(context, subId, settingTitle);
348d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startActivity(intent);
349d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
350d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
351d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
352d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public Intent getViewUrlIntent(final String url) {
353d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Uri uri = Uri.parse(url);
354d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return new Intent(Intent.ACTION_VIEW, uri);
355d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
356d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
357d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
358d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void broadcastConversationSelfIdChange(final Context context,
359d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String conversationId, final String conversationSelfId) {
360d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(CONVERSATION_SELF_ID_CHANGE_BROADCAST_ACTION);
361d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(UI_INTENT_EXTRA_CONVERSATION_ID, conversationId);
362d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(UI_INTENT_EXTRA_CONVERSATION_SELF_ID, conversationSelfId);
363d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
364d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
365d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
366d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
367d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public PendingIntent getPendingIntentForConversationListActivity(final Context context) {
368d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = getConversationListActivityIntent(context);
369d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return getPendingIntentWithParentStack(context, intent, 0);
370d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
371d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
372d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
373d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public PendingIntent getPendingIntentForConversationActivity(final Context context,
374d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String conversationId, final MessageData draft) {
375d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = getConversationActivityIntent(context, conversationId, draft,
376d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                false /* withCustomTransition */);
377d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // Ensure that the platform doesn't reuse PendingIntents across conversations
378d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setData(MessagingContentProvider.buildConversationMetadataUri(conversationId));
379d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return getPendingIntentWithParentStack(context, intent, 0);
380d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
381d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
382d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
383d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public Intent getIntentForConversationActivity(final Context context,
384d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String conversationId, final MessageData draft) {
385d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = getConversationActivityIntent(context, conversationId, draft,
386d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                false /* withCustomTransition */);
387d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return intent;
388d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
389d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
390d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
391d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public PendingIntent getPendingIntentForSendingMessageToConversation(final Context context,
392d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String conversationId, final String selfId, final boolean requiresMms,
393d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final int requestCode) {
394d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(context, RemoteInputEntrypointActivity.class);
395d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setAction(Intent.ACTION_SENDTO);
396d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // Ensure that the platform doesn't reuse PendingIntents across conversations
397d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setData(MessagingContentProvider.buildConversationMetadataUri(conversationId));
398d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(UIIntents.UI_INTENT_EXTRA_CONVERSATION_ID, conversationId);
399d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(UIIntents.UI_INTENT_EXTRA_SELF_ID, selfId);
400d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(UIIntents.UI_INTENT_EXTRA_REQUIRES_MMS, requiresMms);
401d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
402d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return getPendingIntentWithParentStack(context, intent, requestCode);
403d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
404d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
405d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
406d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public PendingIntent getPendingIntentForClearingNotifications(final Context context,
407d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final int updateTargets, final ConversationIdSet conversationIdSet,
408d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final int requestCode) {
409d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(context, NotificationReceiver.class);
410d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setAction(ACTION_RESET_NOTIFICATIONS);
411d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(UI_INTENT_EXTRA_NOTIFICATIONS_UPDATE, updateTargets);
412d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (conversationIdSet != null) {
413d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            intent.putExtra(UI_INTENT_EXTRA_CONVERSATION_ID_SET,
414d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    conversationIdSet.getDelimitedString());
415d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
416d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return PendingIntent.getBroadcast(context,
417d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                requestCode, intent,
418d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                PendingIntent.FLAG_UPDATE_CURRENT);
419d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
420d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
421d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
422d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * Gets a PendingIntent associated with an Intent to start an Activity. All notifications
423d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * that starts an Activity must use this method to get a PendingIntent, which achieves two
424d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * goals:
425d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * 1. The target activities will be created, with any existing ones destroyed. This ensures
426d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     *    we don't end up with multiple instances of ConversationListActivity, for example.
427d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * 2. The target activity, when launched, will have its backstack correctly constructed so
428d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     *    back navigation will work correctly.
429d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
430d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static PendingIntent getPendingIntentWithParentStack(final Context context,
431d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final Intent intent, final int requestCode) {
432d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
433d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // Adds the back stack for the Intent (plus the Intent itself)
434d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        stackBuilder.addNextIntentWithParentStack(intent);
435d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final PendingIntent resultPendingIntent =
436d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            stackBuilder.getPendingIntent(requestCode, PendingIntent.FLAG_UPDATE_CURRENT);
437d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return resultPendingIntent;
438d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
439d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
440d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
441d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public Intent getRingtonePickerIntent(final String title, final Uri existingUri,
442d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final Uri defaultUri, final int toneType) {
443d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return new Intent(RingtoneManager.ACTION_RINGTONE_PICKER)
444d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, toneType)
445d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, title)
446d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, existingUri)
447d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, defaultUri);
448d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
449d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
450d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
451d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public PendingIntent getPendingIntentForLowStorageNotifications(final Context context) {
452d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context);
453d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent conversationListIntent = getConversationListActivityIntent(context);
454d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        taskStackBuilder.addNextIntent(conversationListIntent);
455d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        taskStackBuilder.addNextIntentWithParentStack(
456d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                getSmsStorageLowWarningActivityIntent(context));
457d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
458d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return taskStackBuilder.getPendingIntent(
459d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                0, PendingIntent.FLAG_UPDATE_CURRENT);
460d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
461d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
462d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
463d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public PendingIntent getPendingIntentForSecondaryUserNewMessageNotification(
464d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final Context context) {
465d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return getPendingIntentForConversationListActivity(context);
466d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
467d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
468d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
469d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public Intent getWirelessAlertsIntent() {
470d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(Intent.ACTION_MAIN);
471d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setComponent(new ComponentName(CMAS_COMPONENT, CELL_BROADCAST_LIST_ACTIVITY));
472d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
473d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return intent;
474d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
475d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
476d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
477d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public Intent getApnEditorIntent(final Context context, final String rowId, final int subId) {
478d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(context, ApnEditorActivity.class);
479d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(UI_INTENT_EXTRA_APN_ROW_ID, rowId);
480d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(UI_INTENT_EXTRA_SUB_ID, subId);
481d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return intent;
482d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
483d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
484d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
485d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public Intent getApnSettingsIntent(final Context context, final int subId) {
486d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(context, ApnSettingsActivity.class)
487d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                .putExtra(UI_INTENT_EXTRA_SUB_ID, subId);
488d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return intent;
489d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
490d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
491d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
492d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public Intent getAdvancedSettingsIntent(final Context context) {
493d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return getPerSubscriptionSettingsIntent(context, ParticipantData.DEFAULT_SELF_SUB_ID, null);
494d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
495d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
496d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
497d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public Intent getChangeDefaultSmsAppIntent(final Activity activity) {
498d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
499d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, activity.getPackageName());
500d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return intent;
501d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
502d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
503d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
504d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void launchBrowserForUrl(final Context context, final String url) {
505d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = getViewUrlIntent(url);
506d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        startExternalActivity(context, intent);
507d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
508d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
509d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
510d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * Provides a safe way to handle external activities which may not exist.
511d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
512d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private void startExternalActivity(final Context context, final Intent intent) {
513d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        try {
514d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            context.startActivity(intent);
515d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        } catch (final ActivityNotFoundException ex) {
516d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            LogUtil.w(LogUtil.BUGLE_TAG, "Couldn't find activity:", ex);
517d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            UiUtils.showToastAtBottom(R.string.activity_not_found_message);
518d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
519d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
520d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
521d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private Intent getPerSubscriptionSettingsIntent(final Context context, final int subId,
522d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Nullable final String settingTitle) {
523d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return new Intent(context, PerSubscriptionSettingsActivity.class)
524d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            .putExtra(UI_INTENT_EXTRA_SUB_ID, subId)
525d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            .putExtra(UI_INTENT_EXTRA_PER_SUBSCRIPTION_SETTING_TITLE, settingTitle);
526d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
527d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
528d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
529d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public Intent getLaunchConversationActivityIntent(final Context context) {
530d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(context, LaunchConversationActivity.class);
531d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
532d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return intent;
533d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
534d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
535d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
536d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void kickMediaScanner(final Context context, final String volume) {
537d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = new Intent(MEDIA_SCANNER_SCAN_ACTION)
538d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            .putExtra(MediaStore.MEDIA_SCANNER_VOLUME, volume)
539d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            .setClassName(MEDIA_SCANNER_PACKAGE, MEDIA_SCANNER_CLASS);
540d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        context.startService(intent);
541d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
542d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
543d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
544d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public PendingIntent getWidgetPendingIntentForConversationActivity(final Context context,
545d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String conversationId, final int requestCode) {
546d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = getConversationActivityIntent(context, null, null,
547d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                false /* withCustomTransition */);
548d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (conversationId != null) {
549d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            intent.putExtra(UI_INTENT_EXTRA_CONVERSATION_ID, conversationId);
550d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
551d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // Set the action to something unique to this conversation so if someone calls this
552d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // function again on a different conversation, they'll get a new PendingIntent instead
553d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // of the old one.
554d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            intent.setAction(ACTION_WIDGET_CONVERSATION + conversationId);
555d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
556d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
557d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return getPendingIntentWithParentStack(context, intent, requestCode);
558d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
559d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
560d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
561d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public PendingIntent getWidgetPendingIntentForConversationListActivity(
562d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final Context context) {
563d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent intent = getConversationListActivityIntent(context);
564d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return getPendingIntentWithParentStack(context, intent, 0);
565d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
566d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
567d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
568d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public PendingIntent getWidgetPendingIntentForConfigurationActivity(final Context context,
569d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final int appWidgetId) {
570d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Intent configureIntent = new Intent(context, WidgetPickConversationActivity.class);
571d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        configureIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
572d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        configureIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
573d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        configureIntent.setData(Uri.parse(configureIntent.toUri(Intent.URI_INTENT_SCHEME)));
574d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        configureIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
575d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return getPendingIntentWithParentStack(context, configureIntent, 0);
576d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
577d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd}
578