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