• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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