diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2018-01-23 03:51:25 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-01-23 03:51:25 +0000 |
commit | 5feae4d9f7b3685be38b48c1806ceb03c6b2273c (patch) | |
tree | 6ef19b009a788ed8f6d4b88b0a08b03adf9d1e30 /java/com/android/dialer/voicemail/listui/error/OmtpVoicemailMessageCreator.java | |
parent | c979f257060fbcb95cbd4871461dd5eb1ae04f1b (diff) | |
parent | 4deaebc5a988eb83440693721f1ab28b180d8779 (diff) |
Merge "Move legacy voicemail/error to nui voicemail/listui/error"
Diffstat (limited to 'java/com/android/dialer/voicemail/listui/error/OmtpVoicemailMessageCreator.java')
-rw-r--r-- | java/com/android/dialer/voicemail/listui/error/OmtpVoicemailMessageCreator.java | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/java/com/android/dialer/voicemail/listui/error/OmtpVoicemailMessageCreator.java b/java/com/android/dialer/voicemail/listui/error/OmtpVoicemailMessageCreator.java new file mode 100644 index 000000000..29b698942 --- /dev/null +++ b/java/com/android/dialer/voicemail/listui/error/OmtpVoicemailMessageCreator.java @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.dialer.voicemail.listui.error; + +import android.content.Context; +import android.preference.PreferenceManager; +import android.provider.VoicemailContract.Status; +import android.support.annotation.Nullable; +import android.telecom.PhoneAccountHandle; +import com.android.dialer.common.LogUtil; +import com.android.dialer.common.PerAccountSharedPreferences; +import com.android.dialer.logging.DialerImpression; +import com.android.dialer.logging.Logger; +import com.android.dialer.voicemail.listui.error.VoicemailErrorMessage.Action; +import com.android.voicemail.VoicemailClient; +import com.android.voicemail.VoicemailComponent; +import java.util.ArrayList; +import java.util.List; + +/** + * Create error message from {@link VoicemailStatus} for OMTP visual voicemail. This is also the + * default behavior if other message creator does not handle the status. + */ +public class OmtpVoicemailMessageCreator { + + private static final float QUOTA_NEAR_FULL_THRESHOLD = 0.9f; + private static final float QUOTA_FULL_THRESHOLD = 0.99f; + protected static final String VOICEMAIL_PROMO_DISMISSED_KEY = + "voicemail_archive_promo_was_dismissed"; + protected static final String VOICEMAIL_PROMO_ALMOST_FULL_DISMISSED_KEY = + "voicemail_archive_almost_full_promo_was_dismissed"; + + @Nullable + public static VoicemailErrorMessage create( + Context context, VoicemailStatus status, final VoicemailStatusReader statusReader) { + VoicemailErrorMessage tosMessage = + new VoicemailTosMessageCreator(context, status, statusReader).maybeCreateTosMessage(); + if (tosMessage != null) { + return tosMessage; + } + + if (Status.CONFIGURATION_STATE_OK == status.configurationState + && Status.DATA_CHANNEL_STATE_OK == status.dataChannelState + && Status.NOTIFICATION_CHANNEL_STATE_OK == status.notificationChannelState) { + return checkQuota(context, status, statusReader); + } + // Initial state when the source is activating. Other error might be written into data and + // notification channel during activation. + if (Status.CONFIGURATION_STATE_CONFIGURING == status.configurationState + && Status.DATA_CHANNEL_STATE_OK == status.dataChannelState + && Status.NOTIFICATION_CHANNEL_STATE_OK == status.notificationChannelState) { + return new VoicemailErrorMessage( + context.getString(R.string.voicemail_error_activating_title), + context.getString(R.string.voicemail_error_activating_message), + VoicemailErrorMessage.createCallVoicemailAction(context, status.getPhoneAccountHandle())); + } + + if (Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION == status.notificationChannelState) { + return createNoSignalMessage(context, status); + } + + if (Status.CONFIGURATION_STATE_FAILED == status.configurationState) { + return new VoicemailErrorMessage( + context.getString(R.string.voicemail_error_activation_failed_title), + context.getString(R.string.voicemail_error_activation_failed_message), + VoicemailErrorMessage.createCallVoicemailAction(context, status.getPhoneAccountHandle()), + VoicemailErrorMessage.createRetryAction(context, status)); + } + + if (Status.DATA_CHANNEL_STATE_NO_CONNECTION == status.dataChannelState) { + return new VoicemailErrorMessage( + context.getString(R.string.voicemail_error_no_data_title), + context.getString(R.string.voicemail_error_no_data_message), + VoicemailErrorMessage.createCallVoicemailAction(context, status.getPhoneAccountHandle()), + VoicemailErrorMessage.createRetryAction(context, status)); + } + + if (Status.DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED == status.dataChannelState) { + return new VoicemailErrorMessage( + context.getString(R.string.voicemail_error_no_data_title), + context.getString(R.string.voicemail_error_no_data_cellular_required_message), + VoicemailErrorMessage.createCallVoicemailAction(context, status.getPhoneAccountHandle()), + VoicemailErrorMessage.createRetryAction(context, status)); + } + + if (Status.DATA_CHANNEL_STATE_BAD_CONFIGURATION == status.dataChannelState) { + return new VoicemailErrorMessage( + context.getString(R.string.voicemail_error_bad_config_title), + context.getString(R.string.voicemail_error_bad_config_message), + VoicemailErrorMessage.createCallVoicemailAction(context, status.getPhoneAccountHandle()), + VoicemailErrorMessage.createRetryAction(context, status)); + } + + if (Status.DATA_CHANNEL_STATE_COMMUNICATION_ERROR == status.dataChannelState) { + return new VoicemailErrorMessage( + context.getString(R.string.voicemail_error_communication_title), + context.getString(R.string.voicemail_error_communication_message), + VoicemailErrorMessage.createCallVoicemailAction(context, status.getPhoneAccountHandle()), + VoicemailErrorMessage.createRetryAction(context, status)); + } + + if (Status.DATA_CHANNEL_STATE_SERVER_ERROR == status.dataChannelState) { + return new VoicemailErrorMessage( + context.getString(R.string.voicemail_error_server_title), + context.getString(R.string.voicemail_error_server_message), + VoicemailErrorMessage.createCallVoicemailAction(context, status.getPhoneAccountHandle()), + VoicemailErrorMessage.createRetryAction(context, status)); + } + + if (Status.DATA_CHANNEL_STATE_SERVER_CONNECTION_ERROR == status.dataChannelState) { + return new VoicemailErrorMessage( + context.getString(R.string.voicemail_error_server_connection_title), + context.getString(R.string.voicemail_error_server_connection_message), + VoicemailErrorMessage.createCallVoicemailAction(context, status.getPhoneAccountHandle()), + VoicemailErrorMessage.createRetryAction(context, status)); + } + + // This should be an assertion error, but there's a bug in NYC-DR (a bug) that will + // sometimes give status mixed from multiple SIMs. There's no meaningful message to be displayed + // from it, so just suppress the message. + LogUtil.e("OmtpVoicemailMessageCreator.create", "Unhandled status: " + status); + return null; + } + + public static boolean isSyncBlockingError(VoicemailStatus status) { + if (status.notificationChannelState != Status.NOTIFICATION_CHANNEL_STATE_OK) { + return true; + } + + if (status.dataChannelState != Status.DATA_CHANNEL_STATE_OK) { + return true; + } + + switch (status.configurationState) { + case Status.CONFIGURATION_STATE_OK: + // allow activation to be queued again in case it is interrupted + case Status.CONFIGURATION_STATE_CONFIGURING: + return false; + default: + return true; + } + } + + @Nullable + private static VoicemailErrorMessage checkQuota( + Context context, VoicemailStatus status, VoicemailStatusReader statusReader) { + if (status.quotaOccupied != Status.QUOTA_UNAVAILABLE + && status.quotaTotal != Status.QUOTA_UNAVAILABLE) { + return createInboxErrorMessage(context, status, statusReader); + } + Logger.get(context).logImpression(DialerImpression.Type.VVM_QUOTA_CHECK_UNAVAILABLE); + return null; + } + + @Nullable + private static VoicemailErrorMessage createInboxErrorMessage( + Context context, VoicemailStatus status, VoicemailStatusReader statusReader) { + + float voicemailOccupiedFraction = (float) status.quotaOccupied / (float) status.quotaTotal; + + if (voicemailOccupiedFraction < QUOTA_NEAR_FULL_THRESHOLD) { + return null; + } + + boolean isFull = voicemailOccupiedFraction >= QUOTA_FULL_THRESHOLD; + + PhoneAccountHandle phoneAccountHandle = status.getPhoneAccountHandle(); + + PerAccountSharedPreferences sharedPreferenceForAccount = + new PerAccountSharedPreferences( + context, phoneAccountHandle, PreferenceManager.getDefaultSharedPreferences(context)); + + VoicemailClient voicemailClient = VoicemailComponent.get(context).getVoicemailClient(); + + boolean shouldShowPromoForArchive = + !isPromoForArchiveDismissed(sharedPreferenceForAccount, isFull) + && !voicemailClient.isVoicemailArchiveEnabled(context, phoneAccountHandle) + && voicemailClient.isVoicemailArchiveAvailable(context); + + if (!shouldShowPromoForArchive) { + if (isFull) { + Logger.get(context) + .logImpression(DialerImpression.Type.VVM_USER_SHOWN_VM_FULL_ERROR_MESSAGE); + return new VoicemailErrorMessage( + context.getString(R.string.voicemail_error_inbox_full_title), + context.getString(R.string.voicemail_error_inbox_full_message)); + } else { + Logger.get(context) + .logImpression(DialerImpression.Type.VVM_USER_SHOWN_VM_ALMOST_FULL_ERROR_MESSAGE); + return new VoicemailErrorMessage( + context.getString(R.string.voicemail_error_inbox_near_full_title), + context.getString(R.string.voicemail_error_inbox_near_full_message)); + } + } + + String title; + CharSequence message; + DialerImpression.Type enabledImpression; + DialerImpression.Type dismissedImpression; + String dismissedKey; + + if (isFull) { + Logger.get(context).logImpression(DialerImpression.Type.VVM_USER_SHOWN_VM_FULL_PROMO); + title = context.getString(R.string.voicemail_error_inbox_full_turn_archive_on_title); + message = context.getText(R.string.voicemail_error_inbox_full_turn_archive_on_message); + enabledImpression = DialerImpression.Type.VVM_USER_ENABLED_ARCHIVE_FROM_VM_FULL_PROMO; + dismissedImpression = DialerImpression.Type.VVM_USER_DISMISSED_VM_FULL_PROMO; + dismissedKey = VOICEMAIL_PROMO_DISMISSED_KEY; + } else { + Logger.get(context).logImpression(DialerImpression.Type.VVM_USER_SHOWN_VM_ALMOST_FULL_PROMO); + title = context.getString(R.string.voicemail_error_inbox_almost_full_turn_archive_on_title); + message = context.getText(R.string.voicemail_error_inbox_almost_full_turn_archive_on_message); + enabledImpression = DialerImpression.Type.VVM_USER_ENABLED_ARCHIVE_FROM_VM_ALMOST_FULL_PROMO; + dismissedImpression = DialerImpression.Type.VVM_USER_DISMISSED_VM_ALMOST_FULL_PROMO; + dismissedKey = VOICEMAIL_PROMO_ALMOST_FULL_DISMISSED_KEY; + } + + return createVMQuotaPromo( + context, + phoneAccountHandle, + status, + statusReader, + voicemailClient, + sharedPreferenceForAccount, + title, + message, + enabledImpression, + dismissedImpression, + dismissedKey); + } + + private static boolean isPromoForArchiveDismissed( + PerAccountSharedPreferences sharedPreferenceForAccount, boolean isFull) { + if (isFull) { + return sharedPreferenceForAccount.getBoolean(VOICEMAIL_PROMO_DISMISSED_KEY, false); + } else { + return sharedPreferenceForAccount.getBoolean( + VOICEMAIL_PROMO_ALMOST_FULL_DISMISSED_KEY, false); + } + } + + private static VoicemailErrorMessage createVMQuotaPromo( + Context context, + PhoneAccountHandle phoneAccountHandle, + VoicemailStatus status, + VoicemailStatusReader statusReader, + VoicemailClient voicemailClient, + PerAccountSharedPreferences sharedPreferenceForAccount, + String title, + CharSequence message, + DialerImpression.Type impressionToLogOnEnable, + DialerImpression.Type impressionToLogOnDismiss, + String preferenceKeyToUpdate) { + return new VoicemailErrorMessage( + title, + message, + VoicemailErrorMessage.createTurnArchiveOnAction( + context, + impressionToLogOnEnable, + status, + statusReader, + voicemailClient, + phoneAccountHandle), + VoicemailErrorMessage.createDismissTurnArchiveOnAction( + context, + impressionToLogOnDismiss, + statusReader, + sharedPreferenceForAccount, + preferenceKeyToUpdate)); + } + + @Nullable + private static VoicemailErrorMessage createNoSignalMessage( + Context context, VoicemailStatus status) { + CharSequence title; + CharSequence description; + List<Action> actions = new ArrayList<>(); + if (Status.CONFIGURATION_STATE_OK == status.configurationState) { + if (Status.DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED == status.dataChannelState) { + title = context.getString(R.string.voicemail_error_no_signal_title); + description = + context.getString(R.string.voicemail_error_no_signal_cellular_required_message); + } else { + title = context.getString(R.string.voicemail_error_no_signal_title); + if (status.isAirplaneMode) { + description = context.getString(R.string.voicemail_error_no_signal_airplane_mode_message); + } else { + description = context.getString(R.string.voicemail_error_no_signal_message); + } + actions.add(VoicemailErrorMessage.createSyncAction(context, status)); + } + } else { + title = context.getString(R.string.voicemail_error_not_activate_no_signal_title); + if (status.isAirplaneMode) { + description = + context.getString( + R.string.voicemail_error_not_activate_no_signal_airplane_mode_message); + } else { + description = context.getString(R.string.voicemail_error_not_activate_no_signal_message); + actions.add(VoicemailErrorMessage.createRetryAction(context, status)); + } + } + if (status.isAirplaneMode) { + actions.add(VoicemailErrorMessage.createChangeAirplaneModeAction(context)); + } + return new VoicemailErrorMessage(title, description, actions); + } +} |