• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.phone.vvm.omtp.sync;
17 
18 import android.content.Context;
19 import android.telecom.PhoneAccountHandle;
20 import android.telephony.PhoneStateListener;
21 import android.telephony.SubscriptionManager;
22 import android.telephony.TelephonyManager;
23 import com.android.internal.telephony.Phone;
24 import com.android.phone.PhoneUtils;
25 import com.android.phone.VoicemailStatus;
26 import com.android.phone.vvm.omtp.VvmPhoneStateListener;
27 import java.util.Collections;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.concurrent.ConcurrentHashMap;
31 
32 /**
33  * A singleton class designed to remember the active OMTP visual voicemail sources. Because a
34  * voicemail source is tied 1:1 to a phone account, the phone account handle is used as the key
35  * for each voicemail source and the associated data.
36  */
37 public class OmtpVvmSourceManager {
38     public static final String TAG = "OmtpVvmSourceManager";
39 
40     private static OmtpVvmSourceManager sInstance = new OmtpVvmSourceManager();
41 
42     private Context mContext;
43     private SubscriptionManager mSubscriptionManager;
44     private TelephonyManager mTelephonyManager;
45     // Each phone account is associated with a phone state listener for updates to whether the
46     // device is able to sync.
47     private Set<PhoneAccountHandle> mActiveVvmSources;
48     private Map<PhoneAccountHandle, PhoneStateListener> mPhoneStateListenerMap;
49 
50     /**
51      * Private constructor. Instance should only be acquired through getInstance().
52      */
OmtpVvmSourceManager()53     private OmtpVvmSourceManager() {}
54 
getInstance(Context context)55     public static OmtpVvmSourceManager getInstance(Context context) {
56         sInstance.setup(context);
57         return sInstance;
58     }
59 
60     /**
61      * Set the context and system services so they do not need to be retrieved every time.
62      * @param context The context to get the subscription and telephony manager for.
63      */
setup(Context context)64     private void setup(Context context) {
65         if (mContext == null) {
66             mContext = context;
67             mSubscriptionManager = SubscriptionManager.from(context);
68             mTelephonyManager = (TelephonyManager)
69                     mContext.getSystemService(Context.TELEPHONY_SERVICE);
70             mActiveVvmSources = Collections.newSetFromMap(
71                     new ConcurrentHashMap<PhoneAccountHandle, Boolean>(8, 0.9f, 1));
72             mPhoneStateListenerMap =
73                     new ConcurrentHashMap<PhoneAccountHandle, PhoneStateListener>(8, 0.9f, 1);
74         }
75     }
76 
addSource(PhoneAccountHandle phoneAccount)77     public void addSource(PhoneAccountHandle phoneAccount) {
78         mActiveVvmSources.add(phoneAccount);
79     }
80 
81     /**
82      * When a voicemail source is removed, we don't always know which one was removed. Check the
83      * list of registered phone accounts against the active subscriptions list and remove the
84      * inactive sources.
85      */
removeInactiveSources()86     public void removeInactiveSources() {
87         for (PhoneAccountHandle phoneAccount : mActiveVvmSources) {
88             if (!PhoneUtils.isPhoneAccountActive(mSubscriptionManager, phoneAccount)) {
89                 removeSource(phoneAccount);
90             }
91         }
92 
93         // Remove any orphaned phone state listeners as well.
94         for (PhoneAccountHandle phoneAccount : mPhoneStateListenerMap.keySet()) {
95             if (!PhoneUtils.isPhoneAccountActive(mSubscriptionManager, phoneAccount)) {
96                 removePhoneStateListener(phoneAccount);
97             }
98         }
99     }
100 
removeSource(Phone phone)101     public void removeSource(Phone phone) {
102         removeSource(PhoneUtils.makePstnPhoneAccountHandle(phone));
103     }
104 
removeSource(PhoneAccountHandle phoneAccount)105     public void removeSource(PhoneAccountHandle phoneAccount) {
106         // TODO: should use OmtpVvmCarrierConfigHelper to handle the event. But currently it
107         // couldn't handle events on removed SIMs
108         VoicemailStatus.disable(mContext, phoneAccount);
109         removePhoneStateListener(phoneAccount);
110         mActiveVvmSources.remove(phoneAccount);
111     }
112 
addPhoneStateListener(Phone phone)113     public void addPhoneStateListener(Phone phone) {
114         addPhoneStateListener(PhoneUtils.makePstnPhoneAccountHandle(phone));
115     }
116 
addPhoneStateListener(PhoneAccountHandle phoneAccount)117     public void addPhoneStateListener(PhoneAccountHandle phoneAccount) {
118         if (!mPhoneStateListenerMap.containsKey(phoneAccount)) {
119             VvmPhoneStateListener phoneStateListener = new VvmPhoneStateListener(mContext,
120                     PhoneUtils.makePstnPhoneAccountHandle(phoneAccount.getId()));
121             mPhoneStateListenerMap.put(phoneAccount, phoneStateListener);
122             mTelephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
123         }
124     }
125 
removePhoneStateListener(PhoneAccountHandle phoneAccount)126     public void removePhoneStateListener(PhoneAccountHandle phoneAccount) {
127         PhoneStateListener phoneStateListener =
128                 mPhoneStateListenerMap.remove(phoneAccount);
129         mTelephonyManager.listen(phoneStateListener, 0);
130     }
131 
getOmtpVvmSources()132     public Set<PhoneAccountHandle> getOmtpVvmSources() {
133         return mActiveVvmSources;
134     }
135 
136     /**
137      * Check if a certain account is registered.
138      *
139      * @param phoneAccount The account to look for.
140      * @return {@code true} if the account is in the list of registered OMTP voicemail sources.
141      * {@code false} otherwise.
142      */
isVvmSourceRegistered(PhoneAccountHandle phoneAccount)143     public boolean isVvmSourceRegistered(PhoneAccountHandle phoneAccount) {
144         if (phoneAccount == null) {
145             return false;
146         }
147 
148         return mActiveVvmSources.contains(phoneAccount);
149     }
150 }