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.datamodel.action;
17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Context;
19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.res.Resources;
20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.widget.Toast;
21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.Factory;
23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.R;
24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.DataModel;
25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.MessageData;
26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.ParticipantData;
27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.sms.MmsUtils;
28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.AccessibilityUtil;
29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.PhoneUtils;
30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.ThreadUtil;
31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport javax.annotation.Nullable;
33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/**
35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Shows one-time, transient notifications in response to action failures (i.e. permanent failures
36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * when sending a message) by showing toasts.
37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class BugleActionToasts {
39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * Called when SendMessageAction or DownloadMmsAction finishes
41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @param conversationId the conversation of the sent or downloaded message
42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @param success did the action succeed
43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @param status the message sending status
44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @param isSms whether the message is sent using SMS
45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @param subId the subId of the SIM related to this send
46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @param isSend whether it is a send (false for download)
47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    static void onSendMessageOrManualDownloadActionCompleted(
49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String conversationId,
50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final boolean success,
51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final int status,
52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final boolean isSms,
53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final int subId,
54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final boolean isSend) {
55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // We only show notifications for two cases, i.e. when mobile data is off or when we are
56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // in airplane mode, both of which fail fast with permanent failures.
57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (!success && status == MmsUtils.MMS_REQUEST_MANUAL_RETRY) {
58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final PhoneUtils phoneUtils = PhoneUtils.get(subId);
59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (phoneUtils.isAirplaneModeOn()) {
60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (isSend) {
61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    showToast(R.string.send_message_failure_airplane_mode);
62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                } else {
63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    showToast(R.string.download_message_failure_airplane_mode);
64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return;
66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            } else if (!isSms && !phoneUtils.isMobileDataEnabled()) {
67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (isSend) {
68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    showToast(R.string.send_message_failure_no_data);
69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                } else {
70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    showToast(R.string.download_message_failure_no_data);
71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return;
73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (AccessibilityUtil.isTouchExplorationEnabled(Factory.get().getApplicationContext())) {
77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final boolean isFocusedConversation = DataModel.get().isFocusedConversation(conversationId);
78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (isFocusedConversation && success) {
79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // Using View.announceForAccessibility may be preferable, but we do not have a
80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // View, and so we use a toast instead.
81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                showToast(isSend ? R.string.send_message_success
82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        : R.string.download_message_success);
83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return;
84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // {@link MessageNotificationState#checkFailedMessages} does not post a notification for
87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // failures in observable conversations. For accessibility, we provide an indication
88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // here.
89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final boolean isObservableConversation = DataModel.get().isNewMessageObservable(
90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    conversationId);
91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (isObservableConversation && !success) {
92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                showToast(isSend ? R.string.send_message_failure
93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        : R.string.download_message_failure);
94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static void onMessageReceived(final String conversationId,
99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Nullable final ParticipantData sender, @Nullable final MessageData message) {
100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Context context = Factory.get().getApplicationContext();
101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (AccessibilityUtil.isTouchExplorationEnabled(context)) {
102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final boolean isFocusedConversation = DataModel.get().isFocusedConversation(
103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    conversationId);
104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (isFocusedConversation) {
105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final Resources res = context.getResources();
106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final String senderDisplayName = (sender == null)
107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        ? res.getString(R.string.unknown_sender) : sender.getDisplayName(false);
108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final String announcement = res.getString(
109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        R.string.incoming_message_announcement, senderDisplayName,
110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        (message == null) ? "" : message.getMessageText());
111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                showToast(announcement);
112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static void onConversationDeleted() {
117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        showToast(R.string.conversation_deleted);
118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static void showToast(final int messageResId) {
121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        ThreadUtil.getMainThreadHandler().post(new Runnable() {
122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public void run() {
124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                Toast.makeText(getApplicationContext(),
125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        getApplicationContext().getString(messageResId), Toast.LENGTH_LONG).show();
126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        });
128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static void showToast(final String message) {
131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        ThreadUtil.getMainThreadHandler().post(new Runnable() {
132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public void run() {
134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        });
137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static Context getApplicationContext() {
140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return Factory.get().getApplicationContext();
141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static class UpdateDestinationBlockedActionToast
144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            implements UpdateDestinationBlockedAction.UpdateDestinationBlockedActionListener {
145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        private final Context mContext;
146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        UpdateDestinationBlockedActionToast(final Context context) {
148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mContext = context;
149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        @Override
152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        public void onUpdateDestinationBlockedAction(
153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final UpdateDestinationBlockedAction action,
154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final boolean success,
155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final boolean block,
156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final String destination) {
157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (success) {
158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                Toast.makeText(mContext,
159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        block
160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                ? R.string.update_destination_blocked
161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                : R.string.update_destination_unblocked,
162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        Toast.LENGTH_LONG
163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                ).show();
164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static UpdateDestinationBlockedAction.UpdateDestinationBlockedActionListener
169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            makeUpdateDestinationBlockedActionListener(final Context context) {
170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return new UpdateDestinationBlockedActionToast(context);
171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd}
173