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_PAUSE; 20 import static androidx.lifecycle.Lifecycle.Event.ON_RESUME; 21 22 import android.content.Context; 23 import android.content.Intent; 24 import android.os.UserManager; 25 import android.provider.Settings; 26 import android.telephony.SubscriptionInfo; 27 import android.telephony.SubscriptionManager; 28 import android.telephony.euicc.EuiccManager; 29 30 import androidx.lifecycle.Lifecycle; 31 import androidx.lifecycle.LifecycleObserver; 32 import androidx.lifecycle.OnLifecycleEvent; 33 import androidx.preference.Preference; 34 import androidx.preference.PreferenceScreen; 35 36 import com.android.settings.R; 37 import com.android.settings.core.PreferenceControllerMixin; 38 import com.android.settings.dashboard.DashboardFragment; 39 import com.android.settings.network.telephony.MobileNetworkActivity; 40 import com.android.settings.network.telephony.MobileNetworkUtils; 41 import com.android.settings.overlay.FeatureFactory; 42 import com.android.settings.widget.AddPreference; 43 import com.android.settingslib.Utils; 44 import com.android.settingslib.core.AbstractPreferenceController; 45 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; 46 47 import java.util.List; 48 49 public class MobileNetworkSummaryController extends AbstractPreferenceController implements 50 SubscriptionsChangeListener.SubscriptionsChangeListenerClient, LifecycleObserver, 51 PreferenceControllerMixin { 52 private static final String TAG = "MobileNetSummaryCtlr"; 53 54 private static final String KEY = "mobile_network_list"; 55 56 private final MetricsFeatureProvider mMetricsFeatureProvider; 57 58 private SubscriptionManager mSubscriptionManager; 59 private UserManager mUserManager; 60 private SubscriptionsChangeListener mChangeListener; 61 private AddPreference mPreference; 62 63 /** 64 * This controls the summary text and click behavior of the "Mobile network" item on the 65 * Network & internet page. There are 3 separate cases depending on the number of mobile network 66 * subscriptions: 67 * <ul> 68 * <li>No subscription: click action begins a UI flow to add a network subscription, and 69 * the summary text indicates this</li> 70 * 71 * <li>One subscription: click action takes you to details for that one network, and 72 * the summary text is the network name</li> 73 * 74 * <li>More than one subscription: click action takes you to a page listing the subscriptions, 75 * and the summary text gives the count of SIMs</li> 76 * </ul> 77 */ MobileNetworkSummaryController(Context context, Lifecycle lifecycle)78 public MobileNetworkSummaryController(Context context, Lifecycle lifecycle) { 79 super(context); 80 mMetricsFeatureProvider = FeatureFactory.getFactory(mContext).getMetricsFeatureProvider(); 81 mSubscriptionManager = context.getSystemService(SubscriptionManager.class); 82 mUserManager = context.getSystemService(UserManager.class); 83 if (lifecycle != null) { 84 mChangeListener = new SubscriptionsChangeListener(context, this); 85 lifecycle.addObserver(this); 86 } 87 } 88 89 @OnLifecycleEvent(ON_RESUME) onResume()90 public void onResume() { 91 mChangeListener.start(); 92 update(); 93 } 94 95 @OnLifecycleEvent(ON_PAUSE) onPause()96 public void onPause() { 97 mChangeListener.stop(); 98 } 99 100 @Override displayPreference(PreferenceScreen screen)101 public void displayPreference(PreferenceScreen screen) { 102 super.displayPreference(screen); 103 mPreference = screen.findPreference(getPreferenceKey()); 104 } 105 106 @Override getSummary()107 public CharSequence getSummary() { 108 final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions( 109 mContext); 110 if (subs.isEmpty()) { 111 if (MobileNetworkUtils.showEuiccSettings(mContext)) { 112 return mContext.getResources().getString( 113 R.string.mobile_network_summary_add_a_network); 114 } 115 return null; 116 } else if (subs.size() == 1) { 117 final SubscriptionInfo info = subs.get(0); 118 final int subId = info.getSubscriptionId(); 119 if (!info.isEmbedded() && !mSubscriptionManager.isActiveSubscriptionId(subId) 120 && !SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager)) { 121 return mContext.getString(R.string.mobile_network_tap_to_activate, 122 SubscriptionUtil.getDisplayName(info)); 123 } else { 124 return subs.get(0).getDisplayName(); 125 } 126 } else { 127 final int count = subs.size(); 128 return mContext.getResources().getQuantityString(R.plurals.mobile_network_summary_count, 129 count, count); 130 } 131 } 132 startAddSimFlow()133 private void startAddSimFlow() { 134 final Intent intent = new Intent(EuiccManager.ACTION_PROVISION_EMBEDDED_SUBSCRIPTION); 135 intent.putExtra(EuiccManager.EXTRA_FORCE_PROVISION, true); 136 mContext.startActivity(intent); 137 } 138 update()139 private void update() { 140 if (mPreference == null || mPreference.isDisabledByAdmin()) { 141 return; 142 } 143 refreshSummary(mPreference); 144 mPreference.setOnPreferenceClickListener(null); 145 mPreference.setOnAddClickListener(null); 146 mPreference.setFragment(null); 147 mPreference.setEnabled(!mChangeListener.isAirplaneModeOn()); 148 149 final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions( 150 mContext); 151 152 if (subs.isEmpty()) { 153 if (MobileNetworkUtils.showEuiccSettings(mContext)) { 154 mPreference.setOnPreferenceClickListener((Preference pref) -> { 155 mMetricsFeatureProvider.logClickedPreference(pref, 156 pref.getExtras().getInt(DashboardFragment.CATEGORY)); 157 startAddSimFlow(); 158 return true; 159 }); 160 } else { 161 mPreference.setEnabled(false); 162 } 163 } else { 164 // We have one or more existing subscriptions, so we want the plus button if eSIM is 165 // supported. 166 if (MobileNetworkUtils.showEuiccSettings(mContext)) { 167 mPreference.setAddWidgetEnabled(!mChangeListener.isAirplaneModeOn()); 168 mPreference.setOnAddClickListener(p -> { 169 mMetricsFeatureProvider.logClickedPreference(p, 170 p.getExtras().getInt(DashboardFragment.CATEGORY)); 171 startAddSimFlow(); 172 }); 173 } 174 175 if (subs.size() == 1) { 176 mPreference.setOnPreferenceClickListener((Preference pref) -> { 177 mMetricsFeatureProvider.logClickedPreference(pref, 178 pref.getExtras().getInt(DashboardFragment.CATEGORY)); 179 final SubscriptionInfo info = subs.get(0); 180 final int subId = info.getSubscriptionId(); 181 if (!info.isEmbedded() && !mSubscriptionManager.isActiveSubscriptionId(subId) 182 && !SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager)) { 183 mSubscriptionManager.setSubscriptionEnabled(subId, true); 184 } else { 185 final Intent intent = new Intent(mContext, MobileNetworkActivity.class); 186 intent.putExtra(Settings.EXTRA_SUB_ID, subs.get(0).getSubscriptionId()); 187 mContext.startActivity(intent); 188 } 189 return true; 190 }); 191 } else { 192 mPreference.setFragment(MobileNetworkListFragment.class.getCanonicalName()); 193 } 194 } 195 } 196 197 @Override isAvailable()198 public boolean isAvailable() { 199 return !Utils.isWifiOnly(mContext) && mUserManager.isAdminUser(); 200 } 201 202 @Override getPreferenceKey()203 public String getPreferenceKey() { 204 return KEY; 205 } 206 207 @Override onAirplaneModeChanged(boolean airplaneModeEnabled)208 public void onAirplaneModeChanged(boolean airplaneModeEnabled) { 209 update(); 210 } 211 212 @Override onSubscriptionsChanged()213 public void onSubscriptionsChanged() { 214 refreshSummary(mPreference); 215 update(); 216 } 217 } 218