Don't transcribe voicemail unless carrier allows OTT transcription

Added a carrier config and check to see if the carrier allows over
the top voicemail transcription, and if not do not attempt transcription.

Bug: 68951869
Test: manual and unit test
PiperOrigin-RevId: 176065849
Change-Id: I69df1f2867420d7fdcc7f0a31e0e6c26da67abb1
diff --git a/java/com/android/dialer/app/voicemail/error/VoicemailTosMessageCreator.java b/java/com/android/dialer/app/voicemail/error/VoicemailTosMessageCreator.java
index 1092175..3e43213 100644
--- a/java/com/android/dialer/app/voicemail/error/VoicemailTosMessageCreator.java
+++ b/java/com/android/dialer/app/voicemail/error/VoicemailTosMessageCreator.java
@@ -347,7 +347,12 @@
           .putInt(PREF_DIALER_TOS_VERSION_ACCEPTED_KEY, CURRENT_DIALER_TOS_VERSION)
           .apply();
     }
-    VoicemailComponent.get(context).getVoicemailClient().onTosAccepted(context);
+
+    PhoneAccountHandle handle =
+        new PhoneAccountHandle(
+            ComponentName.unflattenFromString(status.phoneAccountComponentName),
+            status.phoneAccountId);
+    VoicemailComponent.get(context).getVoicemailClient().onTosAccepted(context, handle);
   }
 
   private boolean hasAcknowledgedFeatures() {
diff --git a/java/com/android/voicemail/CarrierConfigKeys.java b/java/com/android/voicemail/CarrierConfigKeys.java
new file mode 100644
index 0000000..609221d
--- /dev/null
+++ b/java/com/android/voicemail/CarrierConfigKeys.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 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.voicemail;
+
+/**
+ * Keys used to lookup carrier specific configuration strings. See {@code
+ * VoicemailClient.getCarrierConfigString}
+ */
+public interface CarrierConfigKeys {
+
+  /**
+   * Carrier config key whose value will be 'true' for carriers that allow over the top voicemail
+   * transcription.
+   */
+  String VVM_CARRIER_ALLOWS_OTT_TRANSCRIPTION_STRING =
+      "vvm_carrier_allows_ott_transcription_string";
+}
diff --git a/java/com/android/voicemail/VoicemailClient.java b/java/com/android/voicemail/VoicemailClient.java
index 050286a..db5d745 100644
--- a/java/com/android/voicemail/VoicemailClient.java
+++ b/java/com/android/voicemail/VoicemailClient.java
@@ -177,5 +177,12 @@
   /** Provides interface to change the PIN used to access the mailbox by calling. */
   PinChanger createPinChanger(Context context, PhoneAccountHandle phoneAccountHandle);
 
-  void onTosAccepted(Context context);
+  void onTosAccepted(Context context, PhoneAccountHandle phoneAccountHandle);
+
+  /**
+   * @return arbitrary carrier configuration String value associate with the indicated key. See
+   *     {@code CarrierConfigKeys.java}
+   */
+  @Nullable
+  String getCarrierConfigString(Context context, PhoneAccountHandle phoneAccountHandle, String key);
 }
diff --git a/java/com/android/voicemail/impl/VoicemailClientImpl.java b/java/com/android/voicemail/impl/VoicemailClientImpl.java
index 2add59e..3305438 100644
--- a/java/com/android/voicemail/impl/VoicemailClientImpl.java
+++ b/java/com/android/voicemail/impl/VoicemailClientImpl.java
@@ -22,6 +22,7 @@
 import android.provider.VoicemailContract.Voicemails;
 import android.support.annotation.MainThread;
 import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.support.v4.os.BuildCompat;
 import android.telecom.PhoneAccountHandle;
 import android.telephony.TelephonyManager;
@@ -285,8 +286,15 @@
   }
 
   @Override
-  public void onTosAccepted(Context context) {
+  public void onTosAccepted(Context context, PhoneAccountHandle account) {
     LogUtil.i("VoicemailClientImpl.onTosAccepted", "try backfilling voicemail transcriptions");
-    TranscriptionBackfillService.scheduleTask(context);
+    TranscriptionBackfillService.scheduleTask(context, account);
+  }
+
+  @Override
+  @Nullable
+  public String getCarrierConfigString(Context context, PhoneAccountHandle account, String key) {
+    OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(context, account);
+    return helper.isValid() ? helper.getString(key) : null;
   }
 }
diff --git a/java/com/android/voicemail/impl/res/xml/vvm_config.xml b/java/com/android/voicemail/impl/res/xml/vvm_config.xml
index 1e5190a..499bae2 100644
--- a/java/com/android/voicemail/impl/res/xml/vvm_config.xml
+++ b/java/com/android/voicemail/impl/res/xml/vvm_config.xml
@@ -104,6 +104,7 @@
       <!-- a bug -->
       <item value="AUTH=DIGEST-MD5"/>
     </string-array>
+    <string name="vvm_carrier_allows_ott_transcription_string">true</string>
   </pbundle_as_map>
 
   <pbundle_as_map>
diff --git a/java/com/android/voicemail/impl/transcribe/TranscriptionBackfillService.java b/java/com/android/voicemail/impl/transcribe/TranscriptionBackfillService.java
index f7f6439..8161e71 100644
--- a/java/com/android/voicemail/impl/transcribe/TranscriptionBackfillService.java
+++ b/java/com/android/voicemail/impl/transcribe/TranscriptionBackfillService.java
@@ -25,6 +25,7 @@
 import android.support.annotation.WorkerThread;
 import android.support.v4.app.JobIntentService;
 import android.support.v4.os.BuildCompat;
+import android.telecom.PhoneAccountHandle;
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.common.concurrent.ThreadUtil;
 import com.android.dialer.constants.ScheduledJobIds;
@@ -38,7 +39,7 @@
 public class TranscriptionBackfillService extends JobIntentService {
 
   /** Schedule a task to scan the database for untranscribed voicemails */
-  public static boolean scheduleTask(Context context) {
+  public static boolean scheduleTask(Context context, PhoneAccountHandle account) {
     if (BuildCompat.isAtLeastO()) {
       LogUtil.enterBlock("TranscriptionBackfillService.transcribeOldVoicemails");
       ComponentName componentName = new ComponentName(context, TranscriptionBackfillService.class);
@@ -46,15 +47,17 @@
           new JobInfo.Builder(ScheduledJobIds.VVM_TRANSCRIPTION_BACKFILL_JOB, componentName)
               .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
       JobScheduler scheduler = context.getSystemService(JobScheduler.class);
-      return scheduler.enqueue(builder.build(), makeWorkItem()) == JobScheduler.RESULT_SUCCESS;
+      return scheduler.enqueue(builder.build(), makeWorkItem(account))
+          == JobScheduler.RESULT_SUCCESS;
     } else {
       LogUtil.i("TranscriptionBackfillService.transcribeOldVoicemails", "not supported");
       return false;
     }
   }
 
-  private static JobWorkItem makeWorkItem() {
+  private static JobWorkItem makeWorkItem(PhoneAccountHandle account) {
     Intent intent = new Intent();
+    intent.putExtra(TranscriptionService.EXTRA_ACCOUNT_HANDLE, account);
     return new JobWorkItem(intent);
   }
 
diff --git a/java/com/android/voicemail/impl/transcribe/TranscriptionService.java b/java/com/android/voicemail/impl/transcribe/TranscriptionService.java
index 79e1a01..33c9676 100644
--- a/java/com/android/voicemail/impl/transcribe/TranscriptionService.java
+++ b/java/com/android/voicemail/impl/transcribe/TranscriptionService.java
@@ -24,10 +24,9 @@
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
+import android.os.Build;
 import android.support.annotation.MainThread;
-import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
-import android.support.v4.os.BuildCompat;
 import android.telecom.PhoneAccountHandle;
 import android.text.TextUtils;
 import com.android.dialer.common.Assert;
@@ -35,6 +34,9 @@
 import com.android.dialer.constants.ScheduledJobIds;
 import com.android.dialer.logging.DialerImpression;
 import com.android.dialer.logging.Logger;
+import com.android.voicemail.CarrierConfigKeys;
+import com.android.voicemail.VoicemailClient;
+import com.android.voicemail.VoicemailComponent;
 import com.android.voicemail.impl.transcribe.grpc.TranscriptionClientFactory;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -65,34 +67,46 @@
   // donation.
   @MainThread
   public static boolean scheduleNewVoicemailTranscriptionJob(
-      Context context,
-      Uri voicemailUri,
-      @Nullable PhoneAccountHandle account,
-      boolean highPriority) {
+      Context context, Uri voicemailUri, PhoneAccountHandle account, boolean highPriority) {
     Assert.isMainThread();
-    if (BuildCompat.isAtLeastO()) {
+    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
       LogUtil.i(
-          "TranscriptionService.scheduleNewVoicemailTranscriptionJob", "scheduling transcription");
-      Logger.get(context).logImpression(DialerImpression.Type.VVM_TRANSCRIPTION_VOICEMAIL_RECEIVED);
-
-      ComponentName componentName = new ComponentName(context, TranscriptionService.class);
-      JobInfo.Builder builder =
-          new JobInfo.Builder(ScheduledJobIds.VVM_TRANSCRIPTION_JOB, componentName);
-      if (highPriority) {
-        builder
-            .setMinimumLatency(0)
-            .setOverrideDeadline(0)
-            .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
-      } else {
-        builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
-      }
-      JobScheduler scheduler = context.getSystemService(JobScheduler.class);
-      JobWorkItem workItem = makeWorkItem(voicemailUri, account);
-      return scheduler.enqueue(builder.build(), workItem) == JobScheduler.RESULT_SUCCESS;
-    } else {
-      LogUtil.i("TranscriptionService.scheduleNewVoicemailTranscriptionJob", "not supported");
+          "TranscriptionService.scheduleNewVoicemailTranscriptionJob", "not supported by sdk");
       return false;
     }
+    if (!carrierAllowsOttTranscription(context, account)) {
+      LogUtil.i(
+          "TranscriptionService.scheduleNewVoicemailTranscriptionJob",
+          "carrier doesn't allow transcription");
+      return false;
+    }
+
+    LogUtil.i(
+        "TranscriptionService.scheduleNewVoicemailTranscriptionJob", "scheduling transcription");
+    Logger.get(context).logImpression(DialerImpression.Type.VVM_TRANSCRIPTION_VOICEMAIL_RECEIVED);
+
+    ComponentName componentName = new ComponentName(context, TranscriptionService.class);
+    JobInfo.Builder builder =
+        new JobInfo.Builder(ScheduledJobIds.VVM_TRANSCRIPTION_JOB, componentName);
+    if (highPriority) {
+      builder
+          .setMinimumLatency(0)
+          .setOverrideDeadline(0)
+          .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
+    } else {
+      builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
+    }
+    JobScheduler scheduler = context.getSystemService(JobScheduler.class);
+    JobWorkItem workItem = makeWorkItem(voicemailUri, account);
+    return scheduler.enqueue(builder.build(), workItem) == JobScheduler.RESULT_SUCCESS;
+  }
+
+  private static boolean carrierAllowsOttTranscription(
+      Context context, PhoneAccountHandle account) {
+    VoicemailClient client = VoicemailComponent.get(context).getVoicemailClient();
+    return Boolean.parseBoolean(
+        client.getCarrierConfigString(
+            context, account, CarrierConfigKeys.VVM_CARRIER_ALLOWS_OTT_TRANSCRIPTION_STRING));
   }
 
   // Cancel all transcription tasks
diff --git a/java/com/android/voicemail/stub/StubVoicemailClient.java b/java/com/android/voicemail/stub/StubVoicemailClient.java
index fe06324..cfbb3ec 100644
--- a/java/com/android/voicemail/stub/StubVoicemailClient.java
+++ b/java/com/android/voicemail/stub/StubVoicemailClient.java
@@ -130,5 +130,11 @@
   }
 
   @Override
-  public void onTosAccepted(Context context) {}
+  public void onTosAccepted(Context context, PhoneAccountHandle account) {}
+
+  @Override
+  @Nullable
+  public String getCarrierConfigString(Context context, PhoneAccountHandle account, String key) {
+    return null;
+  }
 }