1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 package com.android.voicemail.impl.settings; 17 18 import android.content.ContentValues; 19 import android.content.Context; 20 import android.provider.CallLog; 21 import android.provider.CallLog.Calls; 22 import android.provider.VoicemailContract.Voicemails; 23 import android.support.annotation.VisibleForTesting; 24 import android.telecom.PhoneAccountHandle; 25 import com.android.dialer.common.Assert; 26 import com.android.dialer.common.LogUtil; 27 import com.android.dialer.common.concurrent.DialerExecutor.Worker; 28 import com.android.dialer.common.concurrent.DialerExecutorComponent; 29 import com.android.dialer.common.database.Selection; 30 import com.android.dialer.compat.android.provider.VoicemailCompat; 31 import com.android.voicemail.VoicemailComponent; 32 import com.android.voicemail.impl.OmtpVvmCarrierConfigHelper; 33 import com.android.voicemail.impl.VisualVoicemailPreferences; 34 import com.android.voicemail.impl.VvmLog; 35 import com.android.voicemail.impl.sync.VvmAccountManager; 36 37 /** Save whether or not a particular account is enabled in shared to be retrieved later. */ 38 public class VisualVoicemailSettingsUtil { 39 40 @VisibleForTesting public static final String IS_ENABLED_KEY = "is_enabled"; 41 private static final String ARCHIVE_ENABLED_KEY = "archive_is_enabled"; 42 private static final String TRANSCRIBE_VOICEMAILS_KEY = "transcribe_voicemails"; 43 private static final String DONATE_VOICEMAILS_KEY = "donate_voicemails"; 44 setEnabled( Context context, PhoneAccountHandle phoneAccount, boolean isEnabled)45 public static void setEnabled( 46 Context context, PhoneAccountHandle phoneAccount, boolean isEnabled) { 47 VvmLog.i("VisualVoicemailSettingsUtil.setEnable", phoneAccount + " enabled:" + isEnabled); 48 new VisualVoicemailPreferences(context, phoneAccount) 49 .edit() 50 .putBoolean(IS_ENABLED_KEY, isEnabled) 51 .apply(); 52 OmtpVvmCarrierConfigHelper config = new OmtpVvmCarrierConfigHelper(context, phoneAccount); 53 if (isEnabled) { 54 config.startActivation(); 55 } else { 56 VvmAccountManager.removeAccount(context, phoneAccount); 57 config.startDeactivation(); 58 // Remove all voicemails from the database 59 DialerExecutorComponent.get(context) 60 .dialerExecutorFactory() 61 .createNonUiTaskBuilder(new VoicemailDeleteWorker(context)) 62 .onSuccess(VisualVoicemailSettingsUtil::onSuccess) 63 .onFailure(VisualVoicemailSettingsUtil::onFailure) 64 .build() 65 .executeParallel(null); 66 } 67 } 68 onSuccess(Void unused)69 private static void onSuccess(Void unused) { 70 VvmLog.i("VisualVoicemailSettingsUtil.onSuccess", "delete voicemails"); 71 } 72 onFailure(Throwable t)73 private static void onFailure(Throwable t) { 74 VvmLog.e("VisualVoicemailSettingsUtil.onFailure", "delete voicemails", t); 75 } 76 setArchiveEnabled( Context context, PhoneAccountHandle phoneAccount, boolean isEnabled)77 public static void setArchiveEnabled( 78 Context context, PhoneAccountHandle phoneAccount, boolean isEnabled) { 79 Assert.checkArgument( 80 VoicemailComponent.get(context).getVoicemailClient().isVoicemailArchiveAvailable(context)); 81 new VisualVoicemailPreferences(context, phoneAccount) 82 .edit() 83 .putBoolean(ARCHIVE_ENABLED_KEY, isEnabled) 84 .apply(); 85 } 86 setVoicemailTranscriptionEnabled( Context context, PhoneAccountHandle phoneAccount, boolean isEnabled)87 public static void setVoicemailTranscriptionEnabled( 88 Context context, PhoneAccountHandle phoneAccount, boolean isEnabled) { 89 Assert.checkArgument( 90 VoicemailComponent.get(context) 91 .getVoicemailClient() 92 .isVoicemailTranscriptionAvailable(context, phoneAccount)); 93 new VisualVoicemailPreferences(context, phoneAccount) 94 .edit() 95 .putBoolean(TRANSCRIBE_VOICEMAILS_KEY, isEnabled) 96 .apply(); 97 98 if (!isEnabled) { 99 VvmLog.i( 100 "VisualVoicemailSettingsUtil.setVoicemailTranscriptionEnabled", 101 "clear all Google transcribed voicemail."); 102 DialerExecutorComponent.get(context) 103 .dialerExecutorFactory() 104 .createNonUiTaskBuilder(new ClearGoogleTranscribedVoicemailTranscriptionWorker(context)) 105 .onSuccess( 106 (result) -> 107 VvmLog.i( 108 "VisualVoicemailSettingsUtil.setVoicemailTranscriptionEnabled", 109 "voicemail transciptions cleared successfully")) 110 .onFailure( 111 (throwable) -> 112 VvmLog.e( 113 "VisualVoicemailSettingsUtil.setVoicemailTranscriptionEnabled", 114 "unable to clear Google transcribed voicemails", 115 throwable)) 116 .build() 117 .executeParallel(null); 118 } 119 } 120 setVoicemailDonationEnabled( Context context, PhoneAccountHandle phoneAccount, boolean isEnabled)121 public static void setVoicemailDonationEnabled( 122 Context context, PhoneAccountHandle phoneAccount, boolean isEnabled) { 123 Assert.checkArgument( 124 VoicemailComponent.get(context) 125 .getVoicemailClient() 126 .isVoicemailTranscriptionAvailable(context, phoneAccount)); 127 new VisualVoicemailPreferences(context, phoneAccount) 128 .edit() 129 .putBoolean(DONATE_VOICEMAILS_KEY, isEnabled) 130 .apply(); 131 } 132 isEnabled(Context context, PhoneAccountHandle phoneAccount)133 public static boolean isEnabled(Context context, PhoneAccountHandle phoneAccount) { 134 if (phoneAccount == null) { 135 LogUtil.i("VisualVoicemailSettingsUtil.isEnabled", "phone account is null"); 136 return false; 137 } 138 139 VisualVoicemailPreferences prefs = new VisualVoicemailPreferences(context, phoneAccount); 140 if (prefs.contains(IS_ENABLED_KEY)) { 141 // isEnableByDefault is a bit expensive, so don't use it as default value of 142 // getBoolean(). The "false" here should never be actually used. 143 return prefs.getBoolean(IS_ENABLED_KEY, false); 144 } 145 return new OmtpVvmCarrierConfigHelper(context, phoneAccount).isEnabledByDefault(); 146 } 147 isArchiveEnabled(Context context, PhoneAccountHandle phoneAccount)148 public static boolean isArchiveEnabled(Context context, PhoneAccountHandle phoneAccount) { 149 Assert.isNotNull(phoneAccount); 150 151 VisualVoicemailPreferences prefs = new VisualVoicemailPreferences(context, phoneAccount); 152 return prefs.getBoolean(ARCHIVE_ENABLED_KEY, false); 153 } 154 isVoicemailTranscriptionEnabled( Context context, PhoneAccountHandle phoneAccount)155 public static boolean isVoicemailTranscriptionEnabled( 156 Context context, PhoneAccountHandle phoneAccount) { 157 Assert.isNotNull(phoneAccount); 158 159 VisualVoicemailPreferences prefs = new VisualVoicemailPreferences(context, phoneAccount); 160 return prefs.getBoolean(TRANSCRIBE_VOICEMAILS_KEY, false); 161 } 162 isVoicemailDonationEnabled( Context context, PhoneAccountHandle phoneAccount)163 public static boolean isVoicemailDonationEnabled( 164 Context context, PhoneAccountHandle phoneAccount) { 165 Assert.isNotNull(phoneAccount); 166 167 VisualVoicemailPreferences prefs = new VisualVoicemailPreferences(context, phoneAccount); 168 return prefs.getBoolean(DONATE_VOICEMAILS_KEY, false); 169 } 170 171 /** 172 * Whether the client enabled status is explicitly set by user or by default(Whether carrier VVM 173 * app is installed). This is used to determine whether to disable the client when the carrier VVM 174 * app is installed. If the carrier VVM app is installed the client should give priority to it if 175 * the settings are not touched. 176 */ isEnabledUserSet(Context context, PhoneAccountHandle phoneAccount)177 public static boolean isEnabledUserSet(Context context, PhoneAccountHandle phoneAccount) { 178 if (phoneAccount == null) { 179 return false; 180 } 181 VisualVoicemailPreferences prefs = new VisualVoicemailPreferences(context, phoneAccount); 182 return prefs.contains(IS_ENABLED_KEY); 183 } 184 185 /** Delete all the voicemails whose source_package field matches this package */ 186 private static class VoicemailDeleteWorker implements Worker<Void, Void> { 187 private final Context context; 188 VoicemailDeleteWorker(Context context)189 VoicemailDeleteWorker(Context context) { 190 this.context = context; 191 } 192 193 @Override doInBackground(Void unused)194 public Void doInBackground(Void unused) { 195 int deleted = 196 context 197 .getContentResolver() 198 .delete(Voicemails.buildSourceUri(context.getPackageName()), null, null); 199 200 VvmLog.i("VisualVoicemailSettingsUtil.doInBackground", "deleted " + deleted + " voicemails"); 201 return null; 202 } 203 } 204 205 /** 206 * Clears all the voicemail transcripts in the call log whose source_package field matches this 207 * package 208 */ 209 private static class ClearGoogleTranscribedVoicemailTranscriptionWorker 210 implements Worker<Void, Void> { 211 private final Context context; 212 ClearGoogleTranscribedVoicemailTranscriptionWorker(Context context)213 ClearGoogleTranscribedVoicemailTranscriptionWorker(Context context) { 214 this.context = context; 215 } 216 217 @Override doInBackground(Void unused)218 public Void doInBackground(Void unused) { 219 ContentValues contentValues = new ContentValues(); 220 contentValues.putNull(Voicemails.TRANSCRIPTION); 221 contentValues.put( 222 VoicemailCompat.TRANSCRIPTION_STATE, VoicemailCompat.TRANSCRIPTION_NOT_STARTED); 223 224 Selection selection = 225 Selection.builder() 226 .and(Selection.column(CallLog.Calls.TYPE).is("=", Calls.VOICEMAIL_TYPE)) 227 .and(Selection.column(Voicemails.SOURCE_PACKAGE).is("=", context.getPackageName())) 228 .build(); 229 230 int cleared = 231 context 232 .getContentResolver() 233 .update( 234 Calls.CONTENT_URI_WITH_VOICEMAIL, 235 contentValues, 236 selection.getSelection(), 237 selection.getSelectionArgs()); 238 239 VvmLog.i( 240 "VisualVoicemailSettingsUtil.doInBackground", 241 "cleared " + cleared + " voicemail transcription"); 242 return null; 243 } 244 } 245 } 246