Support visual voicemail legacy mode

Legacy mode is a mode that on the carrier side visual voicemail is still
activated, but on the client side all network operations are disabled.
SMSs are still monitored so a new message SYNC SMS will be translated
to show a message waiting indicator, like traditional voicemails.

This is for carriers that does not support VVM deactivation so voicemail
can continue to function without the data cost.

Bug: 29399579
Change-Id: I0b72d6e4740aca083401ef1ae3d33976aeaa1253
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 4dd7d0b..9f70349 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -64,7 +64,6 @@
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.sip.SipPhone;
 import com.android.phone.CallGatewayManager.RawGatewayInfo;
-import com.android.services.telephony.TelephonyConnectionService;
 
 import java.util.Arrays;
 import java.util.List;
@@ -2442,7 +2441,7 @@
         return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     }
 
-    static Phone getPhoneForPhoneAccountHandle(PhoneAccountHandle handle) {
+    public static Phone getPhoneForPhoneAccountHandle(PhoneAccountHandle handle) {
         if (handle != null && handle.getComponentName().equals(getPstnConnectionServiceName())) {
             return getPhoneFromIccId(handle.getId());
         }
diff --git a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
index cd27ade..a523119 100644
--- a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
+++ b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
@@ -74,6 +74,12 @@
             "vvm_ssl_port_number_int";
 
     /**
+     * @see #isLegacyModeEnabled()
+     */
+    static final String KEY_VVM_LEGACY_MODE_ENABLED_BOOL =
+            "vvm_legacy_mode_enabled_bool";
+
+    /**
      * Ban a capability reported by the server from being used. The array of string should be a
      * subset of the capabilities returned IMAP CAPABILITY command.
      *
@@ -263,24 +269,46 @@
         return "//VVM";
     }
 
+    /**
+     * Should legacy mode be used when the OMTP VVM client is disabled?
+     *
+     * <p>Legacy mode is a mode that on the carrier side visual voicemail is still activated, but on
+     * the client side all network operations are disabled. SMSs are still monitored so a new
+     * message SYNC SMS will be translated to show a message waiting indicator, like traditional
+     * voicemails.
+     *
+     * <p>This is for carriers that does not support VVM deactivation so voicemail can continue to
+     * function without the data cost.
+     */
+    public boolean isLegacyModeEnabled() {
+        return (boolean) getValue(KEY_VVM_LEGACY_MODE_ENABLED_BOOL, false);
+    }
+
     public void startActivation() {
         VoicemailStatus.edit(mContext, mSubId)
                 .setType(getVvmType())
                 .apply();
 
-        TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
-        telephonyManager.enableVisualVoicemailSmsFilter(mSubId,
-                new VisualVoicemailSmsFilterSettings.Builder().setClientPrefix(getClientPrefix())
-                        .build());
+        activateSmsFilter();
 
         if (mProtocol != null) {
             mProtocol.startActivation(this);
         }
     }
 
+    public void activateSmsFilter() {
+        TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
+        telephonyManager.enableVisualVoicemailSmsFilter(mSubId,
+                new VisualVoicemailSmsFilterSettings.Builder().setClientPrefix(getClientPrefix())
+                        .build());
+    }
+
     public void startDeactivation() {
-        mContext.getSystemService(TelephonyManager.class)
-                .disableVisualVoicemailSmsFilter(mSubId);
+        if (!isLegacyModeEnabled()) {
+            // SMS should still be filtered in legacy mode
+            mContext.getSystemService(TelephonyManager.class)
+                    .disableVisualVoicemailSmsFilter(mSubId);
+        }
         if (mProtocol != null) {
             mProtocol.startDeactivation(this);
         }
diff --git a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
index 833daa9..9f99d71 100644
--- a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
+++ b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
@@ -99,6 +99,10 @@
                         phoneAccount);
                 carrierConfigHelper.startActivation();
             } else {
+                if (carrierConfigHelper.isLegacyModeEnabled()) {
+                    // SMS still need to be filtered under legacy mode.
+                    carrierConfigHelper.activateSmsFilter();
+                }
                 // It may be that the source was not registered to begin with but we want
                 // to run through the steps to remove the source just in case.
                 OmtpVvmSourceManager.getInstance(context).removeSource(phoneAccount);
diff --git a/src/com/android/phone/vvm/omtp/sms/LegacyModeSmsHandler.java b/src/com/android/phone/vvm/omtp/sms/LegacyModeSmsHandler.java
new file mode 100644
index 0000000..53422c4
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/sms/LegacyModeSmsHandler.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.phone.vvm.omtp.sms;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.VoicemailContract;
+import android.telecom.PhoneAccountHandle;
+import android.util.Log;
+
+import com.android.internal.telephony.Phone;
+import com.android.phone.PhoneUtils;
+import com.android.phone.vvm.omtp.OmtpConstants;
+import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
+
+/**
+ * Class ot handle voicemail SMS under legacy mode
+ *
+ * @see OmtpVvmCarrierConfigHelper#isLegacyModeEnabled()
+ */
+public class LegacyModeSmsHandler {
+
+    private static final String TAG = "LegacyModeSmsHandler";
+
+    public static void handle(Context context, Intent intent, PhoneAccountHandle handle) {
+        Log.v(TAG, "processing VVM SMS on legacy mode");
+        String eventType = intent.getExtras()
+                .getString(VoicemailContract.EXTRA_VOICEMAIL_SMS_PREFIX);
+        Bundle data = intent.getExtras().getBundle(VoicemailContract.EXTRA_VOICEMAIL_SMS_FIELDS);
+
+        if (eventType.equals(OmtpConstants.SYNC_SMS_PREFIX)) {
+            SyncMessage message = new SyncMessage(data);
+            Log.v(TAG, "Received SYNC sms for " + handle.getId() +
+                    " with event " + message.getSyncTriggerEvent());
+
+            switch (message.getSyncTriggerEvent()) {
+                case OmtpConstants.NEW_MESSAGE:
+                case OmtpConstants.MAILBOX_UPDATE:
+                    // The user has called into the voicemail and the new message count could
+                    // change.
+                    // For some carriers new message count could be set to 0 even if there are still
+                    // unread messages, to clear the message waiting indicator.
+                    Log.v(TAG, "updating MWI");
+                    Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(handle);
+                    // Setting voicemail message count to non-zero will show the telephony voicemail
+                    // notification, and zero will clear it.
+                    phone.setVoiceMessageCount(message.getNewMessageCount());
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
diff --git a/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java b/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java
index d9939c2..6bb053f 100644
--- a/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java
+++ b/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java
@@ -63,8 +63,13 @@
             return;
         }
 
+        OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(mContext, subId);
         if (!VisualVoicemailSettingsUtil.isVisualVoicemailEnabled(mContext, phone)) {
-            Log.i(TAG, "Received vvm message for disabled vvm source.");
+            if (helper.isLegacyModeEnabled()) {
+                LegacyModeSmsHandler.handle(context, intent, phone);
+            } else {
+                Log.i(TAG, "Received vvm message for disabled vvm source.");
+            }
             return;
         }