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.telephony.SubscriptionManager;
26 import android.telephony.euicc.EuiccManager;
27 
28 import androidx.lifecycle.Lifecycle;
29 import androidx.lifecycle.LifecycleObserver;
30 import androidx.lifecycle.LifecycleOwner;
31 import androidx.lifecycle.OnLifecycleEvent;
32 import androidx.preference.Preference;
33 import androidx.preference.PreferenceScreen;
34 
35 import com.android.settings.R;
36 import com.android.settings.core.PreferenceControllerMixin;
37 import com.android.settings.dashboard.DashboardFragment;
38 import com.android.settings.network.telephony.MobileNetworkUtils;
39 import com.android.settings.overlay.FeatureFactory;
40 import com.android.settingslib.RestrictedPreference;
41 import com.android.settingslib.Utils;
42 import com.android.settingslib.core.AbstractPreferenceController;
43 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
44 import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
45 import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
46 import com.android.settingslib.mobile.dataservice.UiccInfoEntity;
47 
48 import java.util.List;
49 import java.util.stream.Collectors;
50 
51 public class MobileNetworkSummaryController extends AbstractPreferenceController implements
52         LifecycleObserver, PreferenceControllerMixin,
53         MobileNetworkRepository.MobileNetworkCallback {
54     private static final String TAG = "MobileNetSummaryCtlr";
55 
56     private static final String KEY = "mobile_network_list";
57 
58     private final MetricsFeatureProvider mMetricsFeatureProvider;
59     private UserManager mUserManager;
60     private RestrictedPreference mPreference;
61 
62     private MobileNetworkRepository mMobileNetworkRepository;
63     private List<SubscriptionInfoEntity> mSubInfoEntityList;
64     private List<UiccInfoEntity> mUiccInfoEntityList;
65     private List<MobileNetworkInfoEntity> mMobileNetworkInfoEntityList;
66     private boolean mIsAirplaneModeOn;
67     private LifecycleOwner mLifecycleOwner;
68 
69     /**
70      * This controls the summary text and click behavior of the "Mobile network" item on the
71      * Network & internet page. There are 3 separate cases depending on the number of mobile network
72      * subscriptions:
73      * <ul>
74      * <li>No subscription: click action begins a UI flow to add a network subscription, and
75      * the summary text indicates this</li>
76      *
77      * <li>One subscription: click action takes you to details for that one network, and
78      * the summary text is the network name</li>
79      *
80      * <li>More than one subscription: click action takes you to a page listing the subscriptions,
81      * and the summary text gives the count of SIMs</li>
82      * </ul>
83      */
MobileNetworkSummaryController(Context context, Lifecycle lifecycle, LifecycleOwner lifecycleOwner)84     public MobileNetworkSummaryController(Context context, Lifecycle lifecycle,
85             LifecycleOwner lifecycleOwner) {
86         super(context);
87         mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
88         mUserManager = context.getSystemService(UserManager.class);
89         mLifecycleOwner = lifecycleOwner;
90         mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
91         mIsAirplaneModeOn = mMobileNetworkRepository.isAirplaneModeOn();
92         if (lifecycle != null) {
93             lifecycle.addObserver(this);
94         }
95     }
96 
97     @OnLifecycleEvent(ON_RESUME)
onResume()98     public void onResume() {
99         mMobileNetworkRepository.addRegister(mLifecycleOwner, this,
100                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
101         mMobileNetworkRepository.updateEntity();
102     }
103 
104     @OnLifecycleEvent(ON_PAUSE)
onPause()105     public void onPause() {
106         mMobileNetworkRepository.removeRegister(this);
107     }
108 
109     @Override
displayPreference(PreferenceScreen screen)110     public void displayPreference(PreferenceScreen screen) {
111         super.displayPreference(screen);
112         mPreference = screen.findPreference(getPreferenceKey());
113     }
114 
115     @Override
getSummary()116     public CharSequence getSummary() {
117 
118         if ((mSubInfoEntityList == null || mSubInfoEntityList.isEmpty()) || (
119                 mUiccInfoEntityList == null || mUiccInfoEntityList.isEmpty()) || (
120                 mMobileNetworkInfoEntityList == null || mMobileNetworkInfoEntityList.isEmpty())) {
121             if (MobileNetworkUtils.showEuiccSettingsDetecting(mContext)) {
122                 return mContext.getResources().getString(
123                         R.string.mobile_network_summary_add_a_network);
124             }
125             // set empty string to override previous text for carrier when SIM available
126             return "";
127         } else if (mSubInfoEntityList.size() == 1) {
128             SubscriptionInfoEntity info = mSubInfoEntityList.get(0);
129             CharSequence displayName = info.uniqueName;
130             if (info.isEmbedded || mUiccInfoEntityList.get(0).isActive
131                     || mMobileNetworkInfoEntityList.get(0).showToggleForPhysicalSim) {
132                 return displayName;
133             }
134             return mContext.getString(R.string.mobile_network_tap_to_activate, displayName);
135         } else {
136             return mSubInfoEntityList.stream()
137                     .map(SubscriptionInfoEntity::getUniqueDisplayName)
138                     .collect(Collectors.joining(", "));
139         }
140     }
141 
logPreferenceClick(Preference preference)142     private void logPreferenceClick(Preference preference) {
143         mMetricsFeatureProvider.logClickedPreference(preference,
144                 preference.getExtras().getInt(DashboardFragment.CATEGORY));
145     }
146 
startAddSimFlow()147     private void startAddSimFlow() {
148         final Intent intent = new Intent(EuiccManager.ACTION_PROVISION_EMBEDDED_SUBSCRIPTION);
149         intent.setPackage(com.android.settings.Utils.PHONE_PACKAGE_NAME);
150         intent.putExtra(EuiccManager.EXTRA_FORCE_PROVISION, true);
151         mContext.startActivity(intent);
152     }
153 
initPreference()154     private void initPreference() {
155         refreshSummary(mPreference);
156         mPreference.setOnPreferenceClickListener(null);
157         mPreference.setFragment(null);
158         mPreference.setEnabled(!mIsAirplaneModeOn);
159     }
160 
update()161     private void update() {
162         if (mPreference == null || mPreference.isDisabledByAdmin()) {
163             return;
164         }
165 
166         initPreference();
167         if (((mSubInfoEntityList == null || mSubInfoEntityList.isEmpty())
168                 || (mUiccInfoEntityList == null || mUiccInfoEntityList.isEmpty())
169                 || (mMobileNetworkInfoEntityList == null
170                 || mMobileNetworkInfoEntityList.isEmpty()))) {
171             if (MobileNetworkUtils.showEuiccSettingsDetecting(mContext)) {
172                 mPreference.setOnPreferenceClickListener((Preference pref) -> {
173                     logPreferenceClick(pref);
174                     startAddSimFlow();
175                     return true;
176                 });
177             } else {
178                 mPreference.setEnabled(false);
179             }
180             return;
181         }
182 
183         mPreference.setFragment(MobileNetworkListFragment.class.getCanonicalName());
184     }
185 
186     @Override
isAvailable()187     public boolean isAvailable() {
188         return SubscriptionUtil.isSimHardwareVisible(mContext) &&
189                 !Utils.isWifiOnly(mContext) && mUserManager.isAdminUser();
190     }
191 
192     @Override
getPreferenceKey()193     public String getPreferenceKey() {
194         return KEY;
195     }
196 
197     @Override
onAirplaneModeChanged(boolean airplaneModeEnabled)198     public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
199         if (mIsAirplaneModeOn != airplaneModeEnabled) {
200             mIsAirplaneModeOn = airplaneModeEnabled;
201             update();
202         }
203     }
204 
205     @Override
onAvailableSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList)206     public void onAvailableSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) {
207         mSubInfoEntityList = subInfoEntityList;
208         update();
209     }
210 
211     @Override
onAllUiccInfoChanged(List<UiccInfoEntity> uiccInfoEntityList)212     public void onAllUiccInfoChanged(List<UiccInfoEntity> uiccInfoEntityList) {
213         mUiccInfoEntityList = uiccInfoEntityList;
214         update();
215     }
216 
217     @Override
onAllMobileNetworkInfoChanged( List<MobileNetworkInfoEntity> mobileNetworkInfoEntityList)218     public void onAllMobileNetworkInfoChanged(
219             List<MobileNetworkInfoEntity> mobileNetworkInfoEntityList) {
220         mMobileNetworkInfoEntityList = mobileNetworkInfoEntityList;
221         update();
222     }
223 }
224