Postpone error until no more retries are available
Error messages generated from tasks that have retries are often short
lived and not actionable. These errors should wait until no more
retries are available before being shown.
Before this CL, All error codes are written directly to the database
when a event is triggered. After this CL, writing to the database
requires a VoicemailStatus.Editor() object to be passed in. Usually
the object will be the same direct-write object as before. But in
retrying tasks, the object passed in will have the writes deferred
until the result of the task is determined. The writes will only be
committed if the task is successful or no more retries are left.
Passing a error handling object deep down is not ideal. A better way
will be throwing a exception back up so the task can decide how to
handle it. Unfortunately, deeper codes cannot handle escaping
exceptions gracefully, and changing it involves too much risk at this
moment.
+ Subsequent activation does not show the activating message
Fixes: 30284894
Change-Id: I523e8aa2f89ff3af13016eccd2392cee302e79dc
diff --git a/src/com/android/phone/VoicemailStatus.java b/src/com/android/phone/VoicemailStatus.java
index 062e734..2d8bcc3 100644
--- a/src/com/android/phone/VoicemailStatus.java
+++ b/src/com/android/phone/VoicemailStatus.java
@@ -23,7 +23,6 @@
import android.provider.VoicemailContract;
import android.provider.VoicemailContract.Status;
import android.telecom.PhoneAccountHandle;
-
import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
public class VoicemailStatus {
@@ -41,6 +40,10 @@
mPhoneAccountHandle = phoneAccountHandle;
}
+ public PhoneAccountHandle getPhoneAccountHandle() {
+ return mPhoneAccountHandle;
+ }
+
public Editor setType(String type) {
mValues.put(Status.SOURCE_TYPE, type);
return this;
@@ -79,6 +82,33 @@
ContentResolver contentResolver = mContext.getContentResolver();
Uri statusUri = VoicemailContract.Status.buildSourceUri(mContext.getPackageName());
contentResolver.insert(statusUri, mValues);
+ mValues.clear();
+ }
+
+ public ContentValues getValues() {
+ return mValues;
+ }
+ }
+
+ /**
+ * A voicemail status editor that the decision of whether to actually write to the database can
+ * be deferred. This object will be passed around as a usual {@link Editor}, but {@link
+ * #apply()} doesn't do anything. If later the creator of this object decides any status changes
+ * written to it should be committed, {@link #deferredApply()} should be called.
+ */
+ public static class DeferredEditor extends Editor {
+
+ private DeferredEditor(Context context, PhoneAccountHandle phoneAccountHandle) {
+ super(context, phoneAccountHandle);
+ }
+
+ @Override
+ public void apply() {
+ // Do nothing
+ }
+
+ public void deferredApply() {
+ super.apply();
}
}
@@ -89,4 +119,8 @@
public static Editor edit(Context context, int subId) {
return new Editor(context, PhoneAccountHandleConverter.fromSubId(subId));
}
+
+ public static DeferredEditor deferredEdit(Context context, int subId) {
+ return new DeferredEditor(context, PhoneAccountHandleConverter.fromSubId(subId));
+ }
}
diff --git a/src/com/android/phone/settings/VoicemailChangePinActivity.java b/src/com/android/phone/settings/VoicemailChangePinActivity.java
index a963af2..74adb12 100644
--- a/src/com/android/phone/settings/VoicemailChangePinActivity.java
+++ b/src/com/android/phone/settings/VoicemailChangePinActivity.java
@@ -46,6 +46,7 @@
import android.widget.Toast;
import com.android.phone.PhoneUtils;
import com.android.phone.R;
+import com.android.phone.VoicemailStatus;
import com.android.phone.common.mail.MessagingException;
import com.android.phone.vvm.omtp.OmtpConstants;
import com.android.phone.vvm.omtp.OmtpConstants.ChangePinResult;
@@ -181,7 +182,7 @@
// Wipe the default old PIN so the old PIN input box will be shown to the user
// on the next time.
setDefaultOldPIN(activity, activity.mPhoneAccountHandle, null);
- activity.mConfig.handleEvent(OmtpEvents.CONFIG_PIN_SET);
+ activity.handleOmtpEvent(OmtpEvents.CONFIG_PIN_SET);
activity.updateState(State.EnterOldPin);
}
}
@@ -271,7 +272,7 @@
// Wipe the default old PIN so the old PIN input box will be shown to the user
// on the next time.
setDefaultOldPIN(activity, activity.mPhoneAccountHandle, null);
- activity.mConfig.handleEvent(OmtpEvents.CONFIG_PIN_SET);
+ activity.handleOmtpEvent(OmtpEvents.CONFIG_PIN_SET);
activity.finish();
@@ -377,6 +378,16 @@
}
}
+ private void handleOmtpEvent(OmtpEvents event) {
+ mConfig.handleEvent(getVoicemailStatusEditor(), event);
+ }
+
+ private VoicemailStatus.Editor getVoicemailStatusEditor() {
+ // This activity does not have any automatic retry mechanism, errors should be written right
+ // away.
+ return VoicemailStatus.edit(this, mPhoneAccountHandle);
+ }
+
/**
* Extracts the pin length requirement sent by the server with a STATUS SMS.
*/
@@ -588,7 +599,8 @@
private final String mNewPin;
public ChangePinNetworkRequestCallback(String oldPin, String newPin) {
- super(mConfig, mPhoneAccountHandle);
+ super(mConfig, mPhoneAccountHandle,
+ VoicemailChangePinActivity.this.getVoicemailStatusEditor());
mOldPin = oldPin;
mNewPin = newPin;
}
@@ -597,7 +609,8 @@
public void onAvailable(Network network) {
super.onAvailable(network);
try (ImapHelper helper =
- new ImapHelper(VoicemailChangePinActivity.this, mPhoneAccountHandle, network)){
+ new ImapHelper(VoicemailChangePinActivity.this, mPhoneAccountHandle, network,
+ getVoicemailStatusEditor())) {
@ChangePinResult int result =
helper.changePin(mOldPin, mNewPin);
diff --git a/src/com/android/phone/vvm/omtp/ActivationTask.java b/src/com/android/phone/vvm/omtp/ActivationTask.java
index b575b95..5998950 100644
--- a/src/com/android/phone/vvm/omtp/ActivationTask.java
+++ b/src/com/android/phone/vvm/omtp/ActivationTask.java
@@ -29,6 +29,7 @@
import android.telephony.TelephonyManager;
import com.android.phone.Assert;
import com.android.phone.PhoneGlobals;
+import com.android.phone.VoicemailStatus;
import com.android.phone.vvm.omtp.protocol.VisualVoicemailProtocol;
import com.android.phone.vvm.omtp.scheduling.BaseTask;
import com.android.phone.vvm.omtp.scheduling.RetryPolicy;
@@ -63,11 +64,14 @@
@Nullable
private static DeviceProvisionedObserver sDeviceProvisionedObserver;
+ private final RetryPolicy mRetryPolicy;
+
private Bundle mData;
public ActivationTask() {
super(TASK_ACTIVATION);
- addPolicy(new RetryPolicy(RETRY_TIMES, RETRY_INTERVAL_MILLIS));
+ mRetryPolicy = new RetryPolicy(RETRY_TIMES, RETRY_INTERVAL_MILLIS);
+ addPolicy(mRetryPolicy);
}
/**
@@ -123,9 +127,18 @@
int subId = getSubId();
OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(getContext(), subId);
- helper.handleEvent(OmtpEvents.CONFIG_ACTIVATING);
- helper.activateSmsFilter();
PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
+ if (!OmtpVvmSourceManager.getInstance(getContext())
+ .isVvmSourceRegistered(phoneAccountHandle)) {
+ // Only show the "activating" message if activation has not been completed before in
+ // this boot. Subsequent activations are more of a status check and usually does not
+ // concern the user.
+ helper.handleEvent(VoicemailStatus.edit(getContext(), subId),
+ OmtpEvents.CONFIG_ACTIVATING);
+ }
+
+ helper.activateSmsFilter();
+ VoicemailStatus.Editor status = mRetryPolicy.getVoicemailStatusEditor();
VisualVoicemailProtocol protocol = helper.getProtocol();
@@ -144,7 +157,7 @@
} catch (TimeoutException e) {
// The carrier is expected to return an STATUS SMS within STATUS_SMS_TIMEOUT_MILLIS
// handleEvent() will do the logging.
- helper.handleEvent(OmtpEvents.CONFIG_STATUS_SMS_TIME_OUT);
+ helper.handleEvent(status, OmtpEvents.CONFIG_STATUS_SMS_TIME_OUT);
fail();
return;
} catch (InterruptedException | ExecutionException | IOException e) {
@@ -160,32 +173,32 @@
if (message.getProvisioningStatus().equals(OmtpConstants.SUBSCRIBER_READY)) {
VvmLog.d(TAG, "subscriber ready, no activation required");
- updateSource(getContext(), phoneAccountHandle, getSubId(), message);
+ updateSource(getContext(), phoneAccountHandle, getSubId(), status, message);
} else {
if (helper.supportsProvisioning()) {
VvmLog.i(TAG, "Subscriber not ready, start provisioning");
- helper.startProvisioning(this, phoneAccountHandle, message, data);
+ helper.startProvisioning(this, phoneAccountHandle, status, message, data);
} else if (message.getProvisioningStatus().equals(OmtpConstants.SUBSCRIBER_NEW)) {
VvmLog.i(TAG, "Subscriber new but provisioning is not supported");
// Ignore the non-ready state and attempt to use the provided info as is.
// This is probably caused by not completing the new user tutorial.
- updateSource(getContext(), phoneAccountHandle, getSubId(), message);
+ updateSource(getContext(), phoneAccountHandle, getSubId(), status, message);
} else {
VvmLog.i(TAG, "Subscriber not ready but provisioning is not supported");
- helper.handleEvent(OmtpEvents.CONFIG_SERVICE_NOT_AVAILABLE);
+ helper.handleEvent(status, OmtpEvents.CONFIG_SERVICE_NOT_AVAILABLE);
}
}
}
public static void updateSource(Context context, PhoneAccountHandle phone, int subId,
- StatusMessage message) {
+ VoicemailStatus.Editor status, StatusMessage message) {
OmtpVvmSourceManager vvmSourceManager =
OmtpVvmSourceManager.getInstance(context);
if (OmtpConstants.SUCCESS.equals(message.getReturnCode())) {
OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(context, subId);
- helper.handleEvent(OmtpEvents.CONFIG_REQUEST_STATUS_SUCCESS);
+ helper.handleEvent(status, OmtpEvents.CONFIG_REQUEST_STATUS_SUCCESS);
// Save the IMAP credentials in preferences so they are persistent and can be retrieved.
VisualVoicemailPreferences prefs = new VisualVoicemailPreferences(context, phone);
diff --git a/src/com/android/phone/vvm/omtp/DefaultOmtpEventHandler.java b/src/com/android/phone/vvm/omtp/DefaultOmtpEventHandler.java
index 353ba07..88943c9 100644
--- a/src/com/android/phone/vvm/omtp/DefaultOmtpEventHandler.java
+++ b/src/com/android/phone/vvm/omtp/DefaultOmtpEventHandler.java
@@ -27,31 +27,31 @@
private static final String TAG = "DefErrorCodeHandler";
public static void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
- OmtpEvents event) {
+ VoicemailStatus.Editor status, OmtpEvents event) {
switch (event.getType()) {
case Type.CONFIGURATION:
- handleConfigurationEvent(context, config, event);
+ handleConfigurationEvent(context, status, event);
break;
case Type.DATA_CHANNEL:
- handleDataChannelEvent(context, config, event);
+ handleDataChannelEvent(context, status, event);
break;
case Type.NOTIFICATION_CHANNEL:
- handleNotificationChannelEvent(context, config, event);
+ handleNotificationChannelEvent(context, config, status, event);
break;
case Type.OTHER:
- handleOtherEvent(context, config, event);
+ handleOtherEvent(context, status, event);
break;
default:
VvmLog.wtf(TAG, "invalid event type " + event.getType() + " for " + event);
}
}
- private static void handleConfigurationEvent(Context context, OmtpVvmCarrierConfigHelper config,
+ private static void handleConfigurationEvent(Context context, VoicemailStatus.Editor status,
OmtpEvents event) {
switch (event) {
case CONFIG_REQUEST_STATUS_SUCCESS:
case CONFIG_PIN_SET:
- VoicemailStatus.edit(context, config.getSubId())
+ status
.setConfigurationState(VoicemailContract.Status.CONFIGURATION_STATE_OK)
.setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
.apply();
@@ -59,18 +59,18 @@
case CONFIG_ACTIVATING:
// Wipe all errors from the last activation. All errors shown should be new errors
// for this activation.
- VoicemailStatus.edit(context, config.getSubId())
+ status
.setConfigurationState(Status.CONFIGURATION_STATE_CONFIGURING)
.setDataChannelState(Status.DATA_CHANNEL_STATE_OK)
.setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK).apply();
break;
case CONFIG_SERVICE_NOT_AVAILABLE:
- VoicemailStatus.edit(context, config.getSubId())
+ status
.setConfigurationState(Status.CONFIGURATION_STATE_FAILED)
.apply();
break;
case CONFIG_STATUS_SMS_TIME_OUT:
- VoicemailStatus.edit(context, config.getSubId())
+ status
.setConfigurationState(Status.CONFIGURATION_STATE_FAILED)
.apply();
break;
@@ -79,36 +79,36 @@
}
}
- private static void handleDataChannelEvent(Context context, OmtpVvmCarrierConfigHelper config,
+ private static void handleDataChannelEvent(Context context, VoicemailStatus.Editor status,
OmtpEvents event) {
switch (event) {
case DATA_IMAP_OPERATION_STARTED:
case DATA_IMAP_OPERATION_COMPLETED:
- VoicemailStatus.edit(context, config.getSubId())
+ status
.setDataChannelState(Status.DATA_CHANNEL_STATE_OK)
.apply();
break;
case DATA_NO_CONNECTION:
- VoicemailStatus.edit(context, config.getSubId())
+ status
.setDataChannelState(Status.DATA_CHANNEL_STATE_NO_CONNECTION)
.apply();
break;
case DATA_NO_CONNECTION_CELLULAR_REQUIRED:
- VoicemailStatus.edit(context, config.getSubId())
+ status
.setDataChannelState(
Status.DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED)
.apply();
break;
case DATA_INVALID_PORT:
- VoicemailStatus.edit(context, config.getSubId())
+ status
.setDataChannelState(
VoicemailContract.Status.DATA_CHANNEL_STATE_BAD_CONFIGURATION)
.apply();
break;
case DATA_CANNOT_RESOLVE_HOST_ON_NETWORK:
- VoicemailStatus.edit(context, config.getSubId())
+ status
.setDataChannelState(
VoicemailContract.Status.DATA_CHANNEL_STATE_SERVER_CONNECTION_ERROR)
.apply();
@@ -116,7 +116,7 @@
case DATA_SSL_INVALID_HOST_NAME:
case DATA_CANNOT_ESTABLISH_SSL_SESSION:
case DATA_IOE_ON_OPEN:
- VoicemailStatus.edit(context, config.getSubId())
+ status
.setDataChannelState(
VoicemailContract.Status.DATA_CHANNEL_STATE_COMMUNICATION_ERROR)
.apply();
@@ -129,7 +129,7 @@
case DATA_AUTH_SERVICE_NOT_PROVISIONED:
case DATA_AUTH_SERVICE_NOT_ACTIVATED:
case DATA_AUTH_USER_IS_BLOCKED:
- VoicemailStatus.edit(context, config.getSubId())
+ status
.setDataChannelState(
VoicemailContract.Status.DATA_CHANNEL_STATE_BAD_CONFIGURATION)
.apply();
@@ -139,7 +139,7 @@
case DATA_INVALID_INITIAL_SERVER_RESPONSE:
case DATA_SSL_EXCEPTION:
case DATA_ALL_SOCKET_CONNECTION_FAILED:
- VoicemailStatus.edit(context, config.getSubId())
+ status
.setDataChannelState(
VoicemailContract.Status.DATA_CHANNEL_STATE_SERVER_ERROR)
.apply();
@@ -151,10 +151,10 @@
}
private static void handleNotificationChannelEvent(Context context,
- OmtpVvmCarrierConfigHelper config, OmtpEvents event) {
+ OmtpVvmCarrierConfigHelper config, VoicemailStatus.Editor status, OmtpEvents event) {
switch (event) {
case NOTIFICATION_IN_SERVICE:
- VoicemailStatus.edit(context, config.getSubId())
+ status
.setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
// Clear the error state. A sync should follow signal return so any error
// will be reposted.
@@ -162,24 +162,23 @@
.apply();
break;
case NOTIFICATION_SERVICE_LOST:
- VoicemailStatus.Editor editor = VoicemailStatus.edit(context, config.getSubId());
- editor.setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
+ status.setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
if (config.isCellularDataRequired()) {
- editor.setDataChannelState(
+ status.setDataChannelState(
Status.DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED);
}
- editor.apply();
+ status.apply();
break;
default:
VvmLog.wtf(TAG, "invalid notification channel event " + event);
}
}
- private static void handleOtherEvent(Context context, OmtpVvmCarrierConfigHelper config,
+ private static void handleOtherEvent(Context context, VoicemailStatus.Editor status,
OmtpEvents event) {
switch (event) {
case OTHER_SOURCE_REMOVED:
- VoicemailStatus.edit(context, config.getSubId())
+ status
.setConfigurationState(Status.CONFIGURATION_STATE_NOT_CONFIGURED)
.setNotificationChannelState(
Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION)
diff --git a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
index 00a70be..5d06d1e 100644
--- a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
+++ b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
@@ -342,9 +342,9 @@
}
public void startProvisioning(ActivationTask task, PhoneAccountHandle phone,
- StatusMessage message, Bundle data) {
+ VoicemailStatus.Editor status, StatusMessage message, Bundle data) {
if (mProtocol != null) {
- mProtocol.startProvisioning(task, phone, this, message, data);
+ mProtocol.startProvisioning(task, phone, this, status, message, data);
}
}
@@ -354,10 +354,10 @@
}
}
- public void handleEvent(OmtpEvents event) {
+ public void handleEvent(VoicemailStatus.Editor status, OmtpEvents event) {
VvmLog.i(TAG, "OmtpEvent:" + event);
if (mProtocol != null) {
- mProtocol.handleEvent(mContext, this, event);
+ mProtocol.handleEvent(mContext, this, status, event);
}
}
diff --git a/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java b/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
index 1cb23d4..f64d15b 100644
--- a/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
+++ b/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
@@ -19,9 +19,9 @@
import android.telecom.PhoneAccountHandle;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
-
import com.android.phone.PhoneGlobals;
import com.android.phone.PhoneUtils;
+import com.android.phone.VoicemailStatus;
import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
import com.android.phone.vvm.omtp.sync.OmtpVvmSyncService;
import com.android.phone.vvm.omtp.sync.SyncTask;
@@ -66,7 +66,8 @@
if (!voicemailStatusQueryHelper.isNotificationsChannelActive(mPhoneAccount)) {
VvmLog
.v(TAG, "Notifications channel is active for " + subId);
- helper.handleEvent(OmtpEvents.NOTIFICATION_IN_SERVICE);
+ helper.handleEvent(VoicemailStatus.edit(mContext, mPhoneAccount),
+ OmtpEvents.NOTIFICATION_IN_SERVICE);
PhoneGlobals.getInstance().clearMwiIndicator(subId);
}
}
@@ -91,7 +92,8 @@
if (!OmtpVvmSourceManager.getInstance(mContext).isVvmSourceRegistered(mPhoneAccount)) {
return;
}
- helper.handleEvent(OmtpEvents.NOTIFICATION_SERVICE_LOST);
+ helper.handleEvent(VoicemailStatus.edit(mContext, mPhoneAccount),
+ OmtpEvents.NOTIFICATION_SERVICE_LOST);
}
mPreviousState = state;
}
diff --git a/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java b/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
index 5ec190f..d5e627f 100644
--- a/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
+++ b/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
@@ -30,15 +30,14 @@
import android.telecom.PhoneAccountHandle;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
-
import com.android.phone.PhoneUtils;
+import com.android.phone.VoicemailStatus;
import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
import com.android.phone.vvm.omtp.VvmLog;
import com.android.phone.vvm.omtp.imap.ImapHelper;
import com.android.phone.vvm.omtp.imap.ImapHelper.InitializingException;
import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
import com.android.phone.vvm.omtp.sync.VvmNetworkRequestCallback;
-
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
@@ -142,17 +141,17 @@
public fetchVoicemailNetworkRequestCallback(Context context,
PhoneAccountHandle phoneAccount) {
- super(context, phoneAccount);
+ super(context, phoneAccount, VoicemailStatus.edit(context, phoneAccount));
}
@Override
public void onAvailable(final Network network) {
super.onAvailable(network);
- fetchVoicemail(network);
+ fetchVoicemail(network, getVoicemailStatusEditor());
}
}
- private void fetchVoicemail(final Network network) {
+ private void fetchVoicemail(final Network network, final VoicemailStatus.Editor status) {
Executor executor = Executors.newCachedThreadPool();
executor.execute(new Runnable() {
@Override
@@ -161,7 +160,7 @@
while (mRetryCount > 0) {
VvmLog.i(TAG, "fetching voicemail, retry count=" + mRetryCount);
try (ImapHelper imapHelper = new ImapHelper(mContext, mPhoneAccount,
- network)) {
+ network, status)) {
boolean success = imapHelper.fetchVoicemailPayload(
new VoicemailFetchedCallback(mContext, mUri), mUid);
if (!success && mRetryCount > 0) {
diff --git a/src/com/android/phone/vvm/omtp/imap/ImapHelper.java b/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
index ce13323..d2df8de 100644
--- a/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
+++ b/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
@@ -72,6 +72,7 @@
private final Context mContext;
private final PhoneAccountHandle mPhoneAccount;
private final Network mNetwork;
+ private final VoicemailStatus.Editor mStatus;
VisualVoicemailPreferences mPrefs;
private static final String PREF_KEY_QUOTA_OCCUPIED = "quota_occupied_";
@@ -89,17 +90,20 @@
}
}
- public ImapHelper(Context context, PhoneAccountHandle phoneAccount, Network network)
+ public ImapHelper(Context context, PhoneAccountHandle phoneAccount, Network network,
+ VoicemailStatus.Editor status)
throws InitializingException {
this(context, new OmtpVvmCarrierConfigHelper(context,
- PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccount)), phoneAccount, network);
+ PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccount)), phoneAccount, network, status);
}
public ImapHelper(Context context, OmtpVvmCarrierConfigHelper config,
- PhoneAccountHandle phoneAccount, Network network) throws InitializingException {
+ PhoneAccountHandle phoneAccount, Network network, VoicemailStatus.Editor status)
+ throws InitializingException {
mContext = context;
mPhoneAccount = phoneAccount;
mNetwork = network;
+ mStatus = status;
mConfig = config;
mPrefs = new VisualVoicemailPreferences(context,
phoneAccount);
@@ -123,7 +127,7 @@
mImapStore = new ImapStore(
context, this, username, password, port, serverName, auth, network);
} catch (NumberFormatException e) {
- mConfig.handleEvent(OmtpEvents.DATA_INVALID_PORT);
+ handleEvent(OmtpEvents.DATA_INVALID_PORT);
LogUtils.w(TAG, "Could not parse port number");
throw new InitializingException("cannot initialize ImapHelper:" + e.toString());
}
@@ -172,7 +176,7 @@
}
public void handleEvent(OmtpEvents event) {
- mConfig.handleEvent(event);
+ mConfig.handleEvent(mStatus, event);
}
/**
diff --git a/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocol.java b/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocol.java
index 5f89471..e0b6359 100644
--- a/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocol.java
+++ b/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocol.java
@@ -21,6 +21,7 @@
import android.os.Bundle;
import android.telecom.PhoneAccountHandle;
import android.telephony.SmsManager;
+import com.android.phone.VoicemailStatus;
import com.android.phone.vvm.omtp.ActivationTask;
import com.android.phone.vvm.omtp.DefaultOmtpEventHandler;
import com.android.phone.vvm.omtp.OmtpEvents;
@@ -52,7 +53,8 @@
}
public void startProvisioning(ActivationTask task, PhoneAccountHandle handle,
- OmtpVvmCarrierConfigHelper config, StatusMessage message, Bundle data) {
+ OmtpVvmCarrierConfigHelper config, VoicemailStatus.Editor editor, StatusMessage message,
+ Bundle data) {
// Do nothing
}
@@ -79,8 +81,8 @@
}
public void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
- OmtpEvents event) {
- DefaultOmtpEventHandler.handleEvent(context, config, event);
+ VoicemailStatus.Editor status, OmtpEvents event) {
+ DefaultOmtpEventHandler.handleEvent(context, config, status, event);
}
/**
diff --git a/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java b/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java
index 3a3adb8..6fac708 100644
--- a/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java
+++ b/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java
@@ -18,7 +18,6 @@
import android.annotation.IntDef;
import android.content.Context;
-import android.telecom.PhoneAccountHandle;
import android.util.Log;
import com.android.phone.VoicemailStatus;
import com.android.phone.settings.VoicemailChangePinActivity;
@@ -26,7 +25,6 @@
import com.android.phone.vvm.omtp.OmtpEvents;
import com.android.phone.vvm.omtp.OmtpEvents.Type;
import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -87,47 +85,46 @@
public static void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
- OmtpEvents event) {
+ VoicemailStatus.Editor status, OmtpEvents event) {
boolean handled = false;
switch (event.getType()) {
case Type.CONFIGURATION:
- handled = handleConfigurationEvent(context, config, event);
+ handled = handleConfigurationEvent(context, status, event);
break;
case Type.DATA_CHANNEL:
- handled = handleDataChannelEvent(context, config, event);
+ handled = handleDataChannelEvent(status, event);
break;
case Type.NOTIFICATION_CHANNEL:
- handled = handleNotificationChannelEvent(context, config, event);
+ handled = handleNotificationChannelEvent(status, event);
break;
case Type.OTHER:
- handled = handleOtherEvent(context, config, event);
+ handled = handleOtherEvent(status, event);
break;
default:
com.android.services.telephony.Log
.wtf(TAG, "invalid event type " + event.getType() + " for " + event);
}
if (!handled) {
- DefaultOmtpEventHandler.handleEvent(context, config, event);
+ DefaultOmtpEventHandler.handleEvent(context, config, status, event);
}
}
- private static boolean handleConfigurationEvent(Context context,
- OmtpVvmCarrierConfigHelper config, OmtpEvents event) {
+ private static boolean handleConfigurationEvent(Context context, VoicemailStatus.Editor status,
+ OmtpEvents event) {
switch (event) {
case CONFIG_REQUEST_STATUS_SUCCESS:
- PhoneAccountHandle handle = PhoneAccountHandleConverter
- .fromSubId(config.getSubId());
- if (!VoicemailChangePinActivity.isDefaultOldPinSet(context, handle)) {
+ if (!VoicemailChangePinActivity
+ .isDefaultOldPinSet(context, status.getPhoneAccountHandle())) {
return false;
} else {
- postError(context, config, PIN_NOT_SET);
+ postError(status, PIN_NOT_SET);
}
break;
case CONFIG_DEFAULT_PIN_REPLACED:
- postError(context, config, PIN_NOT_SET);
+ postError(status, PIN_NOT_SET);
break;
case CONFIG_STATUS_SMS_TIME_OUT:
- postError(context, config, STATUS_SMS_TIMEOUT);
+ postError(status, STATUS_SMS_TIMEOUT);
break;
default:
return false;
@@ -135,50 +132,49 @@
return true;
}
- private static boolean handleDataChannelEvent(Context context,
- OmtpVvmCarrierConfigHelper config, OmtpEvents event) {
+ private static boolean handleDataChannelEvent(VoicemailStatus.Editor status, OmtpEvents event) {
switch (event) {
case DATA_NO_CONNECTION:
case DATA_NO_CONNECTION_CELLULAR_REQUIRED:
case DATA_ALL_SOCKET_CONNECTION_FAILED:
- postError(context, config, VMS_NO_CELLULAR);
+ postError(status, VMS_NO_CELLULAR);
break;
case DATA_SSL_INVALID_HOST_NAME:
case DATA_CANNOT_ESTABLISH_SSL_SESSION:
case DATA_IOE_ON_OPEN:
- postError(context, config, VMS_TIMEOUT);
+ postError(status, VMS_TIMEOUT);
break;
case DATA_CANNOT_RESOLVE_HOST_ON_NETWORK:
- postError(context, config, VMS_DNS_FAILURE);
+ postError(status, VMS_DNS_FAILURE);
break;
case DATA_BAD_IMAP_CREDENTIAL:
- postError(context, config, IMAP_ERROR);
+ postError(status, IMAP_ERROR);
break;
case DATA_AUTH_UNKNOWN_USER:
- postError(context, config, UNKNOWN_USER);
+ postError(status, UNKNOWN_USER);
break;
case DATA_AUTH_UNKNOWN_DEVICE:
- postError(context, config, UNKNOWN_DEVICE);
+ postError(status, UNKNOWN_DEVICE);
break;
case DATA_AUTH_INVALID_PASSWORD:
- postError(context, config, INVALID_PASSWORD);
+ postError(status, INVALID_PASSWORD);
break;
case DATA_AUTH_MAILBOX_NOT_INITIALIZED:
- postError(context, config, MAILBOX_NOT_INITIALIZED);
+ postError(status, MAILBOX_NOT_INITIALIZED);
break;
case DATA_AUTH_SERVICE_NOT_PROVISIONED:
- postError(context, config, SERVICE_NOT_PROVISIONED);
+ postError(status, SERVICE_NOT_PROVISIONED);
break;
case DATA_AUTH_SERVICE_NOT_ACTIVATED:
- postError(context, config, SERVICE_NOT_ACTIVATED);
+ postError(status, SERVICE_NOT_ACTIVATED);
break;
case DATA_AUTH_USER_IS_BLOCKED:
- postError(context, config, USER_BLOCKED);
+ postError(status, USER_BLOCKED);
break;
case DATA_REJECTED_SERVER_RESPONSE:
case DATA_INVALID_INITIAL_SERVER_RESPONSE:
case DATA_SSL_EXCEPTION:
- postError(context, config, IMAP_ERROR);
+ postError(status, IMAP_ERROR);
break;
default:
return false;
@@ -186,40 +182,40 @@
return true;
}
- private static boolean handleNotificationChannelEvent(Context context,
- OmtpVvmCarrierConfigHelper config, OmtpEvents event) {
+ private static boolean handleNotificationChannelEvent(VoicemailStatus.Editor status,
+ OmtpEvents event) {
return false;
}
- private static boolean handleOtherEvent(Context context, OmtpVvmCarrierConfigHelper config,
+ private static boolean handleOtherEvent(VoicemailStatus.Editor status,
OmtpEvents event) {
switch (event) {
case VVM3_NEW_USER_SETUP_FAILED:
- postError(context, config, MAILBOX_NOT_INITIALIZED);
+ postError(status, MAILBOX_NOT_INITIALIZED);
break;
case VVM3_VMG_DNS_FAILURE:
- postError(context, config, VMG_DNS_FAILURE);
+ postError(status, VMG_DNS_FAILURE);
break;
case VVM3_SPG_DNS_FAILURE:
- postError(context, config, SPG_DNS_FAILURE);
+ postError(status, SPG_DNS_FAILURE);
break;
case VVM3_VMG_CONNECTION_FAILED:
- postError(context, config, VMG_NO_CELLULAR);
+ postError(status, VMG_NO_CELLULAR);
break;
case VVM3_SPG_CONNECTION_FAILED:
- postError(context, config, SPG_NO_CELLULAR);
+ postError(status, SPG_NO_CELLULAR);
break;
case VVM3_VMG_TIMEOUT:
- postError(context, config, VMG_TIMEOUT);
+ postError(status, VMG_TIMEOUT);
break;
case VVM3_SUBSCRIBER_PROVISIONED:
- postError(context, config, SERVICE_NOT_ACTIVATED);
+ postError(status, SERVICE_NOT_ACTIVATED);
break;
case VVM3_SUBSCRIBER_BLOCKED:
- postError(context, config, SUBSCRIBER_BLOCKED);
+ postError(status, SUBSCRIBER_BLOCKED);
break;
case VVM3_SUBSCRIBER_UNKNOWN:
- postError(context, config, SUBSCRIBER_UNKNOWN);
+ postError(status, SUBSCRIBER_UNKNOWN);
break;
default:
return false;
@@ -227,10 +223,7 @@
return true;
}
- private static void postError(Context context, OmtpVvmCarrierConfigHelper config,
- @ErrorCode int errorCode) {
- VoicemailStatus.Editor editor = VoicemailStatus.edit(context, config.getSubId());
-
+ private static void postError(VoicemailStatus.Editor editor, @ErrorCode int errorCode) {
switch (errorCode) {
case VMG_DNS_FAILURE:
case SPG_DNS_FAILURE:
diff --git a/src/com/android/phone/vvm/omtp/protocol/Vvm3Protocol.java b/src/com/android/phone/vvm/omtp/protocol/Vvm3Protocol.java
index f5c65e2..39d2b34 100644
--- a/src/com/android/phone/vvm/omtp/protocol/Vvm3Protocol.java
+++ b/src/com/android/phone/vvm/omtp/protocol/Vvm3Protocol.java
@@ -23,6 +23,7 @@
import android.telecom.PhoneAccountHandle;
import android.telephony.SmsManager;
import android.text.TextUtils;
+import com.android.phone.VoicemailStatus;
import com.android.phone.common.mail.MessagingException;
import com.android.phone.settings.VisualVoicemailSettingsUtil;
import com.android.phone.settings.VoicemailChangePinActivity;
@@ -102,16 +103,17 @@
@Override
public void startProvisioning(ActivationTask task, PhoneAccountHandle phoneAccountHandle,
- OmtpVvmCarrierConfigHelper config, StatusMessage message, Bundle data) {
+ OmtpVvmCarrierConfigHelper config, VoicemailStatus.Editor status, StatusMessage message,
+ Bundle data) {
VvmLog.i(TAG, "start vvm3 provisioning");
if (OmtpConstants.SUBSCRIBER_UNKNOWN.equals(message.getProvisioningStatus())) {
VvmLog.i(TAG, "Provisioning status: Unknown");
if (VVM3_UNKNOWN_SUBSCRIBER_CAN_SUBSCRIBE_RESPONSE_CODE
.equals(message.getReturnCode())) {
VvmLog.i(TAG, "Self provisioning available, subscribing");
- new Vvm3Subscriber(task, phoneAccountHandle, config, data).subscribe();
+ new Vvm3Subscriber(task, phoneAccountHandle, config, status, data).subscribe();
} else {
- config.handleEvent(OmtpEvents.VVM3_SUBSCRIBER_UNKNOWN);
+ config.handleEvent(status, OmtpEvents.VVM3_SUBSCRIBER_UNKNOWN);
}
} else if (OmtpConstants.SUBSCRIBER_NEW.equals(message.getProvisioningStatus())) {
VvmLog.i(TAG, "setting up new user");
@@ -120,14 +122,14 @@
new VisualVoicemailPreferences(config.getContext(), phoneAccountHandle);
message.putStatus(prefs.edit()).apply();
- startProvisionNewUser(task, phoneAccountHandle, config, message);
+ startProvisionNewUser(task, phoneAccountHandle, config, status, message);
} else if (OmtpConstants.SUBSCRIBER_PROVISIONED.equals(message.getProvisioningStatus())) {
VvmLog.i(TAG, "User provisioned but not activated, disabling VVM");
VisualVoicemailSettingsUtil
.setEnabled(config.getContext(), phoneAccountHandle, false);
} else if (OmtpConstants.SUBSCRIBER_BLOCKED.equals(message.getProvisioningStatus())) {
VvmLog.i(TAG, "User blocked");
- config.handleEvent(OmtpEvents.VVM3_SUBSCRIBER_BLOCKED);
+ config.handleEvent(status, OmtpEvents.VVM3_SUBSCRIBER_BLOCKED);
}
}
@@ -138,8 +140,9 @@
}
@Override
- public void handleEvent(Context context, OmtpVvmCarrierConfigHelper config, OmtpEvents event) {
- Vvm3EventHandler.handleEvent(context, config, event);
+ public void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
+ VoicemailStatus.Editor status, OmtpEvents event) {
+ Vvm3EventHandler.handleEvent(context, config, status, event);
}
@Override
@@ -183,13 +186,15 @@
}
private void startProvisionNewUser(ActivationTask task, PhoneAccountHandle phoneAccountHandle,
- OmtpVvmCarrierConfigHelper config, StatusMessage message) {
- try (NetworkWrapper wrapper = VvmNetworkRequest.getNetwork(config, phoneAccountHandle)) {
+ OmtpVvmCarrierConfigHelper config, VoicemailStatus.Editor status,
+ StatusMessage message) {
+ try (NetworkWrapper wrapper = VvmNetworkRequest
+ .getNetwork(config, phoneAccountHandle, status)) {
Network network = wrapper.get();
VvmLog.i(TAG, "new user: network available");
try (ImapHelper helper = new ImapHelper(config.getContext(), phoneAccountHandle,
- network)) {
+ network, status)) {
// VVM3 has inconsistent error language code to OMTP. Just issue a raw command
// here.
// TODO(b/29082671): use LocaleList
@@ -213,12 +218,12 @@
config.requestStatus();
}
} catch (InitializingException | MessagingException | IOException e) {
- config.handleEvent(OmtpEvents.VVM3_NEW_USER_SETUP_FAILED);
+ config.handleEvent(status, OmtpEvents.VVM3_NEW_USER_SETUP_FAILED);
task.fail();
VvmLog.e(TAG, e.toString());
}
} catch (RequestFailedException e) {
- config.handleEvent(OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
+ config.handleEvent(status, OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
task.fail();
}
diff --git a/src/com/android/phone/vvm/omtp/protocol/Vvm3Subscriber.java b/src/com/android/phone/vvm/omtp/protocol/Vvm3Subscriber.java
index 08e9352..ad00aa4 100644
--- a/src/com/android/phone/vvm/omtp/protocol/Vvm3Subscriber.java
+++ b/src/com/android/phone/vvm/omtp/protocol/Vvm3Subscriber.java
@@ -27,6 +27,7 @@
import android.text.style.URLSpan;
import android.util.ArrayMap;
import com.android.phone.Assert;
+import com.android.phone.VoicemailStatus;
import com.android.phone.vvm.omtp.ActivationTask;
import com.android.phone.vvm.omtp.OmtpEvents;
import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
@@ -113,6 +114,7 @@
private final ActivationTask mTask;
private final PhoneAccountHandle mHandle;
private final OmtpVvmCarrierConfigHelper mHelper;
+ private final VoicemailStatus.Editor mStatus;
private final Bundle mData;
private final String mNumber;
@@ -137,11 +139,12 @@
@WorkerThread
public Vvm3Subscriber(ActivationTask task, PhoneAccountHandle handle,
- OmtpVvmCarrierConfigHelper helper, Bundle data) {
+ OmtpVvmCarrierConfigHelper helper, VoicemailStatus.Editor status, Bundle data) {
Assert.isNotMainThread();
mTask = task;
mHandle = handle;
mHelper = helper;
+ mStatus = status;
mData = data;
// Assuming getLine1Number() will work with VVM3. For unprovisioned users the IMAP username
@@ -157,14 +160,14 @@
// processSubscription() is called after network is available.
VvmLog.i(TAG, "Subscribing");
- try (NetworkWrapper wrapper = VvmNetworkRequest.getNetwork(mHelper, mHandle)) {
+ try (NetworkWrapper wrapper = VvmNetworkRequest.getNetwork(mHelper, mHandle, mStatus)) {
Network network = wrapper.get();
VvmLog.d(TAG, "provisioning: network available");
mRequestQueue = Volley
.newRequestQueue(mHelper.getContext(), new NetworkSpecifiedHurlStack(network));
processSubscription();
} catch (RequestFailedException e) {
- mHelper.handleEvent(OmtpEvents.VVM3_VMG_CONNECTION_FAILED);
+ mHelper.handleEvent(mStatus, OmtpEvents.VVM3_VMG_CONNECTION_FAILED);
mTask.fail();
}
}
@@ -219,7 +222,7 @@
try {
return future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
- mHelper.handleEvent(OmtpEvents.VVM3_SPG_CONNECTION_FAILED);
+ mHelper.handleEvent(mStatus, OmtpEvents.VVM3_SPG_CONNECTION_FAILED);
throw new ProvisioningException(e.toString());
}
}
@@ -235,7 +238,7 @@
// A new STATUS SMS will be sent after this request.
future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (TimeoutException | ExecutionException | InterruptedException e) {
- mHelper.handleEvent(OmtpEvents.VVM3_SPG_CONNECTION_FAILED);
+ mHelper.handleEvent(mStatus, OmtpEvents.VVM3_SPG_CONNECTION_FAILED);
throw new ProvisioningException(e.toString());
}
// It could take very long for the STATUS SMS to return. Waiting for it is unreliable.
@@ -271,7 +274,7 @@
}
return response;
} catch (InterruptedException | ExecutionException | TimeoutException e) {
- mHelper.handleEvent(OmtpEvents.VVM3_VMG_CONNECTION_FAILED);
+ mHelper.handleEvent(mStatus, OmtpEvents.VVM3_VMG_CONNECTION_FAILED);
throw new ProvisioningException(e.toString());
}
}
diff --git a/src/com/android/phone/vvm/omtp/scheduling/BaseTask.java b/src/com/android/phone/vvm/omtp/scheduling/BaseTask.java
index 8b3e88e..273d2d3 100644
--- a/src/com/android/phone/vvm/omtp/scheduling/BaseTask.java
+++ b/src/com/android/phone/vvm/omtp/scheduling/BaseTask.java
@@ -23,10 +23,8 @@
import android.content.Intent;
import android.os.SystemClock;
import android.support.annotation.NonNull;
-
import com.android.phone.Assert;
import com.android.phone.NeededForTesting;
-
import java.util.ArrayList;
import java.util.List;
@@ -167,6 +165,7 @@
}
@Override
+ @CallSuper
public void onCompleted() {
if (mHasFailed) {
for (Policy policy : mPolicies) {
diff --git a/src/com/android/phone/vvm/omtp/scheduling/RetryPolicy.java b/src/com/android/phone/vvm/omtp/scheduling/RetryPolicy.java
index 3c2274f..bd0c75e 100644
--- a/src/com/android/phone/vvm/omtp/scheduling/RetryPolicy.java
+++ b/src/com/android/phone/vvm/omtp/scheduling/RetryPolicy.java
@@ -17,7 +17,7 @@
package com.android.phone.vvm.omtp.scheduling;
import android.content.Intent;
-
+import com.android.phone.VoicemailStatus;
import com.android.phone.vvm.omtp.VvmLog;
/**
@@ -38,11 +38,26 @@
private int mRetryCount;
private boolean mFailed;
+ private VoicemailStatus.DeferredEditor mVoicemailStatusEditor;
+
public RetryPolicy(int retryLimit, int retryDelayMillis) {
mRetryLimit = retryLimit;
mRetryDelayMillis = retryDelayMillis;
}
+ private boolean hasMoreRetries() {
+ return mRetryCount < mRetryLimit;
+ }
+
+ /**
+ * Error status should only be set if retries has exhausted or the task is successful. Status
+ * writes to this editor will be deferred until the task has ended, and will only be committed
+ * if the task is successful or there are no retries left.
+ */
+ public VoicemailStatus.Editor getVoicemailStatusEditor() {
+ return mVoicemailStatusEditor;
+ }
+
@Override
public void onCreate(BaseTask task, Intent intent, int flags, int startId) {
mTask = task;
@@ -52,6 +67,8 @@
+ mRetryDelayMillis);
mTask.setExecutionTime(mTask.getTimeMillis() + mRetryDelayMillis);
}
+ mVoicemailStatusEditor = VoicemailStatus.deferredEdit(task.getContext(),
+ task.getSubId());
}
@Override
@@ -61,14 +78,18 @@
@Override
public void onCompleted() {
- if (!mFailed) {
+ if (!mFailed || !hasMoreRetries()) {
+ if (!mFailed) {
+ VvmLog.d(TAG, mTask.toString() + " completed successfully");
+ }
+ if (!hasMoreRetries()) {
+ VvmLog.d(TAG, "Retry limit for " + mTask + " reached");
+ }
+ VvmLog.i(TAG, "committing deferred status: " + mVoicemailStatusEditor.getValues());
+ mVoicemailStatusEditor.deferredApply();
return;
}
- if (mRetryCount >= mRetryLimit) {
- VvmLog.d(TAG, "Retry limit for " + mTask + " reached");
- return;
- }
-
+ VvmLog.i(TAG, "discarding deferred status: " + mVoicemailStatusEditor.getValues());
Intent intent = mTask.createRestartIntent();
intent.putExtra(EXTRA_RETRY_COUNT, mRetryCount + 1);
diff --git a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java
index 1972ca6..ac4ba0a 100644
--- a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java
+++ b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java
@@ -20,14 +20,13 @@
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
-
import com.android.internal.telephony.Phone;
import com.android.phone.PhoneUtils;
+import com.android.phone.VoicemailStatus;
import com.android.phone.vvm.omtp.OmtpEvents;
import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
import com.android.phone.vvm.omtp.VvmPhoneStateListener;
import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-
import java.util.Collections;
import java.util.Map;
import java.util.Set;
@@ -108,7 +107,8 @@
public void removeSource(PhoneAccountHandle phoneAccount) {
new OmtpVvmCarrierConfigHelper(mContext, PhoneAccountHandleConverter.toSubId(phoneAccount))
- .handleEvent(OmtpEvents.OTHER_SOURCE_REMOVED);
+ .handleEvent(VoicemailStatus.edit(mContext, phoneAccount),
+ OmtpEvents.OTHER_SOURCE_REMOVED);
removePhoneStateListener(phoneAccount);
mActiveVvmSources.remove(phoneAccount);
}
diff --git a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
index 157f51f..2dc27b2 100644
--- a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
+++ b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
@@ -24,6 +24,7 @@
import android.telecom.Voicemail;
import android.text.TextUtils;
import com.android.phone.PhoneUtils;
+import com.android.phone.VoicemailStatus;
import com.android.phone.settings.VisualVoicemailSettingsUtil;
import com.android.phone.vvm.omtp.ActivationTask;
import com.android.phone.vvm.omtp.OmtpEvents;
@@ -81,19 +82,19 @@
}
public void sync(BaseTask task, String action, PhoneAccountHandle phoneAccount,
- Voicemail voicemail) {
+ Voicemail voicemail, VoicemailStatus.Editor status) {
VvmLog.log(TAG, "Sync requested: " + action +
" for all accounts: " + String.valueOf(phoneAccount == null));
if (phoneAccount != null) {
VvmLog.v(TAG, "Sync requested: " + action + " - for account: " + phoneAccount);
- setupAndSendRequest(task, phoneAccount, voicemail, action);
+ setupAndSendRequest(task, phoneAccount, voicemail, action, status);
} else {
VvmLog.v(TAG, "Sync requested: " + action + " - for all accounts");
OmtpVvmSourceManager vvmSourceManager =
OmtpVvmSourceManager.getInstance(mContext);
Set<PhoneAccountHandle> sources = vvmSourceManager.getOmtpVvmSources();
for (PhoneAccountHandle source : sources) {
- setupAndSendRequest(task, source, null, action);
+ setupAndSendRequest(task, source, null, action, status);
}
activateUnactivatedAccounts();
}
@@ -115,7 +116,7 @@
}
private void setupAndSendRequest(BaseTask task, PhoneAccountHandle phoneAccount,
- Voicemail voicemail, String action) {
+ Voicemail voicemail, String action, VoicemailStatus.Editor status) {
if (!VisualVoicemailSettingsUtil.isEnabled(mContext, phoneAccount)) {
VvmLog.v(TAG, "Sync requested for disabled account");
return;
@@ -127,23 +128,27 @@
}
OmtpVvmCarrierConfigHelper config = new OmtpVvmCarrierConfigHelper(mContext, subId);
- config.handleEvent(OmtpEvents.DATA_IMAP_OPERATION_STARTED);
- try (NetworkWrapper network = VvmNetworkRequest.getNetwork(config, phoneAccount)) {
+ // DATA_IMAP_OPERATION_STARTED posting should not be deferred. This event clears all data
+ // channel errors, which should happen when the task starts, not when it ends. It is the
+ // "Sync in progress..." status.
+ config.handleEvent(VoicemailStatus.edit(mContext, phoneAccount),
+ OmtpEvents.DATA_IMAP_OPERATION_STARTED);
+ try (NetworkWrapper network = VvmNetworkRequest.getNetwork(config, phoneAccount, status)) {
if (network == null) {
VvmLog.e(TAG, "unable to acquire network");
task.fail();
return;
}
- doSync(task, network.get(), phoneAccount, voicemail, action);
+ doSync(task, network.get(), phoneAccount, voicemail, action, status);
} catch (RequestFailedException e) {
- config.handleEvent(OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
+ config.handleEvent(status, OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
task.fail();
}
}
private void doSync(BaseTask task, Network network, PhoneAccountHandle phoneAccount,
- Voicemail voicemail, String action) {
- try(ImapHelper imapHelper = new ImapHelper(mContext, phoneAccount, network)) {
+ Voicemail voicemail, String action, VoicemailStatus.Editor status) {
+ try (ImapHelper imapHelper = new ImapHelper(mContext, phoneAccount, network, status)) {
boolean success;
if (voicemail == null) {
success = syncAll(action, imapHelper, phoneAccount);
diff --git a/src/com/android/phone/vvm/omtp/sync/SyncOneTask.java b/src/com/android/phone/vvm/omtp/sync/SyncOneTask.java
index 165f043..510efc7 100644
--- a/src/com/android/phone/vvm/omtp/sync/SyncOneTask.java
+++ b/src/com/android/phone/vvm/omtp/sync/SyncOneTask.java
@@ -20,7 +20,7 @@
import android.content.Intent;
import android.telecom.PhoneAccountHandle;
import android.telecom.Voicemail;
-
+import com.android.phone.VoicemailStatus;
import com.android.phone.vvm.omtp.scheduling.BaseTask;
import com.android.phone.vvm.omtp.scheduling.RetryPolicy;
import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
@@ -67,7 +67,8 @@
@Override
public void onExecuteInBackgroundThread() {
OmtpVvmSyncService service = new OmtpVvmSyncService(getContext());
- service.sync(this, mSyncType, mPhone, mVoicemail);
+ service.sync(this, mSyncType, mPhone, mVoicemail,
+ VoicemailStatus.edit(getContext(), mPhone));
}
@Override
diff --git a/src/com/android/phone/vvm/omtp/sync/SyncTask.java b/src/com/android/phone/vvm/omtp/sync/SyncTask.java
index 0d91c5c..7374ee6 100644
--- a/src/com/android/phone/vvm/omtp/sync/SyncTask.java
+++ b/src/com/android/phone/vvm/omtp/sync/SyncTask.java
@@ -37,6 +37,8 @@
private static final String EXTRA_PHONE_ACCOUNT_HANDLE = "extra_phone_account_handle";
private static final String EXTRA_SYNC_TYPE = "extra_sync_type";
+ private final RetryPolicy mRetryPolicy;
+
private PhoneAccountHandle mPhone;
private String mSyncType;
@@ -50,7 +52,8 @@
public SyncTask() {
super(TASK_SYNC);
- addPolicy(new RetryPolicy(RETRY_TIMES, RETRY_INTERVAL_MILLIS));
+ mRetryPolicy = new RetryPolicy(RETRY_TIMES, RETRY_INTERVAL_MILLIS);
+ addPolicy(mRetryPolicy);
addPolicy(new MinimalIntervalPolicy(MINIMAL_INTERVAL_MILLIS));
}
@@ -63,7 +66,7 @@
@Override
public void onExecuteInBackgroundThread() {
OmtpVvmSyncService service = new OmtpVvmSyncService(getContext());
- service.sync(this, mSyncType, mPhone, null);
+ service.sync(this, mSyncType, mPhone, null, mRetryPolicy.getVoicemailStatusEditor());
}
@Override
diff --git a/src/com/android/phone/vvm/omtp/sync/UploadTask.java b/src/com/android/phone/vvm/omtp/sync/UploadTask.java
index afdee58..7945c08 100644
--- a/src/com/android/phone/vvm/omtp/sync/UploadTask.java
+++ b/src/com/android/phone/vvm/omtp/sync/UploadTask.java
@@ -18,7 +18,7 @@
import android.content.Context;
import android.content.Intent;
-
+import com.android.phone.VoicemailStatus;
import com.android.phone.vvm.omtp.scheduling.BaseTask;
import com.android.phone.vvm.omtp.scheduling.PostponePolicy;
@@ -44,6 +44,7 @@
@Override
public void onExecuteInBackgroundThread() {
OmtpVvmSyncService service = new OmtpVvmSyncService(getContext());
- service.sync(this, OmtpVvmSyncService.SYNC_UPLOAD_ONLY, null, null);
+ service.sync(this, OmtpVvmSyncService.SYNC_UPLOAD_ONLY, null, null,
+ VoicemailStatus.edit(getContext(), getSubId()));
}
}
diff --git a/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequest.java b/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequest.java
index 798950d..3bdb45b 100644
--- a/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequest.java
+++ b/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequest.java
@@ -19,6 +19,7 @@
import android.net.Network;
import android.support.annotation.NonNull;
import android.telecom.PhoneAccountHandle;
+import com.android.phone.VoicemailStatus;
import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
import com.android.phone.vvm.omtp.VvmLog;
import java.io.Closeable;
@@ -67,8 +68,9 @@
@NonNull
public static NetworkWrapper getNetwork(OmtpVvmCarrierConfigHelper config,
- PhoneAccountHandle handle) throws RequestFailedException {
- FutureNetworkRequestCallback callback = new FutureNetworkRequestCallback(config, handle);
+ PhoneAccountHandle handle, VoicemailStatus.Editor status) throws RequestFailedException {
+ FutureNetworkRequestCallback callback = new FutureNetworkRequestCallback(config, handle,
+ status);
callback.requestNetwork();
try {
return callback.getFuture().get();
@@ -88,8 +90,8 @@
private final CompletableFuture<NetworkWrapper> mFuture = new CompletableFuture<>();
public FutureNetworkRequestCallback(OmtpVvmCarrierConfigHelper config,
- PhoneAccountHandle phoneAccount) {
- super(config, phoneAccount);
+ PhoneAccountHandle phoneAccount, VoicemailStatus.Editor status) {
+ super(config, phoneAccount, status);
}
public Future<NetworkWrapper> getFuture() {
diff --git a/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java b/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java
index 11526ce..787fdcd 100644
--- a/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java
+++ b/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java
@@ -24,8 +24,8 @@
import android.os.Handler;
import android.os.Looper;
import android.telecom.PhoneAccountHandle;
-
import com.android.phone.PhoneUtils;
+import com.android.phone.VoicemailStatus;
import com.android.phone.vvm.omtp.OmtpEvents;
import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
import com.android.phone.vvm.omtp.VvmLog;
@@ -50,26 +50,34 @@
private ConnectivityManager mConnectivityManager;
private final OmtpVvmCarrierConfigHelper mCarrierConfigHelper;
private final int mSubId;
+ private final VoicemailStatus.Editor mStatus;
private boolean mRequestSent = false;
private boolean mResultReceived = false;
- public VvmNetworkRequestCallback(Context context, PhoneAccountHandle phoneAccount) {
+ public VvmNetworkRequestCallback(Context context, PhoneAccountHandle phoneAccount,
+ VoicemailStatus.Editor status) {
mContext = context;
mPhoneAccount = phoneAccount;
mSubId = PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccount);
+ mStatus = status;
mCarrierConfigHelper = new OmtpVvmCarrierConfigHelper(context, mSubId);
mNetworkRequest = createNetworkRequest();
}
public VvmNetworkRequestCallback(OmtpVvmCarrierConfigHelper config,
- PhoneAccountHandle phoneAccount) {
+ PhoneAccountHandle phoneAccount, VoicemailStatus.Editor status) {
mContext = config.getContext();
mPhoneAccount = phoneAccount;
mSubId = config.getSubId();
+ mStatus = status;
mCarrierConfigHelper = config;
mNetworkRequest = createNetworkRequest();
}
+ public VoicemailStatus.Editor getVoicemailStatusEditor() {
+ return mStatus;
+ }
+
/**
* @return NetworkRequest for a proper transport type. Use only cellular network if the carrier
* requires it. Otherwise use whatever available.
@@ -154,9 +162,10 @@
public void onFailed(String reason) {
VvmLog.d(TAG, "onFailed: " + reason);
if (mCarrierConfigHelper.isCellularDataRequired()) {
- mCarrierConfigHelper.handleEvent(OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
+ mCarrierConfigHelper
+ .handleEvent(mStatus, OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
} else {
- mCarrierConfigHelper.handleEvent(OmtpEvents.DATA_NO_CONNECTION);
+ mCarrierConfigHelper.handleEvent(mStatus, OmtpEvents.DATA_NO_CONNECTION);
}
releaseNetwork();
}