Support SOURCE_TYPE in VoicemailContract.Status

Visual voicemail protocol type is written to the SOURCE_TYPE field upon
activation. For example, "vvm_type_omtp". This string will help the 
dialer interpret protocol-specific error codes.

Helper methods in VoicemailContract.Status is removed in ag/1074791.
This CL replaces VoicemailUtils with VoicemailStatus to support the
removed functionality. It is also changed to an editor to update
multiple values with a single query.

Bug:26944391
Change-Id: Id5fae6852e7f15f6d9ddcdbde6577e379f16a5f3
diff --git a/src/com/android/phone/VoicemailStatus.java b/src/com/android/phone/VoicemailStatus.java
new file mode 100644
index 0000000..ca01de8
--- /dev/null
+++ b/src/com/android/phone/VoicemailStatus.java
@@ -0,0 +1,93 @@
+/*
+ * 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.phone;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.net.Uri;
+import android.provider.VoicemailContract;
+import android.provider.VoicemailContract.Status;
+import android.telecom.PhoneAccountHandle;
+import android.telephony.SubscriptionManager;
+
+public class VoicemailStatus {
+
+
+    public static class Editor {
+
+        private final Context mContext;
+        private final PhoneAccountHandle mPhoneAccountHandle;
+
+        private ContentValues mValues = new ContentValues();
+
+        private Editor(Context context, PhoneAccountHandle phoneAccountHandle) {
+            mContext = context;
+            mPhoneAccountHandle = phoneAccountHandle;
+        }
+
+        public Editor setType(String type) {
+            mValues.put(Status.SOURCE_TYPE, type);
+            return this;
+        }
+
+        public Editor setConfigurationState(int configurationState) {
+            mValues.put(Status.CONFIGURATION_STATE, configurationState);
+            return this;
+        }
+
+        public Editor setDataChannelState(int dataChannelState) {
+            mValues.put(Status.DATA_CHANNEL_STATE, dataChannelState);
+            return this;
+        }
+
+        public Editor setNotificationChannelState(int notificationChannelState) {
+            mValues.put(Status.NOTIFICATION_CHANNEL_STATE, notificationChannelState);
+            return this;
+        }
+
+        public Editor setQuota(int occupied, int total) {
+            if (occupied == VoicemailContract.Status.QUOTA_UNAVAILABLE
+                    && total == VoicemailContract.Status.QUOTA_UNAVAILABLE) {
+                return this;
+            }
+
+            mValues.put(Status.QUOTA_OCCUPIED, occupied);
+            mValues.put(Status.QUOTA_TOTAL, total);
+            return this;
+        }
+
+        public void apply() {
+            mValues.put(Status.PHONE_ACCOUNT_COMPONENT_NAME,
+                    mPhoneAccountHandle.getComponentName().flattenToString());
+            mValues.put(Status.PHONE_ACCOUNT_ID, mPhoneAccountHandle.getId());
+            ContentResolver contentResolver = mContext.getContentResolver();
+            Uri statusUri = VoicemailContract.Status.buildSourceUri(mContext.getPackageName());
+            contentResolver.insert(statusUri, mValues);
+        }
+    }
+
+    public static Editor edit(Context context, PhoneAccountHandle phoneAccountHandle) {
+        return new Editor(context, phoneAccountHandle);
+    }
+
+    public static Editor edit(Context context, int subId) {
+        PhoneAccountHandle phone = PhoneUtils.makePstnPhoneAccountHandle(
+                SubscriptionManager.getPhoneId(subId));
+        return new Editor(context, phone);
+    }
+}
diff --git a/src/com/android/phone/VoicemailUtils.java b/src/com/android/phone/VoicemailUtils.java
deleted file mode 100644
index f67c64b..0000000
--- a/src/com/android/phone/VoicemailUtils.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.phone;
-
-import android.content.Context;
-import android.provider.VoicemailContract;
-import android.provider.VoicemailContract.Status;
-import android.telecom.PhoneAccountHandle;
-
-public class VoicemailUtils {
-
-    public static void setConfigurationState(Context context, PhoneAccountHandle accountHandle,
-            int configurationState) {
-        VoicemailContract.Status.setStatus(context, accountHandle,
-                configurationState,
-                Status.DATA_CHANNEL_STATE_IGNORE,
-                Status.NOTIFICATION_CHANNEL_STATE_IGNORE);
-    }
-
-    public static void setDataChannelState(Context context, PhoneAccountHandle accountHandle,
-            int dataChannelState) {
-        VoicemailContract.Status.setStatus(context, accountHandle,
-                Status.CONFIGURATION_STATE_IGNORE,
-                dataChannelState,
-                Status.NOTIFICATION_CHANNEL_STATE_IGNORE);
-    }
-
-    public static void setNotificationChannelState(Context context,
-            PhoneAccountHandle accountHandle, int notificationChannelState) {
-        VoicemailContract.Status.setStatus(context, accountHandle,
-                Status.CONFIGURATION_STATE_IGNORE,
-                Status.DATA_CHANNEL_STATE_IGNORE,
-                notificationChannelState);
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
index 64e7e31..537b3a7 100644
--- a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
+++ b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
@@ -29,6 +29,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.phone.VoicemailStatus;
 import com.android.phone.vvm.omtp.protocol.VisualVoicemailProtocol;
 import com.android.phone.vvm.omtp.protocol.VisualVoicemailProtocolFactory;
 
@@ -254,6 +255,10 @@
     }
 
     public void startActivation() {
+        VoicemailStatus.edit(mContext, mSubId)
+                .setType(getVvmType())
+                .apply();
+
         TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
         telephonyManager.enableVisualVoicemailSmsFilter(mSubId,
                 new VisualVoicemailSmsFilterSettings.Builder().setClientPrefix(getClientPrefix())
diff --git a/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java b/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
index 1b2e34e..02cf443 100644
--- a/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
+++ b/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
@@ -25,6 +25,7 @@
 
 import com.android.phone.PhoneGlobals;
 import com.android.phone.PhoneUtils;
+import com.android.phone.VoicemailStatus;
 import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
 import com.android.phone.vvm.omtp.sync.OmtpVvmSyncService;
 import com.android.phone.vvm.omtp.sync.VoicemailStatusQueryHelper;
@@ -62,10 +63,10 @@
             if (voicemailStatusQueryHelper.isVoicemailSourceConfigured(mPhoneAccount)) {
                 if (!voicemailStatusQueryHelper.isNotificationsChannelActive(mPhoneAccount)) {
                     Log.v(TAG, "Notifications channel is active for " + mPhoneAccount.getId());
-                    VoicemailContract.Status.setStatus(mContext, mPhoneAccount,
-                            VoicemailContract.Status.CONFIGURATION_STATE_OK,
-                            VoicemailContract.Status.DATA_CHANNEL_STATE_OK,
-                            VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK);
+                    VoicemailStatus.edit(mContext, mPhoneAccount)
+                            .setNotificationChannelState(
+                                    VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK)
+                            .apply();
                     PhoneGlobals.getInstance().clearMwiIndicator(
                             PhoneUtils.getSubIdForPhoneAccountHandle(mPhoneAccount));
                 }
@@ -102,10 +103,10 @@
                 return;
             }
 
-            VoicemailContract.Status.setStatus(mContext, mPhoneAccount,
-                    VoicemailContract.Status.CONFIGURATION_STATE_OK,
-                    VoicemailContract.Status.DATA_CHANNEL_STATE_NO_CONNECTION,
-                    VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
+            VoicemailStatus.edit(mContext, mPhoneAccount)
+                    .setNotificationChannelState(
+                            VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION)
+                    .apply();
         }
         mPreviousState = state;
     }
diff --git a/src/com/android/phone/vvm/omtp/imap/ImapHelper.java b/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
index 4c2192e..9305d7b 100644
--- a/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
+++ b/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
@@ -29,7 +29,7 @@
 import android.util.Log;
 
 import com.android.phone.PhoneUtils;
-import com.android.phone.VoicemailUtils;
+import com.android.phone.VoicemailStatus;
 import com.android.phone.common.mail.Address;
 import com.android.phone.common.mail.Body;
 import com.android.phone.common.mail.BodyPart;
@@ -110,8 +110,9 @@
             mImapStore = new ImapStore(
                     context, this, username, password, port, serverName, auth, network);
         } catch (NumberFormatException e) {
-            VoicemailUtils.setDataChannelState(
-                    mContext, mPhoneAccount, Status.DATA_CHANNEL_STATE_BAD_CONFIGURATION);
+            VoicemailStatus.edit(mContext, mPhoneAccount)
+                    .setDataChannelState(Status.DATA_CHANNEL_STATE_BAD_CONFIGURATION)
+                    .apply();
             LogUtils.w(TAG, "Could not parse port number");
         }
 
@@ -156,7 +157,9 @@
     }
 
     public void setDataChannelState(int dataChannelState) {
-        VoicemailUtils.setDataChannelState(mContext, mPhoneAccount, dataChannelState);
+        VoicemailStatus.edit(mContext, mPhoneAccount)
+                .setDataChannelState(dataChannelState)
+                .apply();
     }
 
     /**
@@ -401,8 +404,9 @@
         }
         mQuotaOccupied = quota.occupied;
         mQuotaTotal = quota.total;
-        VoicemailContract.Status
-                .setQuota(mContext, mPhoneAccount, mQuotaOccupied, mQuotaTotal);
+        VoicemailStatus.edit(mContext, mPhoneAccount)
+                .setQuota(mQuotaOccupied, mQuotaTotal)
+                .apply();
         mPrefs.edit()
                 .putInt(getSharedPrefsKey(PREF_KEY_QUOTA_OCCUPIED), mQuotaOccupied)
                 .putInt(getSharedPrefsKey(PREF_KEY_QUOTA_TOTAL), mQuotaTotal)
diff --git a/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java b/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java
index f2beabe..bb3f758 100644
--- a/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java
+++ b/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java
@@ -23,6 +23,7 @@
 import android.os.Bundle;
 import android.os.UserManager;
 import android.provider.VoicemailContract;
+import android.provider.VoicemailContract.Status;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.Voicemail;
 import android.telephony.SubscriptionManager;
@@ -30,6 +31,7 @@
 
 import com.android.phone.PhoneGlobals;
 import com.android.phone.PhoneUtils;
+import com.android.phone.VoicemailStatus;
 import com.android.phone.settings.VisualVoicemailSettingsUtil;
 import com.android.phone.vvm.omtp.LocalLogHelper;
 import com.android.phone.vvm.omtp.OmtpConstants;
@@ -154,10 +156,10 @@
                 OmtpVvmSourceManager.getInstance(mContext);
 
         if (OmtpConstants.SUCCESS.equals(message.getReturnCode())) {
-            VoicemailContract.Status.setStatus(mContext, phone,
-                    VoicemailContract.Status.CONFIGURATION_STATE_OK,
-                    VoicemailContract.Status.DATA_CHANNEL_STATE_OK,
-                    VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK);
+            VoicemailStatus.edit(mContext, phone)
+                    .setConfigurationState(VoicemailContract.Status.CONFIGURATION_STATE_OK)
+                    .setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
+                    .apply();
 
             // Save the IMAP credentials in preferences so they are persistent and can be retrieved.
             VisualVoicemailSettingsUtil.setVisualVoicemailCredentialsFromStatusMessage(
diff --git a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java
index 0520098..811b05a 100644
--- a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java
+++ b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java
@@ -16,7 +16,7 @@
 package com.android.phone.vvm.omtp.sync;
 
 import android.content.Context;
-import android.provider.VoicemailContract;
+import android.provider.VoicemailContract.Status;
 import android.telecom.PhoneAccountHandle;
 import android.telephony.PhoneStateListener;
 import android.telephony.SubscriptionManager;
@@ -24,6 +24,7 @@
 
 import com.android.internal.telephony.Phone;
 import com.android.phone.PhoneUtils;
+import com.android.phone.VoicemailStatus;
 import com.android.phone.vvm.omtp.VvmPhoneStateListener;
 
 import java.util.Collections;
@@ -105,10 +106,11 @@
     }
 
     public void removeSource(PhoneAccountHandle phoneAccount) {
-        VoicemailContract.Status.setStatus(mContext, phoneAccount,
-                VoicemailContract.Status.CONFIGURATION_STATE_NOT_CONFIGURED,
-                VoicemailContract.Status.DATA_CHANNEL_STATE_NO_CONNECTION,
-                VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
+        VoicemailStatus.edit(mContext, phoneAccount)
+                .setConfigurationState(Status.CONFIGURATION_STATE_NOT_CONFIGURED)
+                .setDataChannelState(Status.DATA_CHANNEL_STATE_NO_CONNECTION)
+                .setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION)
+                .apply();
         removePhoneStateListener(phoneAccount);
         mActiveVvmSources.remove(phoneAccount);
         OmtpVvmSyncService.cancelAllRetries(mContext, phoneAccount);
diff --git a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
index e44904b..d140936 100644
--- a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
+++ b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
@@ -31,7 +31,7 @@
 import android.util.Log;
 
 import com.android.phone.PhoneUtils;
-import com.android.phone.VoicemailUtils;
+import com.android.phone.VoicemailStatus;
 import com.android.phone.settings.VisualVoicemailSettingsUtil;
 import com.android.phone.vvm.omtp.LocalLogHelper;
 import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
@@ -219,10 +219,7 @@
                  *  finished
                  *  b/26937720
                  */
-                Status.setStatus(this, phoneAccount,
-                        Status.CONFIGURATION_STATE_IGNORE,
-                        Status.DATA_CHANNEL_STATE_IGNORE,
-                        Status.NOTIFICATION_CHANNEL_STATE_IGNORE);
+                VoicemailStatus.edit(this, phoneAccount).apply();
                 return;
             }
             VisualVoicemailSettingsUtil.setVisualVoicemailLastFullSyncTime(
@@ -265,8 +262,10 @@
                     // Nothing more to do here, just exit.
                     VisualVoicemailSettingsUtil.resetVisualVoicemailRetryInterval(this,
                             phoneAccount);
-                    VoicemailUtils.setDataChannelState(
-                            this, phoneAccount, Status.DATA_CHANNEL_STATE_OK);
+
+                    VoicemailStatus.edit(this, phoneAccount)
+                            .setDataChannelState(Status.DATA_CHANNEL_STATE_OK)
+                            .apply();
                     return;
                 }
             }
diff --git a/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java b/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java
index 884bec9..1c1c243 100644
--- a/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java
+++ b/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java
@@ -23,13 +23,12 @@
 import android.net.NetworkRequest;
 import android.os.Handler;
 import android.os.Looper;
-import android.provider.VoicemailContract;
 import android.provider.VoicemailContract.Status;
 import android.telecom.PhoneAccountHandle;
 import android.util.Log;
 
 import com.android.phone.PhoneUtils;
-import com.android.phone.VoicemailUtils;
+import com.android.phone.VoicemailStatus;
 import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
 
 /**
@@ -147,12 +146,13 @@
     public void onFailed(String reason) {
         Log.d(TAG, "onFailed: " + reason);
         if (mCarrierConfigHelper.isCellularDataRequired()) {
-            VoicemailUtils.setDataChannelState(
-                    mContext, mPhoneAccount,
-                    Status.DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED);
+            VoicemailStatus.edit(mContext, mPhoneAccount)
+                    .setDataChannelState(Status.DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED)
+                    .apply();
         } else {
-            VoicemailUtils.setDataChannelState(
-                    mContext, mPhoneAccount, Status.DATA_CHANNEL_STATE_NO_CONNECTION);
+            VoicemailStatus.edit(mContext, mPhoneAccount)
+                    .setDataChannelState(Status.DATA_CHANNEL_STATE_NO_CONNECTION)
+                    .apply();
         }
         releaseNetwork();
     }