• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.telephony;
18 
19 import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
20 import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
21 
22 import android.content.Context;
23 import android.telephony.SubscriptionInfo;
24 import android.telephony.SubscriptionManager;
25 
26 import com.android.settings.R;
27 import com.android.settings.core.BasePreferenceController;
28 import com.android.settings.network.SubscriptionUtil;
29 import com.android.settings.network.SubscriptionsChangeListener;
30 
31 import java.util.ArrayList;
32 import java.util.List;
33 
34 import androidx.lifecycle.Lifecycle;
35 import androidx.lifecycle.LifecycleObserver;
36 import androidx.lifecycle.OnLifecycleEvent;
37 import androidx.preference.ListPreference;
38 import androidx.preference.Preference;
39 import androidx.preference.PreferenceScreen;
40 
41 /**
42  * This implements common controller functionality for a Preference letting the user see/change
43  * what mobile network subscription is used by default for some service controlled by the
44  * SubscriptionManager. This can be used for services such as Calls or SMS.
45  */
46 public abstract class DefaultSubscriptionController extends BasePreferenceController implements
47         LifecycleObserver, Preference.OnPreferenceChangeListener,
48         SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
49     private static final String TAG = "DefaultSubController";
50 
51     protected SubscriptionsChangeListener mChangeListener;
52     protected ListPreference mPreference;
53     protected SubscriptionManager mManager;
54 
DefaultSubscriptionController(Context context, String preferenceKey)55     public DefaultSubscriptionController(Context context, String preferenceKey) {
56         super(context, preferenceKey);
57         mManager = context.getSystemService(SubscriptionManager.class);
58         mChangeListener = new SubscriptionsChangeListener(context, this);
59     }
60 
init(Lifecycle lifecycle)61     public void init(Lifecycle lifecycle) {
62         lifecycle.addObserver(this);
63     }
64 
65     /** @return SubscriptionInfo for the default subscription for the service, or null if there
66      * isn't one. */
getDefaultSubscriptionInfo()67     protected abstract SubscriptionInfo getDefaultSubscriptionInfo();
68 
69     /** @return the id of the default subscription for the service, or
70      * SubscriptionManager.INVALID_SUBSCRIPTION_ID if there isn't one. */
getDefaultSubscriptionId()71     protected abstract int getDefaultSubscriptionId();
72 
73     /** Called to change the default subscription for the service. */
setDefaultSubscription(int subscriptionId)74     protected abstract void setDefaultSubscription(int subscriptionId);
75 
76     @Override
getAvailabilityStatus()77     public int getAvailabilityStatus() {
78         final List<SubscriptionInfo> subs = SubscriptionUtil.getActiveSubscriptions(mManager);
79         if (subs.size() > 1) {
80             return AVAILABLE;
81         } else {
82             return CONDITIONALLY_UNAVAILABLE;
83         }
84     }
85 
86     @OnLifecycleEvent(ON_RESUME)
onResume()87     public void onResume() {
88         mChangeListener.start();
89         updateEntries();
90     }
91 
92     @OnLifecycleEvent(ON_PAUSE)
onPause()93     public void onPause() {
94         mChangeListener.stop();
95     }
96 
97     @Override
displayPreference(PreferenceScreen screen)98     public void displayPreference(PreferenceScreen screen) {
99         super.displayPreference(screen);
100         mPreference = screen.findPreference(getPreferenceKey());
101         updateEntries();
102     }
103 
104     @Override
getSummary()105     public CharSequence getSummary() {
106         final SubscriptionInfo info = getDefaultSubscriptionInfo();
107         if (info != null) {
108             return info.getDisplayName();
109         } else {
110             return mContext.getString(R.string.calls_and_sms_ask_every_time);
111         }
112     }
113 
updateEntries()114     private void updateEntries() {
115         if (mPreference == null) {
116             return;
117         }
118         if (!isAvailable()) {
119             mPreference.setVisible(false);
120             return;
121         }
122         mPreference.setVisible(true);
123 
124         // TODO(b/135142209) - for now we need to manually ensure we're registered as a change
125         // listener, because this might not have happened during displayPreference if
126         // getAvailabilityStatus returned CONDITIONALLY_UNAVAILABLE at the time.
127         mPreference.setOnPreferenceChangeListener(this);
128 
129         final List<SubscriptionInfo> subs = SubscriptionUtil.getActiveSubscriptions(mManager);
130 
131         // We'll have one entry for each available subscription, plus one for a "ask me every
132         // time" entry at the end.
133         final ArrayList<CharSequence> displayNames = new ArrayList<>();
134         final ArrayList<CharSequence> subscriptionIds = new ArrayList<>();
135 
136         final int serviceDefaultSubId = getDefaultSubscriptionId();
137         boolean subIsAvailable = false;
138 
139         for (SubscriptionInfo sub : subs) {
140             if (sub.isOpportunistic()) {
141                 continue;
142             }
143             displayNames.add(sub.getDisplayName());
144             final int subId = sub.getSubscriptionId();
145             subscriptionIds.add(Integer.toString(subId));
146             if (subId == serviceDefaultSubId) {
147                 subIsAvailable = true;
148             }
149         }
150         // Add the extra "Ask every time" value at the end.
151         displayNames.add(mContext.getString(R.string.calls_and_sms_ask_every_time));
152         subscriptionIds.add(Integer.toString(SubscriptionManager.INVALID_SUBSCRIPTION_ID));
153 
154         mPreference.setEntries(displayNames.toArray(new CharSequence[0]));
155         mPreference.setEntryValues(subscriptionIds.toArray(new CharSequence[0]));
156 
157         if (subIsAvailable) {
158             mPreference.setValue(Integer.toString(serviceDefaultSubId));
159         } else {
160             mPreference.setValue(Integer.toString(SubscriptionManager.INVALID_SUBSCRIPTION_ID));
161         }
162     }
163 
164     @Override
onPreferenceChange(Preference preference, Object newValue)165     public boolean onPreferenceChange(Preference preference, Object newValue) {
166         final int subscriptionId = Integer.parseInt((String) newValue);
167         setDefaultSubscription(subscriptionId);
168         refreshSummary(mPreference);
169         return true;
170     }
171 
172     @Override
onAirplaneModeChanged(boolean airplaneModeEnabled)173     public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
174     }
175 
176     @Override
onSubscriptionsChanged()177     public void onSubscriptionsChanged() {
178         if (mPreference != null) {
179             updateEntries();
180             refreshSummary(mPreference);
181         }
182     }
183 }
184