Refactoring and adding TOS check before transcribing

This cl just adds a check before starting a transcription job
to verify that the user has accepted the appropriate TOS. Its
a rather big cl just because it had to expose some TOS acceptance
details that were previously encapsulated in the VoicemailTosMessageCreator.

Bug: 69267260
Test: manual and unit tests
PiperOrigin-RevId: 176132370
Change-Id: Ic28fb197a07f9df7a9b5f1729c84566cba0890fc
diff --git a/java/com/android/dialer/app/voicemail/error/AndroidManifest.xml b/java/com/android/dialer/app/voicemail/error/AndroidManifest.xml
index bb6c55f..07cb77f 100644
--- a/java/com/android/dialer/app/voicemail/error/AndroidManifest.xml
+++ b/java/com/android/dialer/app/voicemail/error/AndroidManifest.xml
@@ -18,12 +18,4 @@
 
   <uses-permission android:name="android.permission.CALL_PHONE"/>
 
-  <application>
-    <receiver android:name=".PackageReplacedReceiver" android:exported="false">
-      <intent-filter>
-        <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
-      </intent-filter>
-    </receiver>
-  </application>
-
 </manifest>
diff --git a/java/com/android/dialer/app/voicemail/error/PackageReplacedReceiver.java b/java/com/android/dialer/app/voicemail/error/PackageReplacedReceiver.java
deleted file mode 100644
index 64d72b1..0000000
--- a/java/com/android/dialer/app/voicemail/error/PackageReplacedReceiver.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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.dialer.app.voicemail.error;
-
-import android.annotation.TargetApi;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.net.Uri;
-import android.preference.PreferenceManager;
-import android.provider.CallLog.Calls;
-import android.provider.VoicemailContract.Voicemails;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.common.concurrent.DialerExecutor.Worker;
-import com.android.dialer.common.concurrent.DialerExecutorComponent;
-
-/** Receives MY_PACKAGE_REPLACED to check for legacy voicemail users. */
-public class PackageReplacedReceiver extends BroadcastReceiver {
-
-  @Override
-  public void onReceive(Context context, Intent intent) {
-    LogUtil.enterBlock("PackageReplacedReceiver.onReceive");
-
-    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-    if (!prefs.contains(VoicemailTosMessageCreator.PREF_DIALER_FEATURE_VERSION_ACKNOWLEDGED_KEY)) {
-      setVoicemailFeatureVersionAsync(context);
-    }
-  }
-
-  private void setVoicemailFeatureVersionAsync(Context context) {
-    LogUtil.enterBlock("PackageReplacedReceiver.setVoicemailFeatureVersionAsync");
-
-    // Check if user is already using voicemail (ie do they have any voicemails), and set the
-    // acknowledged feature value accordingly.
-    PendingResult pendingResult = goAsync();
-    DialerExecutorComponent.get(context)
-        .dialerExecutorFactory()
-        .createNonUiTaskBuilder(new ExistingVoicemailCheck(context))
-        .onSuccess(
-            output -> {
-              LogUtil.i("PackageReplacedReceiver.setVoicemailFeatureVersionAsync", "success");
-              pendingResult.finish();
-            })
-        .onFailure(
-            throwable -> {
-              LogUtil.i("PackageReplacedReceiver.setVoicemailFeatureVersionAsync", "failure");
-              pendingResult.finish();
-            })
-        .build()
-        .executeParallel(null);
-  }
-
-  private static class ExistingVoicemailCheck implements Worker<Void, Void> {
-    private static final String[] PROJECTION = new String[] {Voicemails._ID};
-
-    private final Context context;
-
-    ExistingVoicemailCheck(Context context) {
-      this.context = context;
-    }
-
-    @TargetApi(android.os.Build.VERSION_CODES.M) // used for try with resources
-    @Override
-    public Void doInBackground(Void arg) throws Throwable {
-      LogUtil.i("PackageReplacedReceiver.ExistingVoicemailCheck.doInBackground", "");
-
-      // Check the database for existing voicemails.
-      boolean hasVoicemails = false;
-      Uri uri = Voicemails.buildSourceUri(context.getPackageName());
-      String whereClause = Calls.TYPE + " = " + Calls.VOICEMAIL_TYPE;
-      try (Cursor cursor =
-          context.getContentResolver().query(uri, PROJECTION, whereClause, null, null)) {
-        if (cursor == null) {
-          LogUtil.e(
-              "PackageReplacedReceiver.ExistingVoicemailCheck.doInBackground",
-              "failed to check for existing voicemails");
-        } else if (cursor.moveToNext()) {
-          hasVoicemails = true;
-        }
-      }
-
-      LogUtil.i(
-          "PackageReplacedReceiver.ExistingVoicemailCheck.doInBackground",
-          "has voicemails: " + hasVoicemails);
-      int version = hasVoicemails ? VoicemailTosMessageCreator.LEGACY_VOICEMAIL_FEATURE_VERSION : 0;
-      PreferenceManager.getDefaultSharedPreferences(context)
-          .edit()
-          .putInt(VoicemailTosMessageCreator.PREF_DIALER_FEATURE_VERSION_ACKNOWLEDGED_KEY, version)
-          .apply();
-      return null;
-    }
-  }
-}
diff --git a/java/com/android/dialer/app/voicemail/error/VoicemailTosMessageCreator.java b/java/com/android/dialer/app/voicemail/error/VoicemailTosMessageCreator.java
index 3e43213..b7c8ed7 100644
--- a/java/com/android/dialer/app/voicemail/error/VoicemailTosMessageCreator.java
+++ b/java/com/android/dialer/app/voicemail/error/VoicemailTosMessageCreator.java
@@ -48,6 +48,7 @@
 import com.android.voicemail.VisualVoicemailTypeExtensions;
 import com.android.voicemail.VoicemailClient;
 import com.android.voicemail.VoicemailComponent;
+import com.android.voicemail.VoicemailVersionConstants;
 import java.util.Locale;
 
 /**
@@ -55,22 +56,6 @@
  * terms of service for Verizon and for other carriers.
  */
 public class VoicemailTosMessageCreator {
-  // Preference key to check which version of the Verizon ToS that the user has accepted.
-  static final String PREF_VVM3_TOS_VERSION_ACCEPTED_KEY = "vvm3_tos_version_accepted";
-
-  // Preference key to check which version of the Google Dialer ToS that the user has accepted.
-  static final String PREF_DIALER_TOS_VERSION_ACCEPTED_KEY = "dialer_tos_version_accepted";
-
-  // Preference key to check which feature version the user has acknowledged
-  static final String PREF_DIALER_FEATURE_VERSION_ACKNOWLEDGED_KEY =
-      "dialer_feature_version_acknowledged";
-
-  static final int CURRENT_VVM3_TOS_VERSION = 2;
-  static final int CURRENT_DIALER_TOS_VERSION = 1;
-  static final int LEGACY_VOICEMAIL_FEATURE_VERSION = 1; // original visual voicemail
-  static final int TRANSCRIPTION_VOICEMAIL_FEATURE_VERSION = 2; // adds voicemail transcription
-  static final int CURRENT_VOICEMAIL_FEATURE_VERSION = TRANSCRIPTION_VOICEMAIL_FEATURE_VERSION;
-
   private static final String ISO639_SPANISH = "es";
 
   private final Context context;
@@ -328,10 +313,11 @@
 
   private boolean hasAcceptedTos() {
     if (isVvm3()) {
-      return preferences.getInt(PREF_VVM3_TOS_VERSION_ACCEPTED_KEY, 0) >= CURRENT_VVM3_TOS_VERSION;
+      return preferences.getInt(VoicemailVersionConstants.PREF_VVM3_TOS_VERSION_ACCEPTED_KEY, 0)
+          >= VoicemailVersionConstants.CURRENT_VVM3_TOS_VERSION;
     } else {
-      return preferences.getInt(PREF_DIALER_TOS_VERSION_ACCEPTED_KEY, 0)
-          >= CURRENT_DIALER_TOS_VERSION;
+      return preferences.getInt(VoicemailVersionConstants.PREF_DIALER_TOS_VERSION_ACCEPTED_KEY, 0)
+          >= VoicemailVersionConstants.CURRENT_DIALER_TOS_VERSION;
     }
   }
 
@@ -339,12 +325,16 @@
     if (isVvm3()) {
       preferences
           .edit()
-          .putInt(PREF_VVM3_TOS_VERSION_ACCEPTED_KEY, CURRENT_VVM3_TOS_VERSION)
+          .putInt(
+              VoicemailVersionConstants.PREF_VVM3_TOS_VERSION_ACCEPTED_KEY,
+              VoicemailVersionConstants.CURRENT_VVM3_TOS_VERSION)
           .apply();
     } else {
       preferences
           .edit()
-          .putInt(PREF_DIALER_TOS_VERSION_ACCEPTED_KEY, CURRENT_DIALER_TOS_VERSION)
+          .putInt(
+              VoicemailVersionConstants.PREF_DIALER_TOS_VERSION_ACCEPTED_KEY,
+              VoicemailVersionConstants.CURRENT_DIALER_TOS_VERSION)
           .apply();
     }
 
@@ -360,20 +350,24 @@
       return true;
     }
 
-    return preferences.getInt(PREF_DIALER_FEATURE_VERSION_ACKNOWLEDGED_KEY, 0)
-        >= CURRENT_VOICEMAIL_FEATURE_VERSION;
+    return preferences.getInt(
+            VoicemailVersionConstants.PREF_DIALER_FEATURE_VERSION_ACKNOWLEDGED_KEY, 0)
+        >= VoicemailVersionConstants.CURRENT_VOICEMAIL_FEATURE_VERSION;
   }
 
   private void recordFeatureAcknowledgement() {
     preferences
         .edit()
-        .putInt(PREF_DIALER_FEATURE_VERSION_ACKNOWLEDGED_KEY, CURRENT_VOICEMAIL_FEATURE_VERSION)
+        .putInt(
+            VoicemailVersionConstants.PREF_DIALER_FEATURE_VERSION_ACKNOWLEDGED_KEY,
+            VoicemailVersionConstants.CURRENT_VOICEMAIL_FEATURE_VERSION)
         .apply();
   }
 
   private boolean isLegacyVoicemailUser() {
-    return preferences.getInt(PREF_DIALER_FEATURE_VERSION_ACKNOWLEDGED_KEY, 0)
-        == LEGACY_VOICEMAIL_FEATURE_VERSION;
+    return preferences.getInt(
+            VoicemailVersionConstants.PREF_DIALER_FEATURE_VERSION_ACKNOWLEDGED_KEY, 0)
+        == VoicemailVersionConstants.LEGACY_VOICEMAIL_FEATURE_VERSION;
   }
 
   private void logTosCreatedImpression() {
diff --git a/java/com/android/voicemail/VoicemailClient.java b/java/com/android/voicemail/VoicemailClient.java
index db5d745..1ce7ef7 100644
--- a/java/com/android/voicemail/VoicemailClient.java
+++ b/java/com/android/voicemail/VoicemailClient.java
@@ -179,6 +179,8 @@
 
   void onTosAccepted(Context context, PhoneAccountHandle phoneAccountHandle);
 
+  boolean hasAcceptedTos(Context context, PhoneAccountHandle phoneAccountHandle);
+
   /**
    * @return arbitrary carrier configuration String value associate with the indicated key. See
    *     {@code CarrierConfigKeys.java}
diff --git a/java/com/android/voicemail/VoicemailVersionConstants.java b/java/com/android/voicemail/VoicemailVersionConstants.java
new file mode 100644
index 0000000..44ef661
--- /dev/null
+++ b/java/com/android/voicemail/VoicemailVersionConstants.java
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+/**
+ * Shared preference keys and values relating to the voicemail version that the user has accepted.
+ * Note: these can be carrier dependent.
+ */
+public interface VoicemailVersionConstants {
+  // Preference key to check which version of the Verizon ToS that the user has accepted.
+  String PREF_VVM3_TOS_VERSION_ACCEPTED_KEY = "vvm3_tos_version_accepted";
+
+  // Preference key to check which version of the Google Dialer ToS that the user has accepted.
+  String PREF_DIALER_TOS_VERSION_ACCEPTED_KEY = "dialer_tos_version_accepted";
+
+  // Preference key to check which feature version the user has acknowledged
+  String PREF_DIALER_FEATURE_VERSION_ACKNOWLEDGED_KEY = "dialer_feature_version_acknowledged";
+
+  int CURRENT_VVM3_TOS_VERSION = 2;
+  int CURRENT_DIALER_TOS_VERSION = 1;
+  int LEGACY_VOICEMAIL_FEATURE_VERSION = 1; // original visual voicemail
+  int TRANSCRIPTION_VOICEMAIL_FEATURE_VERSION = 2;
+  int CURRENT_VOICEMAIL_FEATURE_VERSION = TRANSCRIPTION_VOICEMAIL_FEATURE_VERSION;
+}
diff --git a/java/com/android/voicemail/impl/PackageReplacedReceiver.java b/java/com/android/voicemail/impl/PackageReplacedReceiver.java
index 6a7ca4a..bc56286 100644
--- a/java/com/android/voicemail/impl/PackageReplacedReceiver.java
+++ b/java/com/android/voicemail/impl/PackageReplacedReceiver.java
@@ -16,14 +16,27 @@
 
 package com.android.voicemail.impl;
 
+import android.annotation.TargetApi;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.net.Uri;
+import android.preference.PreferenceManager;
+import android.provider.CallLog.Calls;
+import android.provider.VoicemailContract.Voicemails;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.common.concurrent.DialerExecutor.Worker;
+import com.android.dialer.common.concurrent.DialerExecutorComponent;
 import com.android.voicemail.VoicemailComponent;
+import com.android.voicemail.VoicemailVersionConstants;
 
-/** Receives MY_PACKAGE_REPLACED to trigger VVM activation. */
+/**
+ * Receives MY_PACKAGE_REPLACED to trigger VVM activation and to check for legacy voicemail users.
+ */
 public class PackageReplacedReceiver extends BroadcastReceiver {
 
   @Override
@@ -39,5 +52,74 @@
         context.getSystemService(TelecomManager.class).getCallCapablePhoneAccounts()) {
       ActivationTask.start(context, phoneAccountHandle, null);
     }
+
+    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+    if (!prefs.contains(VoicemailVersionConstants.PREF_DIALER_FEATURE_VERSION_ACKNOWLEDGED_KEY)) {
+      setVoicemailFeatureVersionAsync(context);
+    }
+  }
+
+  private void setVoicemailFeatureVersionAsync(Context context) {
+    LogUtil.enterBlock("PackageReplacedReceiver.setVoicemailFeatureVersionAsync");
+
+    // Check if user is already using voicemail (ie do they have any voicemails), and set the
+    // acknowledged feature value accordingly.
+    PendingResult pendingResult = goAsync();
+    DialerExecutorComponent.get(context)
+        .dialerExecutorFactory()
+        .createNonUiTaskBuilder(new ExistingVoicemailCheck(context))
+        .onSuccess(
+            output -> {
+              LogUtil.i("PackageReplacedReceiver.setVoicemailFeatureVersionAsync", "success");
+              pendingResult.finish();
+            })
+        .onFailure(
+            throwable -> {
+              LogUtil.i("PackageReplacedReceiver.setVoicemailFeatureVersionAsync", "failure");
+              pendingResult.finish();
+            })
+        .build()
+        .executeParallel(null);
+  }
+
+  private static class ExistingVoicemailCheck implements Worker<Void, Void> {
+    private static final String[] PROJECTION = new String[] {Voicemails._ID};
+
+    private final Context context;
+
+    ExistingVoicemailCheck(Context context) {
+      this.context = context;
+    }
+
+    @TargetApi(android.os.Build.VERSION_CODES.M) // used for try with resources
+    @Override
+    public Void doInBackground(Void arg) throws Throwable {
+      LogUtil.i("PackageReplacedReceiver.ExistingVoicemailCheck.doInBackground", "");
+
+      // Check the database for existing voicemails.
+      boolean hasVoicemails = false;
+      Uri uri = Voicemails.buildSourceUri(context.getPackageName());
+      String whereClause = Calls.TYPE + " = " + Calls.VOICEMAIL_TYPE;
+      try (Cursor cursor =
+          context.getContentResolver().query(uri, PROJECTION, whereClause, null, null)) {
+        if (cursor == null) {
+          LogUtil.e(
+              "PackageReplacedReceiver.ExistingVoicemailCheck.doInBackground",
+              "failed to check for existing voicemails");
+        } else if (cursor.moveToFirst()) {
+          hasVoicemails = true;
+        }
+      }
+
+      LogUtil.i(
+          "PackageReplacedReceiver.ExistingVoicemailCheck.doInBackground",
+          "has voicemails: " + hasVoicemails);
+      int version = hasVoicemails ? VoicemailVersionConstants.LEGACY_VOICEMAIL_FEATURE_VERSION : 0;
+      PreferenceManager.getDefaultSharedPreferences(context)
+          .edit()
+          .putInt(VoicemailVersionConstants.PREF_DIALER_FEATURE_VERSION_ACKNOWLEDGED_KEY, version)
+          .apply();
+      return null;
+    }
   }
 }
diff --git a/java/com/android/voicemail/impl/VoicemailClientImpl.java b/java/com/android/voicemail/impl/VoicemailClientImpl.java
index 3305438..60fc806 100644
--- a/java/com/android/voicemail/impl/VoicemailClientImpl.java
+++ b/java/com/android/voicemail/impl/VoicemailClientImpl.java
@@ -16,8 +16,10 @@
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.os.Build.VERSION_CODES;
 import android.os.PersistableBundle;
+import android.preference.PreferenceManager;
 import android.provider.VoicemailContract.Status;
 import android.provider.VoicemailContract.Voicemails;
 import android.support.annotation.MainThread;
@@ -32,6 +34,7 @@
 import com.android.voicemail.PinChanger;
 import com.android.voicemail.VisualVoicemailTypeExtensions;
 import com.android.voicemail.VoicemailClient;
+import com.android.voicemail.VoicemailVersionConstants;
 import com.android.voicemail.impl.configui.VoicemailSecretCodeActivity;
 import com.android.voicemail.impl.settings.VisualVoicemailSettingsUtil;
 import com.android.voicemail.impl.sync.VvmAccountManager;
@@ -292,6 +295,21 @@
   }
 
   @Override
+  public boolean hasAcceptedTos(Context context, PhoneAccountHandle phoneAccountHandle) {
+    SharedPreferences preferences =
+        PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
+    OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(context, phoneAccountHandle);
+    boolean isVvm3 = VisualVoicemailTypeExtensions.VVM_TYPE_VVM3.equals(helper.getVvmType());
+    if (isVvm3) {
+      return preferences.getInt(VoicemailVersionConstants.PREF_VVM3_TOS_VERSION_ACCEPTED_KEY, 0)
+          >= VoicemailVersionConstants.CURRENT_VVM3_TOS_VERSION;
+    } else {
+      return preferences.getInt(VoicemailVersionConstants.PREF_DIALER_TOS_VERSION_ACCEPTED_KEY, 0)
+          >= VoicemailVersionConstants.CURRENT_DIALER_TOS_VERSION;
+    }
+  }
+
+  @Override
   @Nullable
   public String getCarrierConfigString(Context context, PhoneAccountHandle account, String key) {
     OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(context, account);
diff --git a/java/com/android/voicemail/impl/transcribe/TranscriptionService.java b/java/com/android/voicemail/impl/transcribe/TranscriptionService.java
index 33c9676..a19ab62 100644
--- a/java/com/android/voicemail/impl/transcribe/TranscriptionService.java
+++ b/java/com/android/voicemail/impl/transcribe/TranscriptionService.java
@@ -69,15 +69,7 @@
   public static boolean scheduleNewVoicemailTranscriptionJob(
       Context context, Uri voicemailUri, PhoneAccountHandle account, boolean highPriority) {
     Assert.isMainThread();
-    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
-      LogUtil.i(
-          "TranscriptionService.scheduleNewVoicemailTranscriptionJob", "not supported by sdk");
-      return false;
-    }
-    if (!carrierAllowsOttTranscription(context, account)) {
-      LogUtil.i(
-          "TranscriptionService.scheduleNewVoicemailTranscriptionJob",
-          "carrier doesn't allow transcription");
+    if (!canTranscribeVoicemail(context, account)) {
       return false;
     }
 
@@ -101,12 +93,24 @@
     return scheduler.enqueue(builder.build(), workItem) == JobScheduler.RESULT_SUCCESS;
   }
 
-  private static boolean carrierAllowsOttTranscription(
-      Context context, PhoneAccountHandle account) {
+  private static boolean canTranscribeVoicemail(Context context, PhoneAccountHandle account) {
+    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+      LogUtil.i("TranscriptionService.canTranscribeVoicemail", "not supported by sdk");
+      return false;
+    }
     VoicemailClient client = VoicemailComponent.get(context).getVoicemailClient();
-    return Boolean.parseBoolean(
+    if (!client.hasAcceptedTos(context, account)) {
+      LogUtil.i("TranscriptionService.canTranscribeVoicemail", "hasn't accepted TOS");
+      return false;
+    }
+    if (!Boolean.parseBoolean(
         client.getCarrierConfigString(
-            context, account, CarrierConfigKeys.VVM_CARRIER_ALLOWS_OTT_TRANSCRIPTION_STRING));
+            context, account, CarrierConfigKeys.VVM_CARRIER_ALLOWS_OTT_TRANSCRIPTION_STRING))) {
+      LogUtil.i(
+          "TranscriptionService.canTranscribeVoicemail", "carrier doesn't allow transcription");
+      return false;
+    }
+    return true;
   }
 
   // Cancel all transcription tasks
diff --git a/java/com/android/voicemail/stub/StubVoicemailClient.java b/java/com/android/voicemail/stub/StubVoicemailClient.java
index cfbb3ec..3069ea4 100644
--- a/java/com/android/voicemail/stub/StubVoicemailClient.java
+++ b/java/com/android/voicemail/stub/StubVoicemailClient.java
@@ -133,6 +133,11 @@
   public void onTosAccepted(Context context, PhoneAccountHandle account) {}
 
   @Override
+  public boolean hasAcceptedTos(Context context, PhoneAccountHandle phoneAccountHandle) {
+    return false;
+  }
+
+  @Override
   @Nullable
   public String getCarrierConfigString(Context context, PhoneAccountHandle account, String key) {
     return null;