summaryrefslogtreecommitdiff
path: root/java/com/android/voicemailomtp/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/voicemailomtp/protocol')
-rw-r--r--java/com/android/voicemailomtp/protocol/CvvmProtocol.java59
-rw-r--r--java/com/android/voicemailomtp/protocol/OmtpProtocol.java37
-rw-r--r--java/com/android/voicemailomtp/protocol/ProtocolHelper.java43
-rw-r--r--java/com/android/voicemailomtp/protocol/VisualVoicemailProtocol.java100
-rw-r--r--java/com/android/voicemailomtp/protocol/VisualVoicemailProtocolFactory.java47
-rw-r--r--java/com/android/voicemailomtp/protocol/Vvm3EventHandler.java271
-rw-r--r--java/com/android/voicemailomtp/protocol/Vvm3Protocol.java301
-rw-r--r--java/com/android/voicemailomtp/protocol/Vvm3Subscriber.java326
8 files changed, 0 insertions, 1184 deletions
diff --git a/java/com/android/voicemailomtp/protocol/CvvmProtocol.java b/java/com/android/voicemailomtp/protocol/CvvmProtocol.java
deleted file mode 100644
index 48ed99709..000000000
--- a/java/com/android/voicemailomtp/protocol/CvvmProtocol.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.voicemailomtp.protocol;
-
-import android.content.Context;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.SmsManager;
-
-import com.android.voicemailomtp.OmtpConstants;
-import com.android.voicemailomtp.sms.OmtpCvvmMessageSender;
-import com.android.voicemailomtp.sms.OmtpMessageSender;
-
-/**
- * A flavor of OMTP protocol with a different mobile originated (MO) format
- *
- * Used by carriers such as T-Mobile
- */
-public class CvvmProtocol extends VisualVoicemailProtocol {
-
- private static String IMAP_CHANGE_TUI_PWD_FORMAT = "CHANGE_TUI_PWD PWD=%1$s OLD_PWD=%2$s";
- private static String IMAP_CHANGE_VM_LANG_FORMAT = "CHANGE_VM_LANG Lang=%1$s";
- private static String IMAP_CLOSE_NUT = "CLOSE_NUT";
-
- @Override
- public OmtpMessageSender createMessageSender(Context context,
- PhoneAccountHandle phoneAccountHandle, short applicationPort,
- String destinationNumber) {
- return new OmtpCvvmMessageSender(context, phoneAccountHandle, applicationPort,
- destinationNumber);
- }
-
- @Override
- public String getCommand(String command) {
- if (command == OmtpConstants.IMAP_CHANGE_TUI_PWD_FORMAT) {
- return IMAP_CHANGE_TUI_PWD_FORMAT;
- }
- if (command == OmtpConstants.IMAP_CLOSE_NUT) {
- return IMAP_CLOSE_NUT;
- }
- if (command == OmtpConstants.IMAP_CHANGE_VM_LANG_FORMAT) {
- return IMAP_CHANGE_VM_LANG_FORMAT;
- }
- return super.getCommand(command);
- }
-}
diff --git a/java/com/android/voicemailomtp/protocol/OmtpProtocol.java b/java/com/android/voicemailomtp/protocol/OmtpProtocol.java
deleted file mode 100644
index d88a23285..000000000
--- a/java/com/android/voicemailomtp/protocol/OmtpProtocol.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.voicemailomtp.protocol;
-
-import android.content.Context;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.SmsManager;
-
-import com.android.voicemailomtp.OmtpConstants;
-import com.android.voicemailomtp.sms.OmtpMessageSender;
-import com.android.voicemailomtp.sms.OmtpStandardMessageSender;
-
-public class OmtpProtocol extends VisualVoicemailProtocol {
-
- @Override
- public OmtpMessageSender createMessageSender(Context context,
- PhoneAccountHandle phoneAccountHandle, short applicationPort,
- String destinationNumber) {
- return new OmtpStandardMessageSender(context, phoneAccountHandle, applicationPort,
- destinationNumber,
- null, OmtpConstants.PROTOCOL_VERSION1_1, null);
- }
-}
diff --git a/java/com/android/voicemailomtp/protocol/ProtocolHelper.java b/java/com/android/voicemailomtp/protocol/ProtocolHelper.java
deleted file mode 100644
index 4fca199bf..000000000
--- a/java/com/android/voicemailomtp/protocol/ProtocolHelper.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.voicemailomtp.protocol;
-
-import android.telephony.SmsManager;
-import android.text.TextUtils;
-
-import com.android.voicemailomtp.OmtpVvmCarrierConfigHelper;
-import com.android.voicemailomtp.VvmLog;
-import com.android.voicemailomtp.sms.OmtpMessageSender;
-
-public class ProtocolHelper {
-
- private static final String TAG = "ProtocolHelper";
-
- public static OmtpMessageSender getMessageSender(VisualVoicemailProtocol protocol,
- OmtpVvmCarrierConfigHelper config) {
-
- int applicationPort = config.getApplicationPort();
- String destinationNumber = config.getDestinationNumber();
- if (TextUtils.isEmpty(destinationNumber)) {
- VvmLog.w(TAG, "No destination number for this carrier.");
- return null;
- }
-
- return protocol.createMessageSender(config.getContext(), config.getPhoneAccountHandle(),
- (short) applicationPort, destinationNumber);
- }
-}
diff --git a/java/com/android/voicemailomtp/protocol/VisualVoicemailProtocol.java b/java/com/android/voicemailomtp/protocol/VisualVoicemailProtocol.java
deleted file mode 100644
index 9ff2ed167..000000000
--- a/java/com/android/voicemailomtp/protocol/VisualVoicemailProtocol.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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.voicemailomtp.protocol;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.SmsManager;
-import com.android.voicemailomtp.ActivationTask;
-import com.android.voicemailomtp.DefaultOmtpEventHandler;
-import com.android.voicemailomtp.OmtpEvents;
-import com.android.voicemailomtp.OmtpVvmCarrierConfigHelper;
-import com.android.voicemailomtp.VoicemailStatus;
-import com.android.voicemailomtp.sms.OmtpMessageSender;
-import com.android.voicemailomtp.sms.StatusMessage;
-
-public abstract class VisualVoicemailProtocol {
-
- /**
- * Activation should cause the carrier to respond with a STATUS SMS.
- */
- public void startActivation(OmtpVvmCarrierConfigHelper config, PendingIntent sentIntent) {
- OmtpMessageSender messageSender = ProtocolHelper.getMessageSender(this, config);
- if (messageSender != null) {
- messageSender.requestVvmActivation(sentIntent);
- }
- }
-
- public void startDeactivation(OmtpVvmCarrierConfigHelper config) {
- OmtpMessageSender messageSender = ProtocolHelper.getMessageSender(this, config);
- if (messageSender != null) {
- messageSender.requestVvmDeactivation(null);
- }
- }
-
- public boolean supportsProvisioning() {
- return false;
- }
-
- public void startProvisioning(ActivationTask task, PhoneAccountHandle handle,
- OmtpVvmCarrierConfigHelper config, VoicemailStatus.Editor editor, StatusMessage message,
- Bundle data) {
- // Do nothing
- }
-
- public void requestStatus(OmtpVvmCarrierConfigHelper config,
- @Nullable PendingIntent sentIntent) {
- OmtpMessageSender messageSender = ProtocolHelper.getMessageSender(this, config);
- if (messageSender != null) {
- messageSender.requestVvmStatus(sentIntent);
- }
- }
-
- public abstract OmtpMessageSender createMessageSender(Context context,
- PhoneAccountHandle phoneAccountHandle,
- short applicationPort, String destinationNumber);
-
- /**
- * Translate an OMTP IMAP command to the protocol specific one. For example, changing the TUI
- * password on OMTP is XCHANGE_TUI_PWD, but on CVVM and VVM3 it is CHANGE_TUI_PWD.
- *
- * @param command A String command in {@link com.android.voicemailomtp.OmtpConstants}, the exact
- * instance should be used instead of its' value.
- * @returns Translated command, or {@code null} if not available in this protocol
- */
- public String getCommand(String command) {
- return command;
- }
-
- public void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
- VoicemailStatus.Editor status, OmtpEvents event) {
- DefaultOmtpEventHandler.handleEvent(context, config, status, event);
- }
-
- /**
- * Given an VVM SMS with an unknown {@code event}, let the protocol attempt to translate it into
- * an equivalent STATUS SMS. Returns {@code null} if it cannot be translated.
- */
- @Nullable
- public Bundle translateStatusSmsBundle(OmtpVvmCarrierConfigHelper config, String event,
- Bundle data) {
- return null;
- }
-}
diff --git a/java/com/android/voicemailomtp/protocol/VisualVoicemailProtocolFactory.java b/java/com/android/voicemailomtp/protocol/VisualVoicemailProtocolFactory.java
deleted file mode 100644
index b74f503c6..000000000
--- a/java/com/android/voicemailomtp/protocol/VisualVoicemailProtocolFactory.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.voicemailomtp.protocol;
-
-import android.content.res.Resources;
-import android.support.annotation.Nullable;
-import android.telephony.TelephonyManager;
-import com.android.voicemailomtp.VvmLog;
-
-public class VisualVoicemailProtocolFactory {
-
- private static final String TAG = "VvmProtocolFactory";
-
- private static final String VVM_TYPE_VVM3 = "vvm_type_vvm3";
-
- @Nullable
- public static VisualVoicemailProtocol create(Resources resources, String type) {
- if (type == null) {
- return null;
- }
- switch (type) {
- case TelephonyManager.VVM_TYPE_OMTP:
- return new OmtpProtocol();
- case TelephonyManager.VVM_TYPE_CVVM:
- return new CvvmProtocol();
- case VVM_TYPE_VVM3:
- return new Vvm3Protocol();
- default:
- VvmLog.e(TAG, "Unexpected visual voicemail type: " + type);
- }
- return null;
- }
-}
diff --git a/java/com/android/voicemailomtp/protocol/Vvm3EventHandler.java b/java/com/android/voicemailomtp/protocol/Vvm3EventHandler.java
deleted file mode 100644
index 72646386c..000000000
--- a/java/com/android/voicemailomtp/protocol/Vvm3EventHandler.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * 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.voicemailomtp.protocol;
-
-import android.content.Context;
-import android.support.annotation.IntDef;
-import android.util.Log;
-import com.android.voicemailomtp.DefaultOmtpEventHandler;
-import com.android.voicemailomtp.OmtpEvents;
-import com.android.voicemailomtp.OmtpEvents.Type;
-import com.android.voicemailomtp.OmtpVvmCarrierConfigHelper;
-import com.android.voicemailomtp.VoicemailStatus;
-import com.android.voicemailomtp.settings.VoicemailChangePinActivity;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Handles {@link OmtpEvents} when {@link Vvm3Protocol} is being used. This handler writes custom
- * error codes into the voicemail status table so support on the dialer side is required.
- *
- * TODO(b/29577838) disable VVM3 by default so support on system dialer can be ensured.
- */
-public class Vvm3EventHandler {
-
- private static final String TAG = "Vvm3EventHandler";
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({VMS_DNS_FAILURE, VMG_DNS_FAILURE, SPG_DNS_FAILURE, VMS_NO_CELLULAR, VMG_NO_CELLULAR,
- SPG_NO_CELLULAR, VMS_TIMEOUT, VMG_TIMEOUT, STATUS_SMS_TIMEOUT, SUBSCRIBER_BLOCKED,
- UNKNOWN_USER, UNKNOWN_DEVICE, INVALID_PASSWORD, MAILBOX_NOT_INITIALIZED,
- SERVICE_NOT_PROVISIONED, SERVICE_NOT_ACTIVATED, USER_BLOCKED, IMAP_GETQUOTA_ERROR,
- IMAP_SELECT_ERROR, IMAP_ERROR, VMG_INTERNAL_ERROR, VMG_DB_ERROR,
- VMG_COMMUNICATION_ERROR, SPG_URL_NOT_FOUND, VMG_UNKNOWN_ERROR, PIN_NOT_SET})
- public @interface ErrorCode {
-
- }
-
- public static final int VMS_DNS_FAILURE = -9001;
- public static final int VMG_DNS_FAILURE = -9002;
- public static final int SPG_DNS_FAILURE = -9003;
- public static final int VMS_NO_CELLULAR = -9004;
- public static final int VMG_NO_CELLULAR = -9005;
- public static final int SPG_NO_CELLULAR = -9006;
- public static final int VMS_TIMEOUT = -9007;
- public static final int VMG_TIMEOUT = -9008;
- public static final int STATUS_SMS_TIMEOUT = -9009;
-
- public static final int SUBSCRIBER_BLOCKED = -9990;
- public static final int UNKNOWN_USER = -9991;
- public static final int UNKNOWN_DEVICE = -9992;
- public static final int INVALID_PASSWORD = -9993;
- public static final int MAILBOX_NOT_INITIALIZED = -9994;
- public static final int SERVICE_NOT_PROVISIONED = -9995;
- public static final int SERVICE_NOT_ACTIVATED = -9996;
- public static final int USER_BLOCKED = -9998;
- public static final int IMAP_GETQUOTA_ERROR = -9997;
- public static final int IMAP_SELECT_ERROR = -9989;
- public static final int IMAP_ERROR = -9999;
-
- public static final int VMG_INTERNAL_ERROR = -101;
- public static final int VMG_DB_ERROR = -102;
- public static final int VMG_COMMUNICATION_ERROR = -103;
- public static final int SPG_URL_NOT_FOUND = -301;
-
- // Non VVM3 codes:
- public static final int VMG_UNKNOWN_ERROR = -1;
- public static final int PIN_NOT_SET = -100;
- // STATUS SMS returned st=U and rc!=2. The user cannot be provisioned and must contact customer
- // support.
- public static final int SUBSCRIBER_UNKNOWN = -99;
-
-
- public static void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
- VoicemailStatus.Editor status, OmtpEvents event) {
- boolean handled = false;
- switch (event.getType()) {
- case Type.CONFIGURATION:
- handled = handleConfigurationEvent(context, status, event);
- break;
- case Type.DATA_CHANNEL:
- handled = handleDataChannelEvent(status, event);
- break;
- case Type.NOTIFICATION_CHANNEL:
- handled = handleNotificationChannelEvent(status, event);
- break;
- case Type.OTHER:
- handled = handleOtherEvent(status, event);
- break;
- default:
- Log.wtf(TAG, "invalid event type " + event.getType() + " for " + event);
- }
- if (!handled) {
- DefaultOmtpEventHandler.handleEvent(context, config, status, event);
- }
- }
-
- private static boolean handleConfigurationEvent(Context context, VoicemailStatus.Editor status,
- OmtpEvents event) {
- switch (event) {
- case CONFIG_REQUEST_STATUS_SUCCESS:
- if (status.getPhoneAccountHandle() == null) {
- // This should never happen.
- Log.e(TAG, "status editor has null phone account handle");
- return true;
- }
-
- if (!VoicemailChangePinActivity
- .isDefaultOldPinSet(context, status.getPhoneAccountHandle())) {
- return false;
- } else {
- postError(status, PIN_NOT_SET);
- }
- break;
- case CONFIG_DEFAULT_PIN_REPLACED:
- postError(status, PIN_NOT_SET);
- break;
- case CONFIG_STATUS_SMS_TIME_OUT:
- postError(status, STATUS_SMS_TIMEOUT);
- break;
- default:
- return false;
- }
- return true;
- }
-
- 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(status, VMS_NO_CELLULAR);
- break;
- case DATA_SSL_INVALID_HOST_NAME:
- case DATA_CANNOT_ESTABLISH_SSL_SESSION:
- case DATA_IOE_ON_OPEN:
- postError(status, VMS_TIMEOUT);
- break;
- case DATA_CANNOT_RESOLVE_HOST_ON_NETWORK:
- postError(status, VMS_DNS_FAILURE);
- break;
- case DATA_BAD_IMAP_CREDENTIAL:
- postError(status, IMAP_ERROR);
- break;
- case DATA_AUTH_UNKNOWN_USER:
- postError(status, UNKNOWN_USER);
- break;
- case DATA_AUTH_UNKNOWN_DEVICE:
- postError(status, UNKNOWN_DEVICE);
- break;
- case DATA_AUTH_INVALID_PASSWORD:
- postError(status, INVALID_PASSWORD);
- break;
- case DATA_AUTH_MAILBOX_NOT_INITIALIZED:
- postError(status, MAILBOX_NOT_INITIALIZED);
- break;
- case DATA_AUTH_SERVICE_NOT_PROVISIONED:
- postError(status, SERVICE_NOT_PROVISIONED);
- break;
- case DATA_AUTH_SERVICE_NOT_ACTIVATED:
- postError(status, SERVICE_NOT_ACTIVATED);
- break;
- case DATA_AUTH_USER_IS_BLOCKED:
- postError(status, USER_BLOCKED);
- break;
- case DATA_REJECTED_SERVER_RESPONSE:
- case DATA_INVALID_INITIAL_SERVER_RESPONSE:
- case DATA_SSL_EXCEPTION:
- postError(status, IMAP_ERROR);
- break;
- default:
- return false;
- }
- return true;
- }
-
- private static boolean handleNotificationChannelEvent(VoicemailStatus.Editor status,
- OmtpEvents event) {
- return false;
- }
-
- private static boolean handleOtherEvent(VoicemailStatus.Editor status,
- OmtpEvents event) {
- switch (event) {
- case VVM3_NEW_USER_SETUP_FAILED:
- postError(status, MAILBOX_NOT_INITIALIZED);
- break;
- case VVM3_VMG_DNS_FAILURE:
- postError(status, VMG_DNS_FAILURE);
- break;
- case VVM3_SPG_DNS_FAILURE:
- postError(status, SPG_DNS_FAILURE);
- break;
- case VVM3_VMG_CONNECTION_FAILED:
- postError(status, VMG_NO_CELLULAR);
- break;
- case VVM3_SPG_CONNECTION_FAILED:
- postError(status, SPG_NO_CELLULAR);
- break;
- case VVM3_VMG_TIMEOUT:
- postError(status, VMG_TIMEOUT);
- break;
- case VVM3_SUBSCRIBER_PROVISIONED:
- postError(status, SERVICE_NOT_ACTIVATED);
- break;
- case VVM3_SUBSCRIBER_BLOCKED:
- postError(status, SUBSCRIBER_BLOCKED);
- break;
- case VVM3_SUBSCRIBER_UNKNOWN:
- postError(status, SUBSCRIBER_UNKNOWN);
- break;
- default:
- return false;
- }
- return true;
- }
-
- private static void postError(VoicemailStatus.Editor editor, @ErrorCode int errorCode) {
- switch (errorCode) {
- case VMG_DNS_FAILURE:
- case SPG_DNS_FAILURE:
- case VMG_NO_CELLULAR:
- case SPG_NO_CELLULAR:
- case VMG_TIMEOUT:
- case SUBSCRIBER_BLOCKED:
- case UNKNOWN_USER:
- case UNKNOWN_DEVICE:
- case INVALID_PASSWORD:
- case MAILBOX_NOT_INITIALIZED:
- case SERVICE_NOT_PROVISIONED:
- case SERVICE_NOT_ACTIVATED:
- case USER_BLOCKED:
- case VMG_UNKNOWN_ERROR:
- case SPG_URL_NOT_FOUND:
- case VMG_INTERNAL_ERROR:
- case VMG_DB_ERROR:
- case VMG_COMMUNICATION_ERROR:
- case PIN_NOT_SET:
- case SUBSCRIBER_UNKNOWN:
- editor.setConfigurationState(errorCode);
- break;
- case VMS_NO_CELLULAR:
- case VMS_DNS_FAILURE:
- case VMS_TIMEOUT:
- case IMAP_GETQUOTA_ERROR:
- case IMAP_SELECT_ERROR:
- case IMAP_ERROR:
- editor.setDataChannelState(errorCode);
- break;
- case STATUS_SMS_TIMEOUT:
- editor.setNotificationChannelState(errorCode);
- break;
- default:
- Log.wtf(TAG, "unknown error code: " + errorCode);
- }
- editor.apply();
- }
-}
diff --git a/java/com/android/voicemailomtp/protocol/Vvm3Protocol.java b/java/com/android/voicemailomtp/protocol/Vvm3Protocol.java
deleted file mode 100644
index 652d1010a..000000000
--- a/java/com/android/voicemailomtp/protocol/Vvm3Protocol.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * 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.voicemailomtp.protocol;
-
-import android.annotation.TargetApi;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.net.Network;
-import android.os.Build.VERSION_CODES;
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.telecom.PhoneAccountHandle;
-import android.text.TextUtils;
-import com.android.voicemailomtp.ActivationTask;
-import com.android.voicemailomtp.OmtpConstants;
-import com.android.voicemailomtp.OmtpEvents;
-import com.android.voicemailomtp.OmtpVvmCarrierConfigHelper;
-import com.android.voicemailomtp.VisualVoicemailPreferences;
-import com.android.voicemailomtp.VoicemailStatus;
-import com.android.voicemailomtp.VvmLog;
-import com.android.voicemailomtp.imap.ImapHelper;
-import com.android.voicemailomtp.imap.ImapHelper.InitializingException;
-import com.android.voicemailomtp.mail.MessagingException;
-import com.android.voicemailomtp.settings.VisualVoicemailSettingsUtil;
-import com.android.voicemailomtp.settings.VoicemailChangePinActivity;
-import com.android.voicemailomtp.sms.OmtpMessageSender;
-import com.android.voicemailomtp.sms.StatusMessage;
-import com.android.voicemailomtp.sms.Vvm3MessageSender;
-import com.android.voicemailomtp.sync.VvmNetworkRequest;
-import com.android.voicemailomtp.sync.VvmNetworkRequest.NetworkWrapper;
-import com.android.voicemailomtp.sync.VvmNetworkRequest.RequestFailedException;
-import java.io.IOException;
-import java.security.SecureRandom;
-import java.util.Locale;
-
-/**
- * A flavor of OMTP protocol with a different provisioning process
- *
- * <p>Used by carriers such as Verizon Wireless
- */
-@TargetApi(VERSION_CODES.CUR_DEVELOPMENT)
-public class Vvm3Protocol extends VisualVoicemailProtocol {
-
- private static final String TAG = "Vvm3Protocol";
-
- private static final String SMS_EVENT_UNRECOGNIZED = "UNRECOGNIZED";
- private static final String SMS_EVENT_UNRECOGNIZED_CMD = "cmd";
- private static final String SMS_EVENT_UNRECOGNIZED_STATUS = "STATUS";
- private static final String DEFAULT_VMG_URL_KEY = "default_vmg_url";
-
- private static final String IMAP_CHANGE_TUI_PWD_FORMAT = "CHANGE_TUI_PWD PWD=%1$s OLD_PWD=%2$s";
- private static final String IMAP_CHANGE_VM_LANG_FORMAT = "CHANGE_VM_LANG Lang=%1$s";
- private static final String IMAP_CLOSE_NUT = "CLOSE_NUT";
-
- private static final String ISO639_Spanish = "es";
-
- /**
- * For VVM3, if the STATUS SMS returns {@link StatusMessage#getProvisioningStatus()} of {@link
- * OmtpConstants#SUBSCRIBER_UNKNOWN} and {@link StatusMessage#getReturnCode()} of this value,
- * the user can self-provision visual voicemail service. For other response codes, the user must
- * contact customer support to resolve the issue.
- */
- private static final String VVM3_UNKNOWN_SUBSCRIBER_CAN_SUBSCRIBE_RESPONSE_CODE = "2";
-
- // Default prompt level when using the telephone user interface.
- // Standard prompt when the user call into the voicemail, and no prompts when someone else is
- // leaving a voicemail.
- private static final String VVM3_VM_LANGUAGE_ENGLISH_STANDARD_NO_GUEST_PROMPTS = "5";
- private static final String VVM3_VM_LANGUAGE_SPANISH_STANDARD_NO_GUEST_PROMPTS = "6";
-
- private static final int DEFAULT_PIN_LENGTH = 6;
-
- @Override
- public void startActivation(OmtpVvmCarrierConfigHelper config,
- @Nullable PendingIntent sentIntent) {
- // VVM3 does not support activation SMS.
- // Send a status request which will start the provisioning process if the user is not
- // provisioned.
- VvmLog.i(TAG, "Activating");
- config.requestStatus(sentIntent);
- }
-
- @Override
- public void startDeactivation(OmtpVvmCarrierConfigHelper config) {
- // VVM3 does not support deactivation.
- // do nothing.
- }
-
- @Override
- public boolean supportsProvisioning() {
- return true;
- }
-
- @Override
- public void startProvisioning(ActivationTask task, PhoneAccountHandle phoneAccountHandle,
- 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, status, data).subscribe();
- } else {
- config.handleEvent(status, OmtpEvents.VVM3_SUBSCRIBER_UNKNOWN);
- }
- } else if (OmtpConstants.SUBSCRIBER_NEW.equals(message.getProvisioningStatus())) {
- VvmLog.i(TAG, "setting up new user");
- // Save the IMAP credentials in preferences so they are persistent and can be retrieved.
- VisualVoicemailPreferences prefs =
- new VisualVoicemailPreferences(config.getContext(), phoneAccountHandle);
- message.putStatus(prefs.edit()).apply();
-
- 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(status, OmtpEvents.VVM3_SUBSCRIBER_BLOCKED);
- }
- }
-
- @Override
- public OmtpMessageSender createMessageSender(Context context,
- PhoneAccountHandle phoneAccountHandle, short applicationPort,
- String destinationNumber) {
- return new Vvm3MessageSender(context, phoneAccountHandle, applicationPort,
- destinationNumber);
- }
-
- @Override
- public void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
- VoicemailStatus.Editor status, OmtpEvents event) {
- Vvm3EventHandler.handleEvent(context, config, status, event);
- }
-
- @Override
- public String getCommand(String command) {
- if (command == OmtpConstants.IMAP_CHANGE_TUI_PWD_FORMAT) {
- return IMAP_CHANGE_TUI_PWD_FORMAT;
- }
- if (command == OmtpConstants.IMAP_CLOSE_NUT) {
- return IMAP_CLOSE_NUT;
- }
- if (command == OmtpConstants.IMAP_CHANGE_VM_LANG_FORMAT) {
- return IMAP_CHANGE_VM_LANG_FORMAT;
- }
- return super.getCommand(command);
- }
-
- @Override
- public Bundle translateStatusSmsBundle(OmtpVvmCarrierConfigHelper config, String event,
- Bundle data) {
- // UNRECOGNIZED?cmd=STATUS is the response of a STATUS request when the user is provisioned
- // with iPhone visual voicemail without VoLTE. Translate it into an unprovisioned status
- // so provisioning can be done.
- if (!SMS_EVENT_UNRECOGNIZED.equals(event)) {
- return null;
- }
- if (!SMS_EVENT_UNRECOGNIZED_STATUS.equals(data.getString(SMS_EVENT_UNRECOGNIZED_CMD))) {
- return null;
- }
- Bundle bundle = new Bundle();
- bundle.putString(OmtpConstants.PROVISIONING_STATUS, OmtpConstants.SUBSCRIBER_UNKNOWN);
- bundle.putString(OmtpConstants.RETURN_CODE,
- VVM3_UNKNOWN_SUBSCRIBER_CAN_SUBSCRIBE_RESPONSE_CODE);
- String vmgUrl = config.getString(DEFAULT_VMG_URL_KEY);
- if (TextUtils.isEmpty(vmgUrl)) {
- VvmLog.e(TAG, "Unable to translate STATUS SMS: VMG URL is not set in config");
- return null;
- }
- bundle.putString(Vvm3Subscriber.VMG_URL_KEY, vmgUrl);
- VvmLog.i(TAG, "UNRECOGNIZED?cmd=STATUS translated into unprovisioned STATUS SMS");
- return bundle;
- }
-
- private void startProvisionNewUser(ActivationTask task, PhoneAccountHandle 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, status)) {
- // VVM3 has inconsistent error language code to OMTP. Just issue a raw command
- // here.
- // TODO(b/29082671): use LocaleList
- if (Locale.getDefault().getLanguage()
- .equals(new Locale(ISO639_Spanish).getLanguage())) {
- // Spanish
- helper.changeVoicemailTuiLanguage(
- VVM3_VM_LANGUAGE_SPANISH_STANDARD_NO_GUEST_PROMPTS);
- } else {
- // English
- helper.changeVoicemailTuiLanguage(
- VVM3_VM_LANGUAGE_ENGLISH_STANDARD_NO_GUEST_PROMPTS);
- }
- VvmLog.i(TAG, "new user: language set");
-
- if (setPin(config.getContext(), phoneAccountHandle, helper, message)) {
- // Only close new user tutorial if the PIN has been changed.
- helper.closeNewUserTutorial();
- VvmLog.i(TAG, "new user: NUT closed");
-
- config.requestStatus(null);
- }
- } catch (InitializingException | MessagingException | IOException e) {
- config.handleEvent(status, OmtpEvents.VVM3_NEW_USER_SETUP_FAILED);
- task.fail();
- VvmLog.e(TAG, e.toString());
- }
- } catch (RequestFailedException e) {
- config.handleEvent(status, OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
- task.fail();
- }
-
- }
-
-
- private static boolean setPin(Context context, PhoneAccountHandle phoneAccountHandle,
- ImapHelper helper, StatusMessage message)
- throws IOException, MessagingException {
- String defaultPin = getDefaultPin(message);
- if (defaultPin == null) {
- VvmLog.i(TAG, "cannot generate default PIN");
- return false;
- }
-
- if (VoicemailChangePinActivity.isDefaultOldPinSet(context, phoneAccountHandle)) {
- // The pin was already set
- VvmLog.i(TAG, "PIN already set");
- return true;
- }
- String newPin = generatePin(getMinimumPinLength(context, phoneAccountHandle));
- if (helper.changePin(defaultPin, newPin) == OmtpConstants.CHANGE_PIN_SUCCESS) {
- VoicemailChangePinActivity.setDefaultOldPIN(context, phoneAccountHandle, newPin);
- helper.handleEvent(OmtpEvents.CONFIG_DEFAULT_PIN_REPLACED);
- }
- VvmLog.i(TAG, "new user: PIN set");
- return true;
- }
-
- @Nullable
- private static String getDefaultPin(StatusMessage message) {
- // The IMAP username is [phone number]@example.com
- String username = message.getImapUserName();
- try {
- String number = username.substring(0, username.indexOf('@'));
- if (number.length() < 4) {
- VvmLog.e(TAG, "unable to extract number from IMAP username");
- return null;
- }
- return "1" + number.substring(number.length() - 4);
- } catch (StringIndexOutOfBoundsException e) {
- VvmLog.e(TAG, "unable to extract number from IMAP username");
- return null;
- }
-
- }
-
- private static int getMinimumPinLength(Context context, PhoneAccountHandle phoneAccountHandle) {
- VisualVoicemailPreferences preferences = new VisualVoicemailPreferences(context,
- phoneAccountHandle);
- // The OMTP pin length format is {min}-{max}
- String[] lengths = preferences.getString(OmtpConstants.TUI_PASSWORD_LENGTH, "").split("-");
- if (lengths.length == 2) {
- try {
- return Integer.parseInt(lengths[0]);
- } catch (NumberFormatException e) {
- return DEFAULT_PIN_LENGTH;
- }
- }
- return DEFAULT_PIN_LENGTH;
- }
-
- private static String generatePin(int length) {
- SecureRandom random = new SecureRandom();
- return String.format(Locale.US, "%010d", Math.abs(random.nextLong()))
- .substring(0, length);
-
- }
-}
diff --git a/java/com/android/voicemailomtp/protocol/Vvm3Subscriber.java b/java/com/android/voicemailomtp/protocol/Vvm3Subscriber.java
deleted file mode 100644
index 0a4d792b2..000000000
--- a/java/com/android/voicemailomtp/protocol/Vvm3Subscriber.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * 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.voicemailomtp.protocol;
-
-import android.annotation.TargetApi;
-import android.net.Network;
-import android.os.Build;
-import android.os.Build.VERSION_CODES;
-import android.os.Bundle;
-import android.support.annotation.WorkerThread;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.TelephonyManager;
-import android.text.Html;
-import android.text.Spanned;
-import android.text.style.URLSpan;
-import android.util.ArrayMap;
-import com.android.voicemailomtp.ActivationTask;
-import com.android.voicemailomtp.Assert;
-import com.android.voicemailomtp.OmtpEvents;
-import com.android.voicemailomtp.OmtpVvmCarrierConfigHelper;
-import com.android.voicemailomtp.VoicemailStatus;
-import com.android.voicemailomtp.VvmLog;
-import com.android.voicemailomtp.sync.VvmNetworkRequest;
-import com.android.voicemailomtp.sync.VvmNetworkRequest.NetworkWrapper;
-import com.android.voicemailomtp.sync.VvmNetworkRequest.RequestFailedException;
-import com.android.volley.AuthFailureError;
-import com.android.volley.Request;
-import com.android.volley.RequestQueue;
-import com.android.volley.toolbox.HurlStack;
-import com.android.volley.toolbox.RequestFuture;
-import com.android.volley.toolbox.StringRequest;
-import com.android.volley.toolbox.Volley;
-import java.io.IOException;
-import java.net.CookieHandler;
-import java.net.CookieManager;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Class to subscribe to basic VVM3 visual voicemail, for example, Verizon. Subscription is required
- * when the user is unprovisioned. This could happen when the user is on a legacy service, or
- * switched over from devices that used other type of visual voicemail.
- *
- * <p>The STATUS SMS will come with a URL to the voicemail management gateway. From it we can find
- * the self provisioning gateway URL that we can modify voicemail services.
- *
- * <p>A request to the self provisioning gateway to activate basic visual voicemail will return us
- * with a web page. If the user hasn't subscribe to it yet it will contain a link to confirm the
- * subscription. This link should be clicked through cellular network, and have cookies enabled.
- *
- * <p>After the process is completed, the carrier should send us another STATUS SMS with a new or
- * ready user.
- */
-@TargetApi(VERSION_CODES.CUR_DEVELOPMENT)
-public class Vvm3Subscriber {
-
- private static final String TAG = "Vvm3Subscriber";
-
- private static final String OPERATION_GET_SPG_URL = "retrieveSPGURL";
- private static final String SPG_URL_TAG = "spgurl";
- private static final String TRANSACTION_ID_TAG = "transactionid";
- //language=XML
- private static final String VMG_XML_REQUEST_FORMAT = ""
- + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
- + "<VMGVVMRequest>"
- + " <MessageHeader>"
- + " <transactionid>%1$s</transactionid>"
- + " </MessageHeader>"
- + " <MessageBody>"
- + " <mdn>%2$s</mdn>"
- + " <operation>%3$s</operation>"
- + " <source>Device</source>"
- + " <devicemodel>%4$s</devicemodel>"
- + " </MessageBody>"
- + "</VMGVVMRequest>";
-
- static final String VMG_URL_KEY = "vmg_url";
-
- // Self provisioning POST key/values. VVM3 API 2.1.0 12.3
- private static final String SPG_VZW_MDN_PARAM = "VZW_MDN";
- private static final String SPG_VZW_SERVICE_PARAM = "VZW_SERVICE";
- private static final String SPG_VZW_SERVICE_BASIC = "BVVM";
- private static final String SPG_DEVICE_MODEL_PARAM = "DEVICE_MODEL";
- // Value for all android device
- private static final String SPG_DEVICE_MODEL_ANDROID = "DROID_4G";
- private static final String SPG_APP_TOKEN_PARAM = "APP_TOKEN";
- private static final String SPG_APP_TOKEN = "q8e3t5u2o1";
- private static final String SPG_LANGUAGE_PARAM = "SPG_LANGUAGE_PARAM";
- private static final String SPG_LANGUAGE_EN = "ENGLISH";
-
- private static final String BASIC_SUBSCRIBE_LINK_TEXT = "Subscribe to Basic Visual Voice Mail";
-
- private static final int REQUEST_TIMEOUT_SECONDS = 30;
-
- 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;
-
- private RequestQueue mRequestQueue;
-
- private static class ProvisioningException extends Exception {
-
- public ProvisioningException(String message) {
- super(message);
- }
- }
-
- static {
- // Set the default cookie handler to retain session data for the self provisioning gateway.
- // Note; this is not ideal as it is application-wide, and can easily get clobbered.
- // But it seems to be the preferred way to manage cookie for HttpURLConnection, and manually
- // managing cookies will greatly increase complexity.
- CookieManager cookieManager = new CookieManager();
- CookieHandler.setDefault(cookieManager);
- }
-
- @WorkerThread
- public Vvm3Subscriber(ActivationTask task, PhoneAccountHandle handle,
- 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
- // is not included in the status SMS, thus no other way to get the current phone number.
- mNumber = mHelper.getContext().getSystemService(TelephonyManager.class)
- .createForPhoneAccountHandle(mHandle).getLine1Number();
- }
-
- @WorkerThread
- public void subscribe() {
- Assert.isNotMainThread();
- // Cellular data is required to subscribe.
- // processSubscription() is called after network is available.
- VvmLog.i(TAG, "Subscribing");
-
- 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(mStatus, OmtpEvents.VVM3_VMG_CONNECTION_FAILED);
- mTask.fail();
- }
- }
-
- private void processSubscription() {
- try {
- String gatewayUrl = getSelfProvisioningGateway();
- String selfProvisionResponse = getSelfProvisionResponse(gatewayUrl);
- String subscribeLink = findSubscribeLink(selfProvisionResponse);
- clickSubscribeLink(subscribeLink);
- } catch (ProvisioningException e) {
- VvmLog.e(TAG, e.toString());
- mTask.fail();
- }
- }
-
- /**
- * Get the URL to perform self-provisioning from the voicemail management gateway.
- */
- private String getSelfProvisioningGateway() throws ProvisioningException {
- VvmLog.i(TAG, "retrieving SPG URL");
- String response = vvm3XmlRequest(OPERATION_GET_SPG_URL);
- return extractText(response, SPG_URL_TAG);
- }
-
- /**
- * Sent a request to the self-provisioning gateway, which will return us with a webpage. The
- * page might contain a "Subscribe to Basic Visual Voice Mail" link to complete the
- * subscription. The cookie from this response and cellular data is required to click the link.
- */
- private String getSelfProvisionResponse(String url) throws ProvisioningException {
- VvmLog.i(TAG, "Retrieving self provisioning response");
-
- RequestFuture<String> future = RequestFuture.newFuture();
-
- StringRequest stringRequest = new StringRequest(Request.Method.POST, url, future, future) {
- @Override
- protected Map<String, String> getParams() {
- Map<String, String> params = new ArrayMap<>();
- params.put(SPG_VZW_MDN_PARAM, mNumber);
- params.put(SPG_VZW_SERVICE_PARAM, SPG_VZW_SERVICE_BASIC);
- params.put(SPG_DEVICE_MODEL_PARAM, SPG_DEVICE_MODEL_ANDROID);
- params.put(SPG_APP_TOKEN_PARAM, SPG_APP_TOKEN);
- // Language to display the subscription page. The page is never shown to the user
- // so just use English.
- params.put(SPG_LANGUAGE_PARAM, SPG_LANGUAGE_EN);
- return params;
- }
- };
-
- mRequestQueue.add(stringRequest);
- try {
- return future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
- } catch (InterruptedException | ExecutionException | TimeoutException e) {
- mHelper.handleEvent(mStatus, OmtpEvents.VVM3_SPG_CONNECTION_FAILED);
- throw new ProvisioningException(e.toString());
- }
- }
-
- private void clickSubscribeLink(String subscribeLink) throws ProvisioningException {
- VvmLog.i(TAG, "Clicking subscribe link");
- RequestFuture<String> future = RequestFuture.newFuture();
-
- StringRequest stringRequest = new StringRequest(Request.Method.POST,
- subscribeLink, future, future);
- mRequestQueue.add(stringRequest);
- try {
- // A new STATUS SMS will be sent after this request.
- future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
- } catch (TimeoutException | ExecutionException | InterruptedException e) {
- 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.
- // Just leave the CONFIG STATUS as CONFIGURING and end the task. The user can always
- // manually retry if it took too long.
- }
-
- private String vvm3XmlRequest(String operation) throws ProvisioningException {
- VvmLog.d(TAG, "Sending vvm3XmlRequest for " + operation);
- String voicemailManagementGateway = mData.getString(VMG_URL_KEY);
- if (voicemailManagementGateway == null) {
- VvmLog.e(TAG, "voicemailManagementGateway url unknown");
- return null;
- }
- String transactionId = createTransactionId();
- String body = String.format(Locale.US, VMG_XML_REQUEST_FORMAT,
- transactionId, mNumber, operation, Build.MODEL);
-
- RequestFuture<String> future = RequestFuture.newFuture();
- StringRequest stringRequest = new StringRequest(Request.Method.POST,
- voicemailManagementGateway, future, future) {
- @Override
- public byte[] getBody() throws AuthFailureError {
- return body.getBytes();
- }
- };
- mRequestQueue.add(stringRequest);
-
- try {
- String response = future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
- if (!transactionId.equals(extractText(response, TRANSACTION_ID_TAG))) {
- throw new ProvisioningException("transactionId mismatch");
- }
- return response;
- } catch (InterruptedException | ExecutionException | TimeoutException e) {
- mHelper.handleEvent(mStatus, OmtpEvents.VVM3_VMG_CONNECTION_FAILED);
- throw new ProvisioningException(e.toString());
- }
- }
-
- private String findSubscribeLink(String response) throws ProvisioningException {
- Spanned doc = Html.fromHtml(response, Html.FROM_HTML_MODE_LEGACY);
- URLSpan[] spans = doc.getSpans(0, doc.length(), URLSpan.class);
- StringBuilder fulltext = new StringBuilder();
- for (URLSpan span : spans) {
- String text = doc.subSequence(doc.getSpanStart(span), doc.getSpanEnd(span)).toString();
- if (BASIC_SUBSCRIBE_LINK_TEXT.equals(text)) {
- return span.getURL();
- }
- fulltext.append(text);
- }
- throw new ProvisioningException("Subscribe link not found: " + fulltext);
- }
-
- private String createTransactionId() {
- return String.valueOf(Math.abs(new Random().nextLong()));
- }
-
- private String extractText(String xml, String tag) throws ProvisioningException {
- Pattern pattern = Pattern.compile("<" + tag + ">(.*)<\\/" + tag + ">");
- Matcher matcher = pattern.matcher(xml);
- if (matcher.find()) {
- return matcher.group(1);
- }
- throw new ProvisioningException("Tag " + tag + " not found in xml response");
- }
-
- private static class NetworkSpecifiedHurlStack extends HurlStack {
-
- private final Network mNetwork;
-
- public NetworkSpecifiedHurlStack(Network network) {
- mNetwork = network;
- }
-
- @Override
- protected HttpURLConnection createConnection(URL url) throws IOException {
- return (HttpURLConnection) mNetwork.openConnection(url);
- }
-
- }
-}