Merge "Added a new API to query VT data usage" into nyc-mr1-dev
diff --git a/src/com/android/phone/settings/VisualVoicemailSettingsUtil.java b/src/com/android/phone/settings/VisualVoicemailSettingsUtil.java
index 94d286e..d7e573e 100644
--- a/src/com/android/phone/settings/VisualVoicemailSettingsUtil.java
+++ b/src/com/android/phone/settings/VisualVoicemailSettingsUtil.java
@@ -49,8 +49,7 @@
     private static final long MAX_SYNC_RETRY_INTERVAL_MS = 86400000;   // 24 hours
     private static final long DEFAULT_SYNC_RETRY_INTERVAL_MS = 900000; // 15 minutes
 
-    /* package */
-    static void setVisualVoicemailEnabled(Context context, PhoneAccountHandle phoneAccount,
+    public static void setVisualVoicemailEnabled(Context context, PhoneAccountHandle phoneAccount,
             boolean isEnabled) {
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         prefs.edit()
diff --git a/src/com/android/phone/vvm/omtp/DefaultOmtpEventHandler.java b/src/com/android/phone/vvm/omtp/DefaultOmtpEventHandler.java
index 6837bf5..c49df64 100644
--- a/src/com/android/phone/vvm/omtp/DefaultOmtpEventHandler.java
+++ b/src/com/android/phone/vvm/omtp/DefaultOmtpEventHandler.java
@@ -27,31 +27,32 @@
 
     private static final String TAG = "DefErrorCodeHandler";
 
-    public static void handleEvent(Context context, int subId, OmtpEvents event) {
+    public static void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
+            OmtpEvents event) {
         switch (event.getType()) {
             case Type.CONFIGURATION:
-                handleConfigurationEvent(context, subId, event);
+                handleConfigurationEvent(context, config, event);
                 break;
             case Type.DATA_CHANNEL:
-                handleDataChannelEvent(context, subId, event);
+                handleDataChannelEvent(context, config, event);
                 break;
             case Type.NOTIFICATION_CHANNEL:
-                handleNotificationChannelEvent(context, subId, event);
+                handleNotificationChannelEvent(context, config, event);
                 break;
             case Type.OTHER:
-                handleOtherEvent(context, subId, event);
+                handleOtherEvent(context, config, event);
                 break;
             default:
                 VvmLog.wtf(TAG, "invalid event type " + event.getType() + " for " + event);
         }
     }
 
-    private static void handleConfigurationEvent(Context context, int subId,
+    private static void handleConfigurationEvent(Context context, OmtpVvmCarrierConfigHelper config,
             OmtpEvents event) {
         switch (event) {
             case CONFIG_REQUEST_STATUS_SUCCESS:
             case CONFIG_PIN_SET:
-                VoicemailStatus.edit(context, subId)
+                VoicemailStatus.edit(context, config.getSubId())
                         .setConfigurationState(VoicemailContract.Status.CONFIGURATION_STATE_OK)
                         .setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
                         .apply();
@@ -61,35 +62,35 @@
         }
     }
 
-    private static void handleDataChannelEvent(Context context, int subId,
+    private static void handleDataChannelEvent(Context context, OmtpVvmCarrierConfigHelper config,
             OmtpEvents event) {
         switch (event) {
             case DATA_IMAP_OPERATION_COMPLETED:
-                VoicemailStatus.edit(context, subId)
+                VoicemailStatus.edit(context, config.getSubId())
                         .setDataChannelState(Status.DATA_CHANNEL_STATE_OK)
                         .apply();
                 break;
 
             case DATA_NO_CONNECTION:
-                VoicemailStatus.edit(context, subId)
+                VoicemailStatus.edit(context, config.getSubId())
                         .setDataChannelState(Status.DATA_CHANNEL_STATE_NO_CONNECTION)
                         .apply();
                 break;
 
             case DATA_NO_CONNECTION_CELLULAR_REQUIRED:
-                VoicemailStatus.edit(context, subId)
+                VoicemailStatus.edit(context, config.getSubId())
                         .setDataChannelState(
                                 Status.DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED)
                         .apply();
                 break;
             case DATA_INVALID_PORT:
-                VoicemailStatus.edit(context, subId)
+                VoicemailStatus.edit(context, config.getSubId())
                         .setDataChannelState(
                                 VoicemailContract.Status.DATA_CHANNEL_STATE_BAD_CONFIGURATION)
                         .apply();
                 break;
             case DATA_CANNOT_RESOLVE_HOST_ON_NETWORK:
-                VoicemailStatus.edit(context, subId)
+                VoicemailStatus.edit(context, config.getSubId())
                         .setDataChannelState(
                                 VoicemailContract.Status.DATA_CHANNEL_STATE_SERVER_CONNECTION_ERROR)
                         .apply();
@@ -97,7 +98,7 @@
             case DATA_SSL_INVALID_HOST_NAME:
             case DATA_CANNOT_ESTABLISH_SSL_SESSION:
             case DATA_IOE_ON_OPEN:
-                VoicemailStatus.edit(context, subId)
+                VoicemailStatus.edit(context, config.getSubId())
                         .setDataChannelState(
                                 VoicemailContract.Status.DATA_CHANNEL_STATE_COMMUNICATION_ERROR)
                         .apply();
@@ -110,7 +111,7 @@
             case DATA_AUTH_SERVICE_NOT_PROVISIONED:
             case DATA_AUTH_SERVICE_NOT_ACTIVATED:
             case DATA_AUTH_USER_IS_BLOCKED:
-                VoicemailStatus.edit(context, subId)
+                VoicemailStatus.edit(context, config.getSubId())
                         .setDataChannelState(
                                 VoicemailContract.Status.DATA_CHANNEL_STATE_BAD_CONFIGURATION)
                         .apply();
@@ -120,7 +121,7 @@
             case DATA_INVALID_INITIAL_SERVER_RESPONSE:
             case DATA_SSL_EXCEPTION:
             case DATA_ALL_SOCKET_CONNECTION_FAILED:
-                VoicemailStatus.edit(context, subId)
+                VoicemailStatus.edit(context, config.getSubId())
                         .setDataChannelState(
                                 VoicemailContract.Status.DATA_CHANNEL_STATE_SERVER_ERROR)
                         .apply();
@@ -131,29 +132,33 @@
         }
     }
 
-    private static void handleNotificationChannelEvent(Context context, int subId,
-            OmtpEvents event) {
+    private static void handleNotificationChannelEvent(Context context,
+            OmtpVvmCarrierConfigHelper config, OmtpEvents event) {
         switch (event) {
             case NOTIFICATION_IN_SERVICE:
-                VoicemailStatus.edit(context, subId)
+                VoicemailStatus.edit(context, config.getSubId())
                         .setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
                         .apply();
                 break;
             case NOTIFICATION_SERVICE_LOST:
-                VoicemailStatus.edit(context, subId)
-                        .setNotificationChannelState(
-                                Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION)
-                        .apply();
+                VoicemailStatus.Editor editor = VoicemailStatus.edit(context, config.getSubId());
+                editor.setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
+                if (config.isCellularDataRequired()) {
+                    editor.setDataChannelState(
+                            Status.DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED);
+                }
+                editor.apply();
                 break;
             default:
                 VvmLog.wtf(TAG, "invalid notification channel event " + event);
         }
     }
 
-    private static void handleOtherEvent(Context context, int subId, OmtpEvents event) {
+    private static void handleOtherEvent(Context context, OmtpVvmCarrierConfigHelper config,
+            OmtpEvents event) {
         switch (event) {
             case OTHER_SOURCE_REMOVED:
-                VoicemailStatus.edit(context, subId)
+                VoicemailStatus.edit(context, config.getSubId())
                         .setConfigurationState(Status.CONFIGURATION_STATE_NOT_CONFIGURED)
                         .setNotificationChannelState(
                                 Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION)
diff --git a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
index 02318c6..b570744 100644
--- a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
+++ b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
@@ -328,7 +328,7 @@
     public void handleEvent(OmtpEvents event) {
         VvmLog.i(TAG, "OmtpEvent:" + event);
         if (mProtocol != null) {
-            mProtocol.handleEvent(mContext, mSubId, event);
+            mProtocol.handleEvent(mContext, this, event);
         }
     }
 
diff --git a/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java b/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
index 4b81fdb..64b37c6 100644
--- a/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
+++ b/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
@@ -98,9 +98,6 @@
                 return;
             }
             helper.handleEvent(OmtpEvents.NOTIFICATION_SERVICE_LOST);
-            if (helper.isCellularDataRequired()) {
-                helper.handleEvent(OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
-            }
         }
         mPreviousState = state;
     }
diff --git a/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocol.java b/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocol.java
index 9e56d12..be2a77f 100644
--- a/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocol.java
+++ b/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocol.java
@@ -70,7 +70,8 @@
         return command;
     }
 
-    public void handleEvent(Context context, int subId, OmtpEvents event) {
-        DefaultOmtpEventHandler.handleEvent(context, subId, event);
+    public void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
+            OmtpEvents event) {
+        DefaultOmtpEventHandler.handleEvent(context, config, event);
     }
 }
diff --git a/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java b/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java
index 1b4144a..8eacb99 100644
--- a/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java
+++ b/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java
@@ -26,6 +26,7 @@
 import com.android.phone.vvm.omtp.DefaultOmtpEventHandler;
 import com.android.phone.vvm.omtp.OmtpEvents;
 import com.android.phone.vvm.omtp.OmtpEvents.Type;
+import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
 import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
 
 import java.lang.annotation.Retention;
@@ -84,43 +85,45 @@
     public static final int PIN_NOT_SET = -100;
 
 
-    public static void handleEvent(Context context, int subId, OmtpEvents event) {
+    public static void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
+            OmtpEvents event) {
         boolean handled = false;
         switch (event.getType()) {
             case Type.CONFIGURATION:
-                handled = handleConfigurationEvent(context, subId, event);
+                handled = handleConfigurationEvent(context, config, event);
                 break;
             case Type.DATA_CHANNEL:
-                handled = handleDataChannelEvent(context, subId, event);
+                handled = handleDataChannelEvent(context, config, event);
                 break;
             case Type.NOTIFICATION_CHANNEL:
-                handled = handleNotificationChannelEvent(context, subId, event);
+                handled = handleNotificationChannelEvent(context, config, event);
                 break;
             case Type.OTHER:
-                handled = handleOtherEvent(context, subId, event);
+                handled = handleOtherEvent(context, config, event);
                 break;
             default:
                 com.android.services.telephony.Log
                         .wtf(TAG, "invalid event type " + event.getType() + " for " + event);
         }
         if (!handled) {
-            DefaultOmtpEventHandler.handleEvent(context, subId, event);
+            DefaultOmtpEventHandler.handleEvent(context, config, event);
         }
     }
 
-    private static boolean handleConfigurationEvent(Context context, int subId,
-            OmtpEvents event) {
+    private static boolean handleConfigurationEvent(Context context,
+            OmtpVvmCarrierConfigHelper config, OmtpEvents event) {
         switch (event) {
             case CONFIG_REQUEST_STATUS_SUCCESS:
-                PhoneAccountHandle handle = PhoneAccountHandleConverter.fromSubId(subId);
+                PhoneAccountHandle handle = PhoneAccountHandleConverter
+                        .fromSubId(config.getSubId());
                 if (VoicemailChangePinDialogPreference.getDefaultOldPin(context, handle) == null) {
                     return false;
                 } else {
-                    postError(context, subId, PIN_NOT_SET);
+                    postError(context, config, PIN_NOT_SET);
                 }
                 break;
             case CONFIG_DEFAULT_PIN_REPLACED:
-                postError(context, subId, PIN_NOT_SET);
+                postError(context, config, PIN_NOT_SET);
                 break;
             default:
                 return false;
@@ -128,39 +131,39 @@
         return true;
     }
 
-    private static boolean handleDataChannelEvent(Context context, int subId,
-            OmtpEvents event) {
+    private static boolean handleDataChannelEvent(Context context,
+            OmtpVvmCarrierConfigHelper config, OmtpEvents event) {
         switch (event) {
             case DATA_NO_CONNECTION:
             case DATA_NO_CONNECTION_CELLULAR_REQUIRED:
-                postError(context, subId, VMS_NO_CELLULAR);
+                postError(context, config, VMS_NO_CELLULAR);
                 break;
             case DATA_CANNOT_RESOLVE_HOST_ON_NETWORK:
-                postError(context, subId, VMS_DNS_FAILURE);
+                postError(context, config, VMS_DNS_FAILURE);
                 break;
             case DATA_BAD_IMAP_CREDENTIAL:
-                postError(context, subId, IMAP_ERROR);
+                postError(context, config, IMAP_ERROR);
                 break;
             case DATA_AUTH_UNKNOWN_USER:
-                postError(context, subId, UNKNOWN_USER);
+                postError(context, config, UNKNOWN_USER);
                 break;
             case DATA_AUTH_UNKNOWN_DEVICE:
-                postError(context, subId, UNKNOWN_DEVICE);
+                postError(context, config, UNKNOWN_DEVICE);
                 break;
             case DATA_AUTH_INVALID_PASSWORD:
-                postError(context, subId, INVALID_PASSWORD);
+                postError(context, config, INVALID_PASSWORD);
                 break;
             case DATA_AUTH_MAILBOX_NOT_INITIALIZED:
-                postError(context, subId, MAILBOX_NOT_INITIALIZED);
+                postError(context, config, MAILBOX_NOT_INITIALIZED);
                 break;
             case DATA_AUTH_SERVICE_NOT_PROVISIONED:
-                postError(context, subId, SERVICE_NOT_PROVISIONED);
+                postError(context, config, SERVICE_NOT_PROVISIONED);
                 break;
             case DATA_AUTH_SERVICE_NOT_ACTIVATED:
-                postError(context, subId, SERVICE_NOT_ACTIVATED);
+                postError(context, config, SERVICE_NOT_ACTIVATED);
                 break;
             case DATA_AUTH_USER_IS_BLOCKED:
-                postError(context, subId, USER_BLOCKED);
+                postError(context, config, USER_BLOCKED);
                 break;
 
             case DATA_INVALID_PORT:
@@ -171,7 +174,7 @@
             case DATA_INVALID_INITIAL_SERVER_RESPONSE:
             case DATA_SSL_EXCEPTION:
             case DATA_ALL_SOCKET_CONNECTION_FAILED:
-                postError(context, subId, IMAP_ERROR);
+                postError(context, config, IMAP_ERROR);
                 break;
 
             default:
@@ -180,44 +183,46 @@
         return true;
     }
 
-    private static boolean handleNotificationChannelEvent(Context context, int subId,
-            OmtpEvents event) {
+    private static boolean handleNotificationChannelEvent(Context context,
+            OmtpVvmCarrierConfigHelper config, OmtpEvents event) {
         return false;
     }
 
-    private static boolean handleOtherEvent(Context context, int subId, OmtpEvents event) {
+    private static boolean handleOtherEvent(Context context, OmtpVvmCarrierConfigHelper config,
+            OmtpEvents event) {
         switch (event) {
             case VVM3_NEW_USER_SETUP_FAILED:
-                postError(context, subId, MAILBOX_NOT_INITIALIZED);
+                postError(context, config, MAILBOX_NOT_INITIALIZED);
                 break;
             case VVM3_VMG_DNS_FAILURE:
-                postError(context, subId, VMG_DNS_FAILURE);
+                postError(context, config, VMG_DNS_FAILURE);
                 break;
             case VVM3_SPG_DNS_FAILURE:
-                postError(context, subId, SPG_DNS_FAILURE);
+                postError(context, config, SPG_DNS_FAILURE);
                 break;
             case VVM3_VMG_CONNECTION_FAILED:
-                postError(context, subId, VMG_NO_CELLULAR);
+                postError(context, config, VMG_NO_CELLULAR);
                 break;
             case VVM3_SPG_CONNECTION_FAILED:
-                postError(context, subId, SPG_NO_CELLULAR);
+                postError(context, config, SPG_NO_CELLULAR);
                 break;
             case VVM3_VMG_TIMEOUT:
-                postError(context, subId, VMG_TIMEOUT);
+                postError(context, config, VMG_TIMEOUT);
                 break;
 
             case VVM3_SUBSCRIBER_PROVISIONED:
-                postError(context, subId, SERVICE_NOT_ACTIVATED);
+                postError(context, config, SERVICE_NOT_ACTIVATED);
             case VVM3_SUBSCRIBER_BLOCKED:
-                postError(context, subId, SUBSCRIBER_BLOCKED);
+                postError(context, config, SUBSCRIBER_BLOCKED);
             default:
                 return false;
         }
         return true;
     }
 
-    private static void postError(Context context, int subId, @ErrorCode int errorCode) {
-        VoicemailStatus.Editor editor = VoicemailStatus.edit(context, subId);
+    private static void postError(Context context, OmtpVvmCarrierConfigHelper config,
+            @ErrorCode int errorCode) {
+        VoicemailStatus.Editor editor = VoicemailStatus.edit(context, config.getSubId());
 
         switch (errorCode) {
             case VMG_DNS_FAILURE:
diff --git a/src/com/android/phone/vvm/omtp/protocol/Vvm3Protocol.java b/src/com/android/phone/vvm/omtp/protocol/Vvm3Protocol.java
index df84034..306006d 100644
--- a/src/com/android/phone/vvm/omtp/protocol/Vvm3Protocol.java
+++ b/src/com/android/phone/vvm/omtp/protocol/Vvm3Protocol.java
@@ -82,14 +82,21 @@
     public void startProvisioning(PhoneAccountHandle phoneAccountHandle,
             OmtpVvmCarrierConfigHelper config, StatusMessage message, Bundle data) {
         VvmLog.i(TAG, "start vvm3 provisioning");
-        if ("U".equals(message.getProvisioningStatus())) {
+        if (OmtpConstants.SUBSCRIBER_UNKNOWN.equals(message.getProvisioningStatus())) {
             VvmLog.i(TAG, "Provisioning status: Unknown, subscribing");
             new Vvm3Subscriber(phoneAccountHandle, config, data).subscribe();
-        } else if ("N".equals(message.getProvisioningStatus())) {
+        } else if (OmtpConstants.SUBSCRIBER_NEW.equals(message.getProvisioningStatus())) {
             VvmLog.i(TAG, "setting up new user");
             VisualVoicemailSettingsUtil.setVisualVoicemailCredentialsFromStatusMessage(
                     config.getContext(), phoneAccountHandle, message);
             startProvisionNewUser(phoneAccountHandle, config, message);
+        } else if (OmtpConstants.SUBSCRIBER_PROVISIONED.equals(message.getProvisioningStatus())) {
+            VvmLog.i(TAG, "User provisioned but not activated, disabling VVM");
+            VisualVoicemailSettingsUtil
+                    .setVisualVoicemailEnabled(config.getContext(), phoneAccountHandle, false);
+        } else if (OmtpConstants.SUBSCRIBER_BLOCKED.equals(message.getProvisioningStatus())) {
+            VvmLog.i(TAG, "User blocked");
+            config.handleEvent(OmtpEvents.VVM3_SUBSCRIBER_BLOCKED);
         }
     }
 
@@ -100,8 +107,8 @@
     }
 
     @Override
-    public void handleEvent(Context context, int subId, OmtpEvents event) {
-        Vvm3EventHandler.handleEvent(context, subId, event);
+    public void handleEvent(Context context, OmtpVvmCarrierConfigHelper config, OmtpEvents event) {
+        Vvm3EventHandler.handleEvent(context, config, event);
     }
 
     @Override