Merge "Immediately retry visual voicemail server calls." into mnc-dev
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 11f81ff..10ea8ce 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -274,8 +274,8 @@
}
if (ImsManager.isVolteEnabledByPlatform(this) &&
- !mPhone.getContext().getResources().getBoolean(
- com.android.internal.R.bool.config_carrier_volte_tty_supported)) {
+ !carrierConfig.getBoolean(
+ CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL)) {
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
/* tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); */
}
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index 303a384..8569693 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -200,10 +200,9 @@
mDialButton = findViewById(R.id.floating_action_button);
- CarrierConfigLoader configLoader = CarrierConfigLoader.init(this);
// Check whether we should show the onscreen "Dial" button and co.
- PersistableBundle carrierConfig =
- configLoader.getConfigForSubId(SubscriptionManager.getDefaultVoiceSubId());
+ PersistableBundle carrierConfig = PhoneGlobals.getInstance().getCarrierConfigForSubId(
+ SubscriptionManager.getDefaultVoiceSubId());
if (carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL)) {
mDialButton.setOnClickListener(this);
} else {
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index e8b6e05..ea44511 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -2651,8 +2651,20 @@
}
private boolean canReadPhoneState(String callingPackage, String message) {
- mApp.enforceCallingOrSelfPermission(
- android.Manifest.permission.READ_PHONE_STATE, message);
+ boolean failReadPhoneState = false;
+ try {
+ mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
+ message);
+ } catch (SecurityException e) {
+ failReadPhoneState = true;
+ }
+ if (failReadPhoneState) {
+ mApp.enforceCallingOrSelfPermission(
+ android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message);
+
+ // SKIP checking for run-time permission since obtained PRIVILEDGED
+ return true;
+ }
if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
callingPackage) != AppOpsManager.MODE_ALLOWED) {
diff --git a/src/com/android/phone/settings/AccessibilitySettingsFragment.java b/src/com/android/phone/settings/AccessibilitySettingsFragment.java
index fdb0cd5..d5a613b 100644
--- a/src/com/android/phone/settings/AccessibilitySettingsFragment.java
+++ b/src/com/android/phone/settings/AccessibilitySettingsFragment.java
@@ -25,6 +25,7 @@
import android.preference.PreferenceScreen;
import android.provider.Settings;
import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
@@ -98,9 +99,7 @@
public void onResume() {
super.onResume();
- if (ImsManager.isVolteEnabledByPlatform(mContext) &&
- !mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_carrier_volte_tty_supported)) {
+ if (ImsManager.isVolteEnabledByPlatform(mContext) && !getVolteTtySupported()) {
TelephonyManager tm =
(TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
@@ -111,9 +110,7 @@
public void onPause() {
super.onPause();
- if (ImsManager.isVolteEnabledByPlatform(mContext) &&
- !mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_carrier_volte_tty_supported)) {
+ if (ImsManager.isVolteEnabledByPlatform(mContext) && !getVolteTtySupported()) {
TelephonyManager tm =
(TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
@@ -138,4 +135,11 @@
}
return false;
}
+
+ private boolean getVolteTtySupported() {
+ CarrierConfigManager configManager =
+ (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ return configManager.getConfig().getBoolean(
+ CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL);
+ }
}
diff --git a/src/com/android/phone/settings/VisualVoicemailSettingsUtil.java b/src/com/android/phone/settings/VisualVoicemailSettingsUtil.java
index d2e797b..95dded8 100644
--- a/src/com/android/phone/settings/VisualVoicemailSettingsUtil.java
+++ b/src/com/android/phone/settings/VisualVoicemailSettingsUtil.java
@@ -73,12 +73,6 @@
PhoneUtils.makePstnPhoneAccountHandle(phone));
}
- public static boolean isEnabledByUserOverride(Context context,
- PhoneAccountHandle phoneAccount) {
- return isVisualVoicemailUserSet(context, phoneAccount) &&
- isVisualVoicemailEnabled(context, phoneAccount);
- }
-
/**
* Differentiate user-enabled/disabled to know whether to ignore automatic enabling and
* disabling by the system. This is relevant when a carrier vvm app is installed and the user
diff --git a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
index 0823552..5ffc9ea 100644
--- a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
+++ b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
@@ -21,7 +21,6 @@
import android.telecom.PhoneAccountHandle;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
import android.util.Log;
import com.android.internal.telephony.IccCardConstants;
@@ -68,20 +67,30 @@
PhoneAccountHandle phoneAccount = PhoneUtils.makePstnPhoneAccountHandle(
SubscriptionManager.getPhoneId(subId));
- if (carrierConfigHelper.isEnabledByDefault()) {
- VisualVoicemailSettingsUtil.setVisualVoicemailEnabled(
- context, phoneAccount, true, false);
+ boolean isUserSet = VisualVoicemailSettingsUtil.isVisualVoicemailUserSet(
+ context, phoneAccount);
+ boolean isEnabledInSettings =
+ VisualVoicemailSettingsUtil.isVisualVoicemailEnabled(context,
+ phoneAccount);
+ boolean isEnabled = isUserSet ? isEnabledInSettings :
+ carrierConfigHelper.isEnabledByDefault();
+
+ if (!isUserSet) {
+ // Preserve the previous setting for "isVisualVoicemailEnabled" if it is
+ // set by the user, otherwise, set this value for the first time.
+ VisualVoicemailSettingsUtil.setVisualVoicemailEnabled(context, phoneAccount,
+ isEnabled, /** isUserSet */ false);
}
- if (carrierConfigHelper.isEnabledByDefault() ||
- VisualVoicemailSettingsUtil.isEnabledByUserOverride(
- context, phoneAccount)) {
+ if (isEnabled) {
+ // Add a phone state listener so that changes to the communication channels
+ // can be recorded.
+ OmtpVvmSourceManager.getInstance(context).addPhoneStateListener(
+ phoneAccount);
carrierConfigHelper.startActivation();
} else {
// It may be that the source was not registered to begin with but we want
// to run through the steps to remove the source just in case.
- VisualVoicemailSettingsUtil.setVisualVoicemailEnabled(
- context, phoneAccount, false, false);
OmtpVvmSourceManager.getInstance(context).removeSource(phoneAccount);
carrierConfigHelper.startDeactivation();
}
diff --git a/src/com/android/phone/vvm/omtp/VvmPackageInstallReceiver.java b/src/com/android/phone/vvm/omtp/VvmPackageInstallReceiver.java
index 5559feb..0c4eb62 100644
--- a/src/com/android/phone/vvm/omtp/VvmPackageInstallReceiver.java
+++ b/src/com/android/phone/vvm/omtp/VvmPackageInstallReceiver.java
@@ -45,8 +45,8 @@
OmtpVvmSourceManager vvmSourceManager = OmtpVvmSourceManager.getInstance(context);
Set<PhoneAccountHandle> phoneAccounts = vvmSourceManager.getOmtpVvmSources();
for (PhoneAccountHandle phoneAccount : phoneAccounts) {
- if (VisualVoicemailSettingsUtil.isEnabledByUserOverride(context, phoneAccount)) {
- // Skip the check if this voicemail source is enabled by the user.
+ if (VisualVoicemailSettingsUtil.isVisualVoicemailUserSet(context, phoneAccount)) {
+ // Skip the check if this voicemail source's setting is overridden by the user.
continue;
}
diff --git a/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java b/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java
index 1467e41..fe4cf11 100644
--- a/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java
+++ b/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java
@@ -132,8 +132,8 @@
mPhoneAccount,
message);
- // Add a phone state listener so that changes to the communication channels can be recorded.
- vvmSourceManager.addPhoneStateListener(mPhoneAccount);
+ // Add the source to indicate that it is active.
+ vvmSourceManager.addSource(mPhoneAccount);
Intent serviceIntent = new Intent(mContext, OmtpVvmSyncService.class);
serviceIntent.setAction(OmtpVvmSyncService.SYNC_FULL_SYNC);
diff --git a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java
index 37fb5e4..59230cc 100644
--- a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java
+++ b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java
@@ -24,9 +24,9 @@
import com.android.internal.telephony.Phone;
import com.android.phone.PhoneUtils;
-import com.android.phone.settings.VisualVoicemailSettingsUtil;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -45,6 +45,7 @@
private TelephonyManager mTelephonyManager;
// Each phone account is associated with a phone state listener for updates to whether the
// device is able to sync.
+ private Set<PhoneAccountHandle> mActiveVvmSources;
private Map<PhoneAccountHandle, PhoneStateListener> mPhoneStateListenerMap;
/**
@@ -67,18 +68,22 @@
mSubscriptionManager = SubscriptionManager.from(context);
mTelephonyManager = (TelephonyManager)
mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ mActiveVvmSources = new HashSet<PhoneAccountHandle>();
mPhoneStateListenerMap = new HashMap<PhoneAccountHandle, PhoneStateListener>();
}
}
+ public void addSource(PhoneAccountHandle phoneAccount) {
+ mActiveVvmSources.add(phoneAccount);
+ }
+
/**
* When a voicemail source is removed, we don't always know which one was removed. Check the
* list of registered phone accounts against the active subscriptions list and remove the
* inactive sources.
*/
public void removeInactiveSources() {
- Set<PhoneAccountHandle> phoneAccounts = getOmtpVvmSources();
- for (PhoneAccountHandle phoneAccount : phoneAccounts) {
+ for (PhoneAccountHandle phoneAccount : mActiveVvmSources) {
if (!PhoneUtils.isPhoneAccountActive(mSubscriptionManager, phoneAccount)) {
removeSource(phoneAccount);
}
@@ -95,6 +100,7 @@
VoicemailContract.Status.DATA_CHANNEL_STATE_NO_CONNECTION,
VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
removePhoneStateListener(phoneAccount);
+ mActiveVvmSources.remove(phoneAccount);
}
public void addPhoneStateListener(PhoneAccountHandle phoneAccount) {
@@ -113,27 +119,21 @@
}
public Set<PhoneAccountHandle> getOmtpVvmSources() {
- return mPhoneStateListenerMap.keySet();
+ return mActiveVvmSources;
}
/**
* Check if a certain account is registered.
*
* @param phoneAccount The account to look for.
- * @return {@code true} if the account is in the list of registered OMTP voicemail sync
- * accounts. {@code false} otherwise.
+ * @return {@code true} if the account is in the list of registered OMTP voicemail sources.
+ * {@code false} otherwise.
*/
public boolean isVvmSourceRegistered(PhoneAccountHandle phoneAccount) {
if (phoneAccount == null) {
return false;
}
- Set<PhoneAccountHandle> sources = getOmtpVvmSources();
- for (PhoneAccountHandle source : sources) {
- if (phoneAccount.equals(source)) {
- return true;
- }
- }
- return false;
+ return mActiveVvmSources.contains(phoneAccount);
}
}
\ No newline at end of file
diff --git a/src/com/android/phone/vvm/omtp/sync/VoicemailStatusQueryHelper.java b/src/com/android/phone/vvm/omtp/sync/VoicemailStatusQueryHelper.java
index fa87a59..66f3e9d 100644
--- a/src/com/android/phone/vvm/omtp/sync/VoicemailStatusQueryHelper.java
+++ b/src/com/android/phone/vvm/omtp/sync/VoicemailStatusQueryHelper.java
@@ -22,23 +22,23 @@
import android.provider.VoicemailContract;
import android.provider.VoicemailContract.Status;
import android.telecom.PhoneAccountHandle;
-import android.util.Log;
/**
* Construct queries to interact with the voicemail status table.
*/
public class VoicemailStatusQueryHelper {
- private static final String TAG = "VoicemailStatusQueryHelper";
final static String[] PROJECTION = new String[] {
Status._ID, // 0
- Status.NOTIFICATION_CHANNEL_STATE, // 1
- Status.SOURCE_PACKAGE // 2
+ Status.CONFIGURATION_STATE, // 1
+ Status.NOTIFICATION_CHANNEL_STATE, // 2
+ Status.SOURCE_PACKAGE // 3
};
public static final int _ID = 0;
- public static final int NOTIFICATION_CHANNEL_STATE = 1;
- public static final int SOURCE_PACKAGE = 2;
+ public static final int CONFIGURATION_STATE = 1;
+ public static final int NOTIFICATION_CHANNEL_STATE = 2;
+ public static final int SOURCE_PACKAGE = 3;
private Context mContext;
private ContentResolver mContentResolver;
@@ -51,12 +51,38 @@
}
/**
+ * Check if the configuration state for the voicemail source is "ok", meaning that the
+ * source is set up.
+ *
+ * @param phoneAccount The phone account for the voicemail source to check.
+ * @return {@code true} if the voicemail source is configured, {@code} false otherwise,
+ * including if the voicemail source is not registered in the table.
+ */
+ public boolean isVoicemailSourceConfigured(PhoneAccountHandle phoneAccount) {
+ return isFieldEqualTo(phoneAccount, CONFIGURATION_STATE, Status.CONFIGURATION_STATE_OK);
+ }
+
+ /**
* Check if the notifications channel of a voicemail source is active. That is, when a new
* voicemail is available, if the server able to notify the device.
*
* @return {@code true} if notifications channel is active, {@code false} otherwise.
*/
public boolean isNotificationsChannelActive(PhoneAccountHandle phoneAccount) {
+ return isFieldEqualTo(phoneAccount, NOTIFICATION_CHANNEL_STATE,
+ Status.NOTIFICATION_CHANNEL_STATE_OK);
+ }
+
+ /**
+ * Check if a field for an entry in the status table is equal to a specific value.
+ *
+ * @param phoneAccount The phone account of the voicemail source to query for.
+ * @param columnIndex The column index of the field in the returned query.
+ * @param value The value to compare against.
+ * @return {@code true} if the stored value is equal to the provided value. {@code false}
+ * otherwise.
+ */
+ private boolean isFieldEqualTo(PhoneAccountHandle phoneAccount, int columnIndex, int value) {
Cursor cursor = null;
if (phoneAccount != null) {
String phoneAccountComponentName = phoneAccount.getComponentName().flattenToString();
@@ -73,8 +99,7 @@
cursor = mContentResolver.query(
mSourceUri, PROJECTION, whereClause, whereArgs, null);
if (cursor != null && cursor.moveToFirst()) {
- return cursor.getInt(NOTIFICATION_CHANNEL_STATE) ==
- Status.NOTIFICATION_CHANNEL_STATE_OK;
+ return cursor.getInt(columnIndex) == value;
}
}
finally {
diff --git a/src/com/android/phone/vvm/omtp/sync/VvmPhoneStateListener.java b/src/com/android/phone/vvm/omtp/sync/VvmPhoneStateListener.java
index f51a2f0..30f5a45 100644
--- a/src/com/android/phone/vvm/omtp/sync/VvmPhoneStateListener.java
+++ b/src/com/android/phone/vvm/omtp/sync/VvmPhoneStateListener.java
@@ -23,11 +23,13 @@
import android.telephony.ServiceState;
import com.android.phone.PhoneUtils;
+import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
/**
* Check if service is lost and indicate this in the voicemail status.
*/
public class VvmPhoneStateListener extends PhoneStateListener {
+
private PhoneAccountHandle mPhoneAccount;
private Context mContext;
public VvmPhoneStateListener(Context context, PhoneAccountHandle accountHandle) {
@@ -41,17 +43,22 @@
if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
VoicemailStatusQueryHelper voicemailStatusQueryHelper =
new VoicemailStatusQueryHelper(mContext);
- if (!voicemailStatusQueryHelper.isNotificationsChannelActive(mPhoneAccount)) {
- VoicemailContract.Status.setStatus(mContext, mPhoneAccount,
- VoicemailContract.Status.CONFIGURATION_STATE_OK,
- VoicemailContract.Status.DATA_CHANNEL_STATE_OK,
- VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK);
-
- // Run a full sync in case something was missed while signal was down.
- Intent serviceIntent = new Intent(mContext, OmtpVvmSyncService.class);
- serviceIntent.setAction(OmtpVvmSyncService.SYNC_FULL_SYNC);
- serviceIntent.putExtra(OmtpVvmSyncService.EXTRA_PHONE_ACCOUNT, mPhoneAccount);
- mContext.startService(serviceIntent);
+ if (voicemailStatusQueryHelper.isVoicemailSourceConfigured(mPhoneAccount)) {
+ if (!voicemailStatusQueryHelper.isNotificationsChannelActive(mPhoneAccount)) {
+ VoicemailContract.Status.setStatus(mContext, mPhoneAccount,
+ VoicemailContract.Status.CONFIGURATION_STATE_OK,
+ VoicemailContract.Status.DATA_CHANNEL_STATE_OK,
+ VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK);
+ // Run a full sync in case something was missed while signal was down.
+ Intent serviceIntent = new Intent(mContext, OmtpVvmSyncService.class);
+ serviceIntent.setAction(OmtpVvmSyncService.SYNC_FULL_SYNC);
+ serviceIntent.putExtra(OmtpVvmSyncService.EXTRA_PHONE_ACCOUNT, mPhoneAccount);
+ mContext.startService(serviceIntent);
+ }
+ } else {
+ OmtpVvmCarrierConfigHelper carrierConfigHelper = new OmtpVvmCarrierConfigHelper(
+ mContext, PhoneUtils.getSubIdForPhoneAccountHandle(mPhoneAccount));
+ carrierConfigHelper.startActivation();
}
} else {
VoicemailContract.Status.setStatus(mContext, mPhoneAccount,