diff options
Diffstat (limited to 'java/com/android/voicemailomtp/protocol/Vvm3Protocol.java')
-rw-r--r-- | java/com/android/voicemailomtp/protocol/Vvm3Protocol.java | 301 |
1 files changed, 0 insertions, 301 deletions
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); - - } -} |