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