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.sync; 17 18 import android.content.Context; 19 import android.support.annotation.MainThread; 20 import android.support.annotation.NonNull; 21 import android.telecom.PhoneAccountHandle; 22 import android.telecom.TelecomManager; 23 import android.util.ArraySet; 24 import com.android.dialer.common.Assert; 25 import com.android.dialer.common.concurrent.ThreadUtil; 26 import com.android.voicemail.impl.OmtpConstants; 27 import com.android.voicemail.impl.VisualVoicemailPreferences; 28 import com.android.voicemail.impl.VoicemailStatus; 29 import com.android.voicemail.impl.sms.StatusMessage; 30 import java.util.ArrayList; 31 import java.util.List; 32 import java.util.Set; 33 34 /** 35 * Tracks the activation state of a visual voicemail phone account. An account is considered 36 * activated if it has valid connection information from the {@link StatusMessage} stored on the 37 * device. Once activation/provisioning is completed, {@link #addAccount(Context, 38 * PhoneAccountHandle, StatusMessage)} should be called to store the connection information. When an 39 * account is removed or if the connection information is deemed invalid, {@link 40 * #removeAccount(Context, PhoneAccountHandle)} should be called to clear the connection information 41 * and allow reactivation. 42 */ 43 public class VvmAccountManager { 44 public static final String TAG = "VvmAccountManager"; 45 46 /** Listener for activation state changes. Will be called on the main thread. */ 47 public interface Listener { 48 @MainThread onActivationStateChanged(PhoneAccountHandle phoneAccountHandle, boolean isActivated)49 void onActivationStateChanged(PhoneAccountHandle phoneAccountHandle, boolean isActivated); 50 } 51 52 private static final String IS_ACCOUNT_ACTIVATED = "is_account_activated"; 53 54 private static Set<Listener> listeners = new ArraySet<>(); 55 addAccount( Context context, PhoneAccountHandle phoneAccountHandle, StatusMessage statusMessage)56 public static void addAccount( 57 Context context, PhoneAccountHandle phoneAccountHandle, StatusMessage statusMessage) { 58 VisualVoicemailPreferences preferences = 59 new VisualVoicemailPreferences(context, phoneAccountHandle); 60 statusMessage.putStatus(preferences.edit()).putBoolean(IS_ACCOUNT_ACTIVATED, true).apply(); 61 62 ThreadUtil.postOnUiThread( 63 () -> { 64 for (Listener listener : listeners) { 65 listener.onActivationStateChanged(phoneAccountHandle, true); 66 } 67 }); 68 } 69 removeAccount(Context context, PhoneAccountHandle phoneAccount)70 public static void removeAccount(Context context, PhoneAccountHandle phoneAccount) { 71 VoicemailStatus.disable(context, phoneAccount); 72 VisualVoicemailPreferences preferences = new VisualVoicemailPreferences(context, phoneAccount); 73 preferences 74 .edit() 75 .putBoolean(IS_ACCOUNT_ACTIVATED, false) 76 .putString(OmtpConstants.IMAP_USER_NAME, null) 77 .putString(OmtpConstants.IMAP_PASSWORD, null) 78 .apply(); 79 ThreadUtil.postOnUiThread( 80 () -> { 81 for (Listener listener : listeners) { 82 listener.onActivationStateChanged(phoneAccount, false); 83 } 84 }); 85 } 86 isAccountActivated(Context context, PhoneAccountHandle phoneAccount)87 public static boolean isAccountActivated(Context context, PhoneAccountHandle phoneAccount) { 88 Assert.isNotNull(phoneAccount); 89 VisualVoicemailPreferences preferences = new VisualVoicemailPreferences(context, phoneAccount); 90 return preferences.getBoolean(IS_ACCOUNT_ACTIVATED, false); 91 } 92 93 @NonNull getActiveAccounts(Context context)94 public static List<PhoneAccountHandle> getActiveAccounts(Context context) { 95 List<PhoneAccountHandle> results = new ArrayList<>(); 96 for (PhoneAccountHandle phoneAccountHandle : 97 context.getSystemService(TelecomManager.class).getCallCapablePhoneAccounts()) { 98 if (isAccountActivated(context, phoneAccountHandle)) { 99 results.add(phoneAccountHandle); 100 } 101 } 102 return results; 103 } 104 105 @MainThread addListener(Listener listener)106 public static void addListener(Listener listener) { 107 Assert.isMainThread(); 108 listeners.add(listener); 109 } 110 111 @MainThread removeListener(Listener listener)112 public static void removeListener(Listener listener) { 113 Assert.isMainThread(); 114 listeners.remove(listener); 115 } 116 } 117