/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.network; import static androidx.lifecycle.Lifecycle.Event.ON_DESTROY; import static androidx.lifecycle.Lifecycle.Event.ON_START; import static androidx.lifecycle.Lifecycle.Event.ON_STOP; import android.content.Context; import android.os.Looper; import android.provider.Settings; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.OnLifecycleEvent; import java.util.ArrayList; import java.util.List; /** * A proxy to the subscription manager */ public class ProxySubscriptionManager implements LifecycleObserver { /** * Interface for monitor active subscriptions list changing */ public interface OnActiveSubscriptionChangedListener { /** * When active subscriptions list get changed */ void onChanged(); /** * get Lifecycle of listener * * @return Returns Lifecycle. */ default Lifecycle getLifecycle() { return null; } } /** * Get proxy instance to subscription manager * * @return proxy to subscription manager */ public static ProxySubscriptionManager getInstance(Context context) { if (sSingleton != null) { return sSingleton; } sSingleton = new ProxySubscriptionManager(context.getApplicationContext()); return sSingleton; } private static ProxySubscriptionManager sSingleton; private ProxySubscriptionManager(Context context) { final Looper looper = Looper.getMainLooper(); mActiveSubscriptionsListeners = new ArrayList(); mSubscriptionMonitor = new ActiveSubsciptionsListener(looper, context) { public void onChanged() { notifyAllListeners(); } }; mAirplaneModeMonitor = new GlobalSettingsChangeListener(looper, context, Settings.Global.AIRPLANE_MODE_ON) { public void onChanged(String field) { mSubscriptionMonitor.clearCache(); notifyAllListeners(); } }; mSubscriptionMonitor.start(); } private Lifecycle mLifecycle; private ActiveSubsciptionsListener mSubscriptionMonitor; private GlobalSettingsChangeListener mAirplaneModeMonitor; private List mActiveSubscriptionsListeners; private void notifyAllListeners() { for (OnActiveSubscriptionChangedListener listener : mActiveSubscriptionsListeners) { final Lifecycle lifecycle = listener.getLifecycle(); if ((lifecycle == null) || (lifecycle.getCurrentState().isAtLeast(Lifecycle.State.STARTED))) { listener.onChanged(); } } } /** * Lifecycle for data within proxy * * @param lifecycle life cycle to reference */ public void setLifecycle(Lifecycle lifecycle) { if (mLifecycle == lifecycle) { return; } if (mLifecycle != null) { mLifecycle.removeObserver(this); } if (lifecycle != null) { lifecycle.addObserver(this); } mLifecycle = lifecycle; mAirplaneModeMonitor.notifyChangeBasedOn(lifecycle); } @OnLifecycleEvent(ON_START) void onStart() { mSubscriptionMonitor.start(); } @OnLifecycleEvent(ON_STOP) void onStop() { mSubscriptionMonitor.stop(); } @OnLifecycleEvent(ON_DESTROY) void onDestroy() { mSubscriptionMonitor.close(); mAirplaneModeMonitor.close(); if (mLifecycle != null) { mLifecycle.removeObserver(this); mLifecycle = null; sSingleton = null; } } /** * Get SubscriptionManager * * @return a SubscriptionManager */ public SubscriptionManager get() { return mSubscriptionMonitor.getSubscriptionManager(); } /** * Get current max. number active subscription info(s) been setup within device * * @return max. number of active subscription info(s) */ public int getActiveSubscriptionInfoCountMax() { return mSubscriptionMonitor.getActiveSubscriptionInfoCountMax(); } /** * Get a list of active subscription info * * @return A list of active subscription info */ public List getActiveSubscriptionsInfo() { return mSubscriptionMonitor.getActiveSubscriptionsInfo(); } /** * Get an active subscription info with given subscription ID * * @param subId target subscription ID * @return A subscription info which is active list */ public SubscriptionInfo getActiveSubscriptionInfo(int subId) { return mSubscriptionMonitor.getActiveSubscriptionInfo(subId); } /** * Get a list of accessible subscription info * * @return A list of accessible subscription info */ public List getAccessibleSubscriptionsInfo() { return mSubscriptionMonitor.getAccessibleSubscriptionsInfo(); } /** * Get an accessible subscription info with given subscription ID * * @param subId target subscription ID * @return A subscription info which is accessible list */ public SubscriptionInfo getAccessibleSubscriptionInfo(int subId) { return mSubscriptionMonitor.getAccessibleSubscriptionInfo(subId); } /** * Clear data cached within proxy */ public void clearCache() { mSubscriptionMonitor.clearCache(); } /** * Add listener to active subscriptions monitor list * * @param listener listener to active subscriptions change */ public void addActiveSubscriptionsListener(OnActiveSubscriptionChangedListener listener) { if (mActiveSubscriptionsListeners.contains(listener)) { return; } mActiveSubscriptionsListeners.add(listener); } /** * Remove listener from active subscriptions monitor list * * @param listener listener to active subscriptions change */ public void removeActiveSubscriptionsListener(OnActiveSubscriptionChangedListener listener) { mActiveSubscriptionsListeners.remove(listener); } }