1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.phone.vvm.omtp.protocol; 18 19 import android.annotation.IntDef; 20 import android.content.Context; 21 import android.util.Log; 22 import com.android.phone.VoicemailStatus; 23 import com.android.phone.settings.VoicemailChangePinActivity; 24 import com.android.phone.vvm.omtp.DefaultOmtpEventHandler; 25 import com.android.phone.vvm.omtp.OmtpEvents; 26 import com.android.phone.vvm.omtp.OmtpEvents.Type; 27 import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper; 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 31 /** 32 * Handles {@link OmtpEvents} when {@link Vvm3Protocol} is being used. This handler writes custom 33 * error codes into the voicemail status table so support on the dialer side is required. 34 * 35 * TODO(b/29577838) disable VVM3 by default so support on system dialer can be ensured. 36 */ 37 public class Vvm3EventHandler { 38 39 private static final String TAG = "Vvm3EventHandler"; 40 41 @Retention(RetentionPolicy.SOURCE) 42 @IntDef({VMS_DNS_FAILURE, VMG_DNS_FAILURE, SPG_DNS_FAILURE, VMS_NO_CELLULAR, VMG_NO_CELLULAR, 43 SPG_NO_CELLULAR, VMS_TIMEOUT, VMG_TIMEOUT, STATUS_SMS_TIMEOUT, SUBSCRIBER_BLOCKED, 44 UNKNOWN_USER, UNKNOWN_DEVICE, INVALID_PASSWORD, MAILBOX_NOT_INITIALIZED, 45 SERVICE_NOT_PROVISIONED, SERVICE_NOT_ACTIVATED, USER_BLOCKED, IMAP_GETQUOTA_ERROR, 46 IMAP_SELECT_ERROR, IMAP_ERROR, VMG_INTERNAL_ERROR, VMG_DB_ERROR, 47 VMG_COMMUNICATION_ERROR, SPG_URL_NOT_FOUND, VMG_UNKNOWN_ERROR, PIN_NOT_SET}) 48 public @interface ErrorCode { 49 50 } 51 52 public static final int VMS_DNS_FAILURE = -9001; 53 public static final int VMG_DNS_FAILURE = -9002; 54 public static final int SPG_DNS_FAILURE = -9003; 55 public static final int VMS_NO_CELLULAR = -9004; 56 public static final int VMG_NO_CELLULAR = -9005; 57 public static final int SPG_NO_CELLULAR = -9006; 58 public static final int VMS_TIMEOUT = -9007; 59 public static final int VMG_TIMEOUT = -9008; 60 public static final int STATUS_SMS_TIMEOUT = -9009; 61 62 public static final int SUBSCRIBER_BLOCKED = -9990; 63 public static final int UNKNOWN_USER = -9991; 64 public static final int UNKNOWN_DEVICE = -9992; 65 public static final int INVALID_PASSWORD = -9993; 66 public static final int MAILBOX_NOT_INITIALIZED = -9994; 67 public static final int SERVICE_NOT_PROVISIONED = -9995; 68 public static final int SERVICE_NOT_ACTIVATED = -9996; 69 public static final int USER_BLOCKED = -9998; 70 public static final int IMAP_GETQUOTA_ERROR = -9997; 71 public static final int IMAP_SELECT_ERROR = -9989; 72 public static final int IMAP_ERROR = -9999; 73 74 public static final int VMG_INTERNAL_ERROR = -101; 75 public static final int VMG_DB_ERROR = -102; 76 public static final int VMG_COMMUNICATION_ERROR = -103; 77 public static final int SPG_URL_NOT_FOUND = -301; 78 79 // Non VVM3 codes: 80 public static final int VMG_UNKNOWN_ERROR = -1; 81 public static final int PIN_NOT_SET = -100; 82 // STATUS SMS returned st=U and rc!=2. The user cannot be provisioned and must contact customer 83 // support. 84 public static final int SUBSCRIBER_UNKNOWN = -99; 85 86 handleEvent(Context context, OmtpVvmCarrierConfigHelper config, VoicemailStatus.Editor status, OmtpEvents event)87 public static void handleEvent(Context context, OmtpVvmCarrierConfigHelper config, 88 VoicemailStatus.Editor status, OmtpEvents event) { 89 boolean handled = false; 90 switch (event.getType()) { 91 case Type.CONFIGURATION: 92 handled = handleConfigurationEvent(context, status, event); 93 break; 94 case Type.DATA_CHANNEL: 95 handled = handleDataChannelEvent(status, event); 96 break; 97 case Type.NOTIFICATION_CHANNEL: 98 handled = handleNotificationChannelEvent(status, event); 99 break; 100 case Type.OTHER: 101 handled = handleOtherEvent(status, event); 102 break; 103 default: 104 com.android.services.telephony.Log 105 .wtf(TAG, "invalid event type " + event.getType() + " for " + event); 106 } 107 if (!handled) { 108 DefaultOmtpEventHandler.handleEvent(context, config, status, event); 109 } 110 } 111 handleConfigurationEvent(Context context, VoicemailStatus.Editor status, OmtpEvents event)112 private static boolean handleConfigurationEvent(Context context, VoicemailStatus.Editor status, 113 OmtpEvents event) { 114 switch (event) { 115 case CONFIG_REQUEST_STATUS_SUCCESS: 116 if (status.getPhoneAccountHandle() == null) { 117 // This should never happen. 118 Log.e(TAG, "status editor has null phone account handle"); 119 return true; 120 } 121 122 if (!VoicemailChangePinActivity 123 .isDefaultOldPinSet(context, status.getPhoneAccountHandle())) { 124 return false; 125 } else { 126 postError(status, PIN_NOT_SET); 127 } 128 break; 129 case CONFIG_DEFAULT_PIN_REPLACED: 130 postError(status, PIN_NOT_SET); 131 break; 132 case CONFIG_STATUS_SMS_TIME_OUT: 133 postError(status, STATUS_SMS_TIMEOUT); 134 break; 135 default: 136 return false; 137 } 138 return true; 139 } 140 handleDataChannelEvent(VoicemailStatus.Editor status, OmtpEvents event)141 private static boolean handleDataChannelEvent(VoicemailStatus.Editor status, OmtpEvents event) { 142 switch (event) { 143 case DATA_NO_CONNECTION: 144 case DATA_NO_CONNECTION_CELLULAR_REQUIRED: 145 case DATA_ALL_SOCKET_CONNECTION_FAILED: 146 postError(status, VMS_NO_CELLULAR); 147 break; 148 case DATA_SSL_INVALID_HOST_NAME: 149 case DATA_CANNOT_ESTABLISH_SSL_SESSION: 150 case DATA_IOE_ON_OPEN: 151 postError(status, VMS_TIMEOUT); 152 break; 153 case DATA_CANNOT_RESOLVE_HOST_ON_NETWORK: 154 postError(status, VMS_DNS_FAILURE); 155 break; 156 case DATA_BAD_IMAP_CREDENTIAL: 157 postError(status, IMAP_ERROR); 158 break; 159 case DATA_AUTH_UNKNOWN_USER: 160 postError(status, UNKNOWN_USER); 161 break; 162 case DATA_AUTH_UNKNOWN_DEVICE: 163 postError(status, UNKNOWN_DEVICE); 164 break; 165 case DATA_AUTH_INVALID_PASSWORD: 166 postError(status, INVALID_PASSWORD); 167 break; 168 case DATA_AUTH_MAILBOX_NOT_INITIALIZED: 169 postError(status, MAILBOX_NOT_INITIALIZED); 170 break; 171 case DATA_AUTH_SERVICE_NOT_PROVISIONED: 172 postError(status, SERVICE_NOT_PROVISIONED); 173 break; 174 case DATA_AUTH_SERVICE_NOT_ACTIVATED: 175 postError(status, SERVICE_NOT_ACTIVATED); 176 break; 177 case DATA_AUTH_USER_IS_BLOCKED: 178 postError(status, USER_BLOCKED); 179 break; 180 case DATA_REJECTED_SERVER_RESPONSE: 181 case DATA_INVALID_INITIAL_SERVER_RESPONSE: 182 case DATA_SSL_EXCEPTION: 183 postError(status, IMAP_ERROR); 184 break; 185 default: 186 return false; 187 } 188 return true; 189 } 190 handleNotificationChannelEvent(VoicemailStatus.Editor status, OmtpEvents event)191 private static boolean handleNotificationChannelEvent(VoicemailStatus.Editor status, 192 OmtpEvents event) { 193 return false; 194 } 195 handleOtherEvent(VoicemailStatus.Editor status, OmtpEvents event)196 private static boolean handleOtherEvent(VoicemailStatus.Editor status, 197 OmtpEvents event) { 198 switch (event) { 199 case VVM3_NEW_USER_SETUP_FAILED: 200 postError(status, MAILBOX_NOT_INITIALIZED); 201 break; 202 case VVM3_VMG_DNS_FAILURE: 203 postError(status, VMG_DNS_FAILURE); 204 break; 205 case VVM3_SPG_DNS_FAILURE: 206 postError(status, SPG_DNS_FAILURE); 207 break; 208 case VVM3_VMG_CONNECTION_FAILED: 209 postError(status, VMG_NO_CELLULAR); 210 break; 211 case VVM3_SPG_CONNECTION_FAILED: 212 postError(status, SPG_NO_CELLULAR); 213 break; 214 case VVM3_VMG_TIMEOUT: 215 postError(status, VMG_TIMEOUT); 216 break; 217 case VVM3_SUBSCRIBER_PROVISIONED: 218 postError(status, SERVICE_NOT_ACTIVATED); 219 break; 220 case VVM3_SUBSCRIBER_BLOCKED: 221 postError(status, SUBSCRIBER_BLOCKED); 222 break; 223 case VVM3_SUBSCRIBER_UNKNOWN: 224 postError(status, SUBSCRIBER_UNKNOWN); 225 break; 226 default: 227 return false; 228 } 229 return true; 230 } 231 postError(VoicemailStatus.Editor editor, @ErrorCode int errorCode)232 private static void postError(VoicemailStatus.Editor editor, @ErrorCode int errorCode) { 233 switch (errorCode) { 234 case VMG_DNS_FAILURE: 235 case SPG_DNS_FAILURE: 236 case VMG_NO_CELLULAR: 237 case SPG_NO_CELLULAR: 238 case VMG_TIMEOUT: 239 case SUBSCRIBER_BLOCKED: 240 case UNKNOWN_USER: 241 case UNKNOWN_DEVICE: 242 case INVALID_PASSWORD: 243 case MAILBOX_NOT_INITIALIZED: 244 case SERVICE_NOT_PROVISIONED: 245 case SERVICE_NOT_ACTIVATED: 246 case USER_BLOCKED: 247 case VMG_UNKNOWN_ERROR: 248 case SPG_URL_NOT_FOUND: 249 case VMG_INTERNAL_ERROR: 250 case VMG_DB_ERROR: 251 case VMG_COMMUNICATION_ERROR: 252 case PIN_NOT_SET: 253 case SUBSCRIBER_UNKNOWN: 254 editor.setConfigurationState(errorCode); 255 break; 256 case VMS_NO_CELLULAR: 257 case VMS_DNS_FAILURE: 258 case VMS_TIMEOUT: 259 case IMAP_GETQUOTA_ERROR: 260 case IMAP_SELECT_ERROR: 261 case IMAP_ERROR: 262 editor.setDataChannelState(errorCode); 263 break; 264 case STATUS_SMS_TIMEOUT: 265 editor.setNotificationChannelState(errorCode); 266 break; 267 default: 268 Log.wtf(TAG, "unknown error code: " + errorCode); 269 } 270 editor.apply(); 271 } 272 } 273