diff options
Diffstat (limited to 'java/com/android/dialer/voicemail/listui/error/VoicemailStatus.java')
-rw-r--r-- | java/com/android/dialer/voicemail/listui/error/VoicemailStatus.java | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/java/com/android/dialer/voicemail/listui/error/VoicemailStatus.java b/java/com/android/dialer/voicemail/listui/error/VoicemailStatus.java new file mode 100644 index 000000000..3447f03df --- /dev/null +++ b/java/com/android/dialer/voicemail/listui/error/VoicemailStatus.java @@ -0,0 +1,310 @@ +/* + * 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.annotation.TargetApi; +import android.content.ComponentName; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.provider.Settings; +import android.provider.Settings.Global; +import android.provider.VoicemailContract.Status; +import android.support.annotation.Nullable; +import android.support.v4.os.BuildCompat; +import android.telecom.PhoneAccountHandle; +import android.telephony.ServiceState; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import com.android.dialer.common.LogUtil; +import com.android.dialer.database.VoicemailStatusQuery; + +/** Structured data from {@link android.provider.VoicemailContract.Status} */ +public class VoicemailStatus { + + public final String sourcePackage; + public final String type; + + public final String phoneAccountComponentName; + public final String phoneAccountId; + + @Nullable public final Uri settingsUri; + @Nullable public final Uri voicemailAccessUri; + + public final int configurationState; + public final int dataChannelState; + public final int notificationChannelState; + + public final int quotaOccupied; + public final int quotaTotal; + + // System status + + public final boolean isAirplaneMode; + + /** Wraps the row currently pointed by <code>statusCursor</code> */ + public VoicemailStatus(Context context, Cursor statusCursor) { + sourcePackage = getString(statusCursor, VoicemailStatusQuery.SOURCE_PACKAGE_INDEX, ""); + + settingsUri = getUri(statusCursor, VoicemailStatusQuery.SETTINGS_URI_INDEX); + voicemailAccessUri = getUri(statusCursor, VoicemailStatusQuery.VOICEMAIL_ACCESS_URI_INDEX); + + if (VERSION.SDK_INT >= VERSION_CODES.N_MR1) { + type = + getString( + statusCursor, VoicemailStatusQuery.SOURCE_TYPE_INDEX, TelephonyManager.VVM_TYPE_OMTP); + phoneAccountComponentName = + getString(statusCursor, VoicemailStatusQuery.PHONE_ACCOUNT_COMPONENT_NAME, ""); + phoneAccountId = getString(statusCursor, VoicemailStatusQuery.PHONE_ACCOUNT_ID, ""); + } else { + type = TelephonyManager.VVM_TYPE_OMTP; + phoneAccountComponentName = ""; + phoneAccountId = ""; + } + + configurationState = + getInt( + statusCursor, + VoicemailStatusQuery.CONFIGURATION_STATE_INDEX, + Status.CONFIGURATION_STATE_NOT_CONFIGURED); + dataChannelState = + getInt( + statusCursor, + VoicemailStatusQuery.DATA_CHANNEL_STATE_INDEX, + Status.DATA_CHANNEL_STATE_NO_CONNECTION); + + /* Before O, the NOTIFICATION_CHANNEL_STATE in the voicemail status table for the system + * visual voicemail client always correspond to the service state (cellular signal availability) + * Tracking the state in the background is redundant because it will not be visible to the + * user. It is much simpler to poll the status on the UI side. The result is injected back to + * the status query result so the handling will be consistent with other voicemail clients. + */ + if (BuildCompat.isAtLeastO() && sourcePackage.equals(context.getPackageName())) { + notificationChannelState = + getNotificationChannelStateFormTelephony(context, getPhoneAccountHandle()); + } else { + notificationChannelState = + getInt( + statusCursor, + VoicemailStatusQuery.NOTIFICATION_CHANNEL_STATE_INDEX, + Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION); + } + isAirplaneMode = + Settings.System.getInt(context.getContentResolver(), Global.AIRPLANE_MODE_ON, 0) != 0; + + if (VERSION.SDK_INT >= VERSION_CODES.N) { + quotaOccupied = + getInt(statusCursor, VoicemailStatusQuery.QUOTA_OCCUPIED_INDEX, Status.QUOTA_UNAVAILABLE); + quotaTotal = + getInt(statusCursor, VoicemailStatusQuery.QUOTA_TOTAL_INDEX, Status.QUOTA_UNAVAILABLE); + } else { + quotaOccupied = Status.QUOTA_UNAVAILABLE; + quotaTotal = Status.QUOTA_UNAVAILABLE; + } + } + + private VoicemailStatus(Builder builder) { + sourcePackage = builder.sourcePackage; + phoneAccountComponentName = builder.phoneAccountComponentName; + phoneAccountId = builder.phoneAccountId; + type = builder.type; + settingsUri = builder.settingsUri; + voicemailAccessUri = builder.voicemailAccessUri; + configurationState = builder.configurationState; + dataChannelState = builder.dataChannelState; + notificationChannelState = builder.notificationChannelState; + quotaOccupied = builder.quotaOccupied; + quotaTotal = builder.quotaTotal; + isAirplaneMode = builder.isAirplaneMode; + } + + @TargetApi(VERSION_CODES.O) + private static int getNotificationChannelStateFormTelephony( + Context context, PhoneAccountHandle phoneAccountHandle) { + TelephonyManager telephonyManager = + context + .getSystemService(TelephonyManager.class) + .createForPhoneAccountHandle(phoneAccountHandle); + if (telephonyManager == null) { + LogUtil.e("VoicemailStatus.constructor", "invalid PhoneAccountHandle"); + return Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION; + } else { + int state = telephonyManager.getServiceState().getState(); + if (state == ServiceState.STATE_IN_SERVICE) { + return Status.NOTIFICATION_CHANNEL_STATE_OK; + } else { + return Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION; + } + } + } + + static class Builder { + + private String sourcePackage = ""; + private String type = TelephonyManager.VVM_TYPE_OMTP; + private String phoneAccountComponentName = ""; + private String phoneAccountId = ""; + + @Nullable private Uri settingsUri; + @Nullable private Uri voicemailAccessUri; + + private int configurationState = Status.CONFIGURATION_STATE_NOT_CONFIGURED; + private int dataChannelState = Status.DATA_CHANNEL_STATE_NO_CONNECTION; + private int notificationChannelState = Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION; + + private int quotaOccupied = Status.QUOTA_UNAVAILABLE; + private int quotaTotal = Status.QUOTA_UNAVAILABLE; + + private boolean isAirplaneMode; + + public VoicemailStatus build() { + return new VoicemailStatus(this); + } + + public Builder setSourcePackage(String sourcePackage) { + this.sourcePackage = sourcePackage; + return this; + } + + public Builder setType(String type) { + this.type = type; + return this; + } + + public Builder setPhoneAccountComponentName(String name) { + this.phoneAccountComponentName = name; + return this; + } + + public Builder setPhoneAccountId(String id) { + this.phoneAccountId = id; + return this; + } + + public Builder setSettingsUri(Uri settingsUri) { + this.settingsUri = settingsUri; + return this; + } + + public Builder setVoicemailAccessUri(Uri voicemailAccessUri) { + this.voicemailAccessUri = voicemailAccessUri; + return this; + } + + public Builder setConfigurationState(int configurationState) { + this.configurationState = configurationState; + return this; + } + + public Builder setDataChannelState(int dataChannelState) { + this.dataChannelState = dataChannelState; + return this; + } + + public Builder setNotificationChannelState(int notificationChannelState) { + this.notificationChannelState = notificationChannelState; + return this; + } + + public Builder setQuotaOccupied(int quotaOccupied) { + this.quotaOccupied = quotaOccupied; + return this; + } + + public Builder setQuotaTotal(int quotaTotal) { + this.quotaTotal = quotaTotal; + return this; + } + + public Builder setAirplaneMode(boolean isAirplaneMode) { + this.isAirplaneMode = isAirplaneMode; + return this; + } + } + + public boolean isActive() { + switch (configurationState) { + case Status.CONFIGURATION_STATE_NOT_CONFIGURED: + case Status.CONFIGURATION_STATE_DISABLED: + return false; + default: + return true; + } + } + + @Override + public String toString() { + return "VoicemailStatus[" + + "sourcePackage: " + + sourcePackage + + ", type:" + + type + + ", settingsUri: " + + settingsUri + + ", voicemailAccessUri: " + + voicemailAccessUri + + ", configurationState: " + + configurationState + + ", dataChannelState: " + + dataChannelState + + ", notificationChannelState: " + + notificationChannelState + + ", quotaOccupied: " + + quotaOccupied + + ", quotaTotal: " + + quotaTotal + + ", isAirplaneMode: " + + isAirplaneMode + + "]"; + } + + @Nullable + private static Uri getUri(Cursor cursor, int index) { + if (cursor.getString(index) != null) { + return Uri.parse(cursor.getString(index)); + } + return null; + } + + private static int getInt(Cursor cursor, int index, int defaultValue) { + if (cursor.isNull(index)) { + return defaultValue; + } + return cursor.getInt(index); + } + + private static String getString(Cursor cursor, int index, String defaultValue) { + if (cursor.isNull(index)) { + return defaultValue; + } + return cursor.getString(index); + } + + @Nullable + public PhoneAccountHandle getPhoneAccountHandle() { + if (TextUtils.isEmpty(phoneAccountComponentName) || TextUtils.isEmpty(phoneAccountId)) { + return null; + } + ComponentName componentName = ComponentName.unflattenFromString(phoneAccountComponentName); + if (componentName == null) { + return null; + } + return new PhoneAccountHandle(componentName, phoneAccountId); + } +} |