diff options
Diffstat (limited to 'java/com/android/dialer/voicemailstatus')
3 files changed, 33 insertions, 336 deletions
diff --git a/java/com/android/dialer/voicemailstatus/VisualVoicemailEnabledChecker.java b/java/com/android/dialer/voicemailstatus/VisualVoicemailEnabledChecker.java index 142bb63ed..a1fc29edf 100644 --- a/java/com/android/dialer/voicemailstatus/VisualVoicemailEnabledChecker.java +++ b/java/com/android/dialer/voicemailstatus/VisualVoicemailEnabledChecker.java @@ -53,7 +53,7 @@ public class VisualVoicemailEnabledChecker implements CallLogQueryHandler.Listen mContext = context; mCallback = callback; mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext); - mVoicemailStatusHelper = new VoicemailStatusHelperImpl(); + mVoicemailStatusHelper = new VoicemailStatusHelper(); mHasActiveVoicemailProvider = mPrefs.getBoolean(PREF_KEY_HAS_ACTIVE_VOICEMAIL_PROVIDER, false); } @@ -80,7 +80,10 @@ public class VisualVoicemailEnabledChecker implements CallLogQueryHandler.Listen mVoicemailStatusHelper.getNumberActivityVoicemailSources(statusCursor) > 0; if (hasActiveVoicemailProvider != mHasActiveVoicemailProvider) { mHasActiveVoicemailProvider = hasActiveVoicemailProvider; - mPrefs.edit().putBoolean(PREF_KEY_HAS_ACTIVE_VOICEMAIL_PROVIDER, mHasActiveVoicemailProvider); + mPrefs + .edit() + .putBoolean(PREF_KEY_HAS_ACTIVE_VOICEMAIL_PROVIDER, mHasActiveVoicemailProvider) + .apply(); if (mCallback != null) { mCallback.onVisualVoicemailEnabledStatusChanged(mHasActiveVoicemailProvider); } diff --git a/java/com/android/dialer/voicemailstatus/VoicemailStatusHelper.java b/java/com/android/dialer/voicemailstatus/VoicemailStatusHelper.java index 16bfe704d..9df45c211 100644 --- a/java/com/android/dialer/voicemailstatus/VoicemailStatusHelper.java +++ b/java/com/android/dialer/voicemailstatus/VoicemailStatusHelper.java @@ -17,10 +17,8 @@ package com.android.dialer.voicemailstatus; import android.database.Cursor; -import android.net.Uri; import android.provider.VoicemailContract.Status; -import android.support.annotation.VisibleForTesting; -import java.util.List; +import com.android.dialer.database.VoicemailStatusQuery; /** * Interface used by the call log UI to determine what user message, if any, related to voicemail @@ -31,66 +29,40 @@ import java.util.List; * shown. The user of this interface must observe/listen to provider changes and invoke this class * to check if any message needs to be shown. */ -public interface VoicemailStatusHelper { - - /** - * Returns a list of messages, in the order or priority that should be shown to the user. An empty - * list is returned if no message needs to be shown. - * - * @param cursor The cursor pointing to the query on {@link Status#CONTENT_URI}. The projection to - * be used is defined by the implementation class of this interface. - */ - @VisibleForTesting - List<StatusMessage> getStatusMessages(Cursor cursor); +public class VoicemailStatusHelper { /** * Returns the number of active voicemail sources installed. * * <p>The number of sources is counted by querying the voicemail status table. + * + * @param cursor The caller is responsible for the life cycle of the cursor and resetting the + * position */ - int getNumberActivityVoicemailSources(Cursor cursor); - - @VisibleForTesting - class StatusMessage { - - /** Package of the source on behalf of which this message has to be shown. */ - public final String sourcePackage; - /** - * The string resource id of the status message that should be shown in the call log page. Set - * to -1, if this message is not to be shown in call log. - */ - public final int callLogMessageId; - /** - * The string resource id of the status message that should be shown in the call details page. - * Set to -1, if this message is not to be shown in call details page. - */ - public final int callDetailsMessageId; - /** The string resource id of the action message that should be shown. */ - public final int actionMessageId; - /** URI for the corrective action, where applicable. Null if no action URI is available. */ - public final Uri actionUri; - - public StatusMessage( - String sourcePackage, - int callLogMessageId, - int callDetailsMessageId, - int actionMessageId, - Uri actionUri) { - this.sourcePackage = sourcePackage; - this.callLogMessageId = callLogMessageId; - this.callDetailsMessageId = callDetailsMessageId; - this.actionMessageId = actionMessageId; - this.actionUri = actionUri; - } - - /** Whether this message should be shown in the call log page. */ - public boolean showInCallLog() { - return callLogMessageId != -1; + public int getNumberActivityVoicemailSources(Cursor cursor) { + int count = 0; + if (!cursor.moveToFirst()) { + return 0; } + do { + if (isVoicemailSourceActive(cursor)) { + ++count; + } + } while (cursor.moveToNext()); + return count; + } - /** Whether this message should be shown in the call details page. */ - public boolean showInCallDetails() { - return callDetailsMessageId != -1; - } + /** + * Returns whether the source status in the cursor corresponds to an active source. A source is + * active if its' configuration state is not NOT_CONFIGURED. For most voicemail sources, only OK + * and NOT_CONFIGURED are used. The OMTP visual voicemail client has the same behavior pre-NMR1. + * NMR1 visual voicemail will only set it to NOT_CONFIGURED when it is deactivated. As soon as + * activation is attempted, it will transition into CONFIGURING then into OK or other error state, + * NOT_CONFIGURED is never set through an error. + */ + private boolean isVoicemailSourceActive(Cursor cursor) { + return cursor.getString(VoicemailStatusQuery.SOURCE_PACKAGE_INDEX) != null + && cursor.getInt(VoicemailStatusQuery.CONFIGURATION_STATE_INDEX) + != Status.CONFIGURATION_STATE_NOT_CONFIGURED; } } diff --git a/java/com/android/dialer/voicemailstatus/VoicemailStatusHelperImpl.java b/java/com/android/dialer/voicemailstatus/VoicemailStatusHelperImpl.java deleted file mode 100644 index 404897fde..000000000 --- a/java/com/android/dialer/voicemailstatus/VoicemailStatusHelperImpl.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2011 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.voicemailstatus; - -import static android.provider.VoicemailContract.Status.CONFIGURATION_STATE_CAN_BE_CONFIGURED; -import static android.provider.VoicemailContract.Status.CONFIGURATION_STATE_OK; -import static android.provider.VoicemailContract.Status.DATA_CHANNEL_STATE_NO_CONNECTION; -import static android.provider.VoicemailContract.Status.DATA_CHANNEL_STATE_OK; -import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING; -import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION; -import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK; - -import android.database.Cursor; -import android.net.Uri; -import android.provider.VoicemailContract.Status; -import com.android.contacts.common.util.UriUtils; -import com.android.dialer.database.VoicemailStatusQuery; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -/** Implementation of {@link VoicemailStatusHelper}. */ -public class VoicemailStatusHelperImpl implements VoicemailStatusHelper { - - @Override - public List<StatusMessage> getStatusMessages(Cursor cursor) { - List<MessageStatusWithPriority> messages = - new ArrayList<VoicemailStatusHelperImpl.MessageStatusWithPriority>(); - cursor.moveToPosition(-1); - while (cursor.moveToNext()) { - MessageStatusWithPriority message = getMessageForStatusEntry(cursor); - if (message != null) { - messages.add(message); - } - } - // Finally reorder the messages by their priority. - return reorderMessages(messages); - } - - @Override - public int getNumberActivityVoicemailSources(Cursor cursor) { - int count = 0; - cursor.moveToPosition(-1); - while (cursor.moveToNext()) { - if (isVoicemailSourceActive(cursor)) { - ++count; - } - } - return count; - } - - /** - * Returns whether the source status in the cursor corresponds to an active source. A source is - * active if its' configuration state is not NOT_CONFIGURED. For most voicemail sources, only OK - * and NOT_CONFIGURED are used. The OMTP visual voicemail client has the same behavior pre-NMR1. - * NMR1 visual voicemail will only set it to NOT_CONFIGURED when it is deactivated. As soon as - * activation is attempted, it will transition into CONFIGURING then into OK or other error state, - * NOT_CONFIGURED is never set through an error. - */ - private boolean isVoicemailSourceActive(Cursor cursor) { - return cursor.getString(VoicemailStatusQuery.SOURCE_PACKAGE_INDEX) != null - && cursor.getInt(VoicemailStatusQuery.CONFIGURATION_STATE_INDEX) - != Status.CONFIGURATION_STATE_NOT_CONFIGURED; - } - - private List<StatusMessage> reorderMessages(List<MessageStatusWithPriority> messageWrappers) { - Collections.sort( - messageWrappers, - new Comparator<MessageStatusWithPriority>() { - @Override - public int compare(MessageStatusWithPriority msg1, MessageStatusWithPriority msg2) { - return msg1.mPriority - msg2.mPriority; - } - }); - List<StatusMessage> reorderMessages = new ArrayList<VoicemailStatusHelper.StatusMessage>(); - // Copy the ordered message objects into the final list. - for (MessageStatusWithPriority messageWrapper : messageWrappers) { - reorderMessages.add(messageWrapper.mMessage); - } - return reorderMessages; - } - - /** Returns the message for the status entry pointed to by the cursor. */ - private MessageStatusWithPriority getMessageForStatusEntry(Cursor cursor) { - final String sourcePackage = cursor.getString(VoicemailStatusQuery.SOURCE_PACKAGE_INDEX); - if (sourcePackage == null) { - return null; - } - final OverallState overallState = - getOverallState( - cursor.getInt(VoicemailStatusQuery.CONFIGURATION_STATE_INDEX), - cursor.getInt(VoicemailStatusQuery.DATA_CHANNEL_STATE_INDEX), - cursor.getInt(VoicemailStatusQuery.NOTIFICATION_CHANNEL_STATE_INDEX)); - final Action action = overallState.getAction(); - - // No source package or no action, means no message shown. - if (action == Action.NONE) { - return null; - } - - Uri actionUri = null; - if (action == Action.CALL_VOICEMAIL) { - actionUri = - UriUtils.parseUriOrNull( - cursor.getString(VoicemailStatusQuery.VOICEMAIL_ACCESS_URI_INDEX)); - // Even if actionUri is null, it is still be useful to show the notification. - } else if (action == Action.CONFIGURE_VOICEMAIL) { - actionUri = - UriUtils.parseUriOrNull(cursor.getString(VoicemailStatusQuery.SETTINGS_URI_INDEX)); - // If there is no settings URI, there is no point in showing the notification. - if (actionUri == null) { - return null; - } - } - return new MessageStatusWithPriority( - new StatusMessage( - sourcePackage, - overallState.getCallLogMessageId(), - overallState.getCallDetailsMessageId(), - action.getMessageId(), - actionUri), - overallState.getPriority()); - } - - private OverallState getOverallState( - int configurationState, int dataChannelState, int notificationChannelState) { - if (configurationState == CONFIGURATION_STATE_OK) { - // Voicemail is configured. Let's see how is the data channel. - if (dataChannelState == DATA_CHANNEL_STATE_OK) { - // Data channel is fine. What about notification channel? - if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_OK) { - return OverallState.OK; - } else if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING) { - return OverallState.NO_DETAILED_NOTIFICATION; - } else if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_NO_CONNECTION) { - return OverallState.NO_NOTIFICATIONS; - } - } else if (dataChannelState == DATA_CHANNEL_STATE_NO_CONNECTION) { - // Data channel is not working. What about notification channel? - if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_OK) { - return OverallState.NO_DATA; - } else if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING) { - return OverallState.MESSAGE_WAITING; - } else if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_NO_CONNECTION) { - return OverallState.NO_CONNECTION; - } - } - } else if (configurationState == CONFIGURATION_STATE_CAN_BE_CONFIGURED) { - // Voicemail not configured. data/notification channel states are irrelevant. - return OverallState.INVITE_FOR_CONFIGURATION; - } else if (configurationState == Status.CONFIGURATION_STATE_NOT_CONFIGURED) { - // Voicemail not configured. data/notification channel states are irrelevant. - return OverallState.NOT_CONFIGURED; - } - // Will reach here only if the source has set an invalid value. - return OverallState.INVALID; - } - - /** Possible user actions. */ - public enum Action { - NONE(-1), - CALL_VOICEMAIL(R.string.voicemail_status_action_call_server), - CONFIGURE_VOICEMAIL(R.string.voicemail_status_action_configure); - - private final int mMessageId; - - Action(int messageId) { - mMessageId = messageId; - } - - public int getMessageId() { - return mMessageId; - } - } - - /** - * Overall state of the source status. Each state is associated with the corresponding display - * string and the corrective action. The states are also assigned a relative priority which is - * used to order the messages from different sources. - */ - private enum OverallState { - // TODO: Add separate string for call details and call log pages for the states that needs - // to be shown in both. - /** Both notification and data channel are not working. */ - NO_CONNECTION( - 0, - Action.CALL_VOICEMAIL, - R.string.voicemail_status_voicemail_not_available, - R.string.voicemail_status_audio_not_available), - /** Notifications working, but data channel is not working. Audio cannot be downloaded. */ - NO_DATA( - 1, - Action.CALL_VOICEMAIL, - R.string.voicemail_status_voicemail_not_available, - R.string.voicemail_status_audio_not_available), - /** Messages are known to be waiting but data channel is not working. */ - MESSAGE_WAITING( - 2, - Action.CALL_VOICEMAIL, - R.string.voicemail_status_messages_waiting, - R.string.voicemail_status_audio_not_available), - /** Notification channel not working, but data channel is. */ - NO_NOTIFICATIONS(3, Action.CALL_VOICEMAIL, R.string.voicemail_status_voicemail_not_available), - /** Invite user to set up voicemail. */ - INVITE_FOR_CONFIGURATION( - 4, Action.CONFIGURE_VOICEMAIL, R.string.voicemail_status_configure_voicemail), - /** - * No detailed notifications, but data channel is working. This is normal mode of operation for - * certain sources. No action needed. - */ - NO_DETAILED_NOTIFICATION(5, Action.NONE, -1), - /** Visual voicemail not yet set up. No local action needed. */ - NOT_CONFIGURED(6, Action.NONE, -1), - /** Everything is OK. */ - OK(7, Action.NONE, -1), - /** If one or more state value set by the source is not valid. */ - INVALID(8, Action.NONE, -1); - - private final int mPriority; - private final Action mAction; - private final int mCallLogMessageId; - private final int mCallDetailsMessageId; - - OverallState(int priority, Action action, int callLogMessageId) { - this(priority, action, callLogMessageId, -1); - } - - OverallState(int priority, Action action, int callLogMessageId, int callDetailsMessageId) { - mPriority = priority; - mAction = action; - mCallLogMessageId = callLogMessageId; - mCallDetailsMessageId = callDetailsMessageId; - } - - public Action getAction() { - return mAction; - } - - public int getPriority() { - return mPriority; - } - - public int getCallLogMessageId() { - return mCallLogMessageId; - } - - public int getCallDetailsMessageId() { - return mCallDetailsMessageId; - } - } - - /** A wrapper on {@link StatusMessage} which additionally stores the priority of the message. */ - private static class MessageStatusWithPriority { - - private final StatusMessage mMessage; - private final int mPriority; - - public MessageStatusWithPriority(StatusMessage message, int priority) { - mMessage = message; - mPriority = priority; - } - } -} |