312 lines
10 KiB
Java
312 lines
10 KiB
Java
/*
|
|
* 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.voicemail.impl.protocol;
|
|
|
|
import android.content.Context;
|
|
import android.provider.VoicemailContract.Status;
|
|
import android.support.annotation.IntDef;
|
|
import android.telecom.PhoneAccountHandle;
|
|
import com.android.voicemail.VoicemailComponent;
|
|
import com.android.voicemail.impl.DefaultOmtpEventHandler;
|
|
import com.android.voicemail.impl.OmtpEvents;
|
|
import com.android.voicemail.impl.OmtpEvents.Type;
|
|
import com.android.voicemail.impl.OmtpVvmCarrierConfigHelper;
|
|
import com.android.voicemail.impl.VoicemailStatus;
|
|
import com.android.voicemail.impl.VvmLog;
|
|
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.
|
|
*
|
|
* <p>TODO(a bug) 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:
|
|
VvmLog.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 (!isPinRandomized(context, status.getPhoneAccountHandle())) {
|
|
return false;
|
|
} else {
|
|
postError(status, PIN_NOT_SET);
|
|
}
|
|
break;
|
|
case CONFIG_ACTIVATING_SUBSEQUENT:
|
|
if (isPinRandomized(context, status.getPhoneAccountHandle())) {
|
|
status.setConfigurationState(PIN_NOT_SET);
|
|
} else {
|
|
status.setConfigurationState(Status.CONFIGURATION_STATE_OK);
|
|
}
|
|
status
|
|
.setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
|
|
.setDataChannelState(Status.DATA_CHANNEL_STATE_OK)
|
|
.apply();
|
|
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 unusedStatus, OmtpEvents unusedEvent) {
|
|
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:
|
|
VvmLog.wtf(TAG, "unknown error code: " + errorCode);
|
|
}
|
|
editor.apply();
|
|
}
|
|
|
|
private static boolean isPinRandomized(Context context, PhoneAccountHandle phoneAccountHandle) {
|
|
if (phoneAccountHandle == null) {
|
|
// This should never happen.
|
|
VvmLog.e(TAG, "status editor has null phone account handle");
|
|
return false;
|
|
}
|
|
return VoicemailComponent.get(context)
|
|
.getVoicemailClient()
|
|
.createPinChanger(context, phoneAccountHandle)
|
|
.getScrambledPin()
|
|
!= null;
|
|
}
|
|
}
|