1 /* 2 * Copyright (C) 2019 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 17 package com.android.settings.network; 18 19 import static androidx.lifecycle.Lifecycle.Event.ON_DESTROY; 20 import static androidx.lifecycle.Lifecycle.Event.ON_START; 21 import static androidx.lifecycle.Lifecycle.Event.ON_STOP; 22 23 import android.content.Context; 24 import android.os.Looper; 25 import android.provider.Settings; 26 import android.telephony.SubscriptionInfo; 27 import android.telephony.SubscriptionManager; 28 29 import androidx.lifecycle.Lifecycle; 30 import androidx.lifecycle.LifecycleObserver; 31 import androidx.lifecycle.OnLifecycleEvent; 32 33 import java.util.ArrayList; 34 import java.util.List; 35 36 /** 37 * A proxy to the subscription manager 38 */ 39 public class ProxySubscriptionManager implements LifecycleObserver { 40 41 /** 42 * Interface for monitor active subscriptions list changing 43 */ 44 public interface OnActiveSubscriptionChangedListener { 45 /** 46 * When active subscriptions list get changed 47 */ onChanged()48 void onChanged(); 49 /** 50 * get Lifecycle of listener 51 * 52 * @return Returns Lifecycle. 53 */ getLifecycle()54 default Lifecycle getLifecycle() { 55 return null; 56 } 57 } 58 59 /** 60 * Get proxy instance to subscription manager 61 * 62 * @return proxy to subscription manager 63 */ getInstance(Context context)64 public static ProxySubscriptionManager getInstance(Context context) { 65 if (sSingleton != null) { 66 return sSingleton; 67 } 68 sSingleton = new ProxySubscriptionManager(context.getApplicationContext()); 69 return sSingleton; 70 } 71 72 private static ProxySubscriptionManager sSingleton; 73 ProxySubscriptionManager(Context context)74 private ProxySubscriptionManager(Context context) { 75 final Looper looper = Looper.getMainLooper(); 76 77 mActiveSubscriptionsListeners = 78 new ArrayList<OnActiveSubscriptionChangedListener>(); 79 80 mSubscriptionMonitor = new ActiveSubsciptionsListener(looper, context) { 81 public void onChanged() { 82 notifyAllListeners(); 83 } 84 }; 85 mAirplaneModeMonitor = new GlobalSettingsChangeListener(looper, 86 context, Settings.Global.AIRPLANE_MODE_ON) { 87 public void onChanged(String field) { 88 mSubscriptionMonitor.clearCache(); 89 notifyAllListeners(); 90 } 91 }; 92 93 mSubscriptionMonitor.start(); 94 } 95 96 private Lifecycle mLifecycle; 97 private ActiveSubsciptionsListener mSubscriptionMonitor; 98 private GlobalSettingsChangeListener mAirplaneModeMonitor; 99 100 private List<OnActiveSubscriptionChangedListener> mActiveSubscriptionsListeners; 101 notifyAllListeners()102 private void notifyAllListeners() { 103 for (OnActiveSubscriptionChangedListener listener : mActiveSubscriptionsListeners) { 104 final Lifecycle lifecycle = listener.getLifecycle(); 105 if ((lifecycle == null) 106 || (lifecycle.getCurrentState().isAtLeast(Lifecycle.State.STARTED))) { 107 listener.onChanged(); 108 } 109 } 110 } 111 112 /** 113 * Lifecycle for data within proxy 114 * 115 * @param lifecycle life cycle to reference 116 */ setLifecycle(Lifecycle lifecycle)117 public void setLifecycle(Lifecycle lifecycle) { 118 if (mLifecycle == lifecycle) { 119 return; 120 } 121 if (mLifecycle != null) { 122 mLifecycle.removeObserver(this); 123 } 124 if (lifecycle != null) { 125 lifecycle.addObserver(this); 126 } 127 mLifecycle = lifecycle; 128 mAirplaneModeMonitor.notifyChangeBasedOn(lifecycle); 129 } 130 131 @OnLifecycleEvent(ON_START) onStart()132 void onStart() { 133 mSubscriptionMonitor.start(); 134 } 135 136 @OnLifecycleEvent(ON_STOP) onStop()137 void onStop() { 138 mSubscriptionMonitor.stop(); 139 } 140 141 @OnLifecycleEvent(ON_DESTROY) onDestroy()142 void onDestroy() { 143 mSubscriptionMonitor.close(); 144 mAirplaneModeMonitor.close(); 145 146 if (mLifecycle != null) { 147 mLifecycle.removeObserver(this); 148 mLifecycle = null; 149 150 sSingleton = null; 151 } 152 } 153 154 /** 155 * Get SubscriptionManager 156 * 157 * @return a SubscriptionManager 158 */ get()159 public SubscriptionManager get() { 160 return mSubscriptionMonitor.getSubscriptionManager(); 161 } 162 163 /** 164 * Get current max. number active subscription info(s) been setup within device 165 * 166 * @return max. number of active subscription info(s) 167 */ getActiveSubscriptionInfoCountMax()168 public int getActiveSubscriptionInfoCountMax() { 169 return mSubscriptionMonitor.getActiveSubscriptionInfoCountMax(); 170 } 171 172 /** 173 * Get a list of active subscription info 174 * 175 * @return A list of active subscription info 176 */ getActiveSubscriptionsInfo()177 public List<SubscriptionInfo> getActiveSubscriptionsInfo() { 178 return mSubscriptionMonitor.getActiveSubscriptionsInfo(); 179 } 180 181 /** 182 * Get an active subscription info with given subscription ID 183 * 184 * @param subId target subscription ID 185 * @return A subscription info which is active list 186 */ getActiveSubscriptionInfo(int subId)187 public SubscriptionInfo getActiveSubscriptionInfo(int subId) { 188 return mSubscriptionMonitor.getActiveSubscriptionInfo(subId); 189 } 190 191 /** 192 * Get a list of accessible subscription info 193 * 194 * @return A list of accessible subscription info 195 */ getAccessibleSubscriptionsInfo()196 public List<SubscriptionInfo> getAccessibleSubscriptionsInfo() { 197 return mSubscriptionMonitor.getAccessibleSubscriptionsInfo(); 198 } 199 200 /** 201 * Get an accessible subscription info with given subscription ID 202 * 203 * @param subId target subscription ID 204 * @return A subscription info which is accessible list 205 */ getAccessibleSubscriptionInfo(int subId)206 public SubscriptionInfo getAccessibleSubscriptionInfo(int subId) { 207 return mSubscriptionMonitor.getAccessibleSubscriptionInfo(subId); 208 } 209 210 /** 211 * Clear data cached within proxy 212 */ clearCache()213 public void clearCache() { 214 mSubscriptionMonitor.clearCache(); 215 } 216 217 /** 218 * Add listener to active subscriptions monitor list 219 * 220 * @param listener listener to active subscriptions change 221 */ addActiveSubscriptionsListener(OnActiveSubscriptionChangedListener listener)222 public void addActiveSubscriptionsListener(OnActiveSubscriptionChangedListener listener) { 223 if (mActiveSubscriptionsListeners.contains(listener)) { 224 return; 225 } 226 mActiveSubscriptionsListeners.add(listener); 227 } 228 229 /** 230 * Remove listener from active subscriptions monitor list 231 * 232 * @param listener listener to active subscriptions change 233 */ removeActiveSubscriptionsListener(OnActiveSubscriptionChangedListener listener)234 public void removeActiveSubscriptionsListener(OnActiveSubscriptionChangedListener listener) { 235 mActiveSubscriptionsListeners.remove(listener); 236 } 237 } 238