• 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.car.settings.network;
18 
19 import static com.android.car.datasubscription.DataSubscription.DATA_SUBSCRIPTION_ACTION;
20 
21 import android.annotation.SuppressLint;
22 import android.car.drivingstate.CarUxRestrictions;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.database.ContentObserver;
26 import android.net.ConnectivityManager;
27 import android.net.Uri;
28 import android.os.Handler;
29 import android.os.Looper;
30 import android.os.UserManager;
31 import android.provider.Settings;
32 import android.telephony.SubscriptionInfo;
33 import android.telephony.SubscriptionManager;
34 import android.telephony.TelephonyManager;
35 
36 import androidx.annotation.CallSuper;
37 import androidx.annotation.VisibleForTesting;
38 
39 import com.android.car.datasubscription.DataSubscription;
40 import com.android.car.settings.R;
41 import com.android.car.settings.common.ColoredTwoActionSwitchPreference;
42 import com.android.car.settings.common.FragmentController;
43 import com.android.car.settings.common.PreferenceController;
44 import com.android.settingslib.utils.StringUtil;
45 
46 import java.util.List;
47 
48 /** Controls the preference for accessing mobile network settings. */
49 public class MobileNetworkEntryPreferenceController extends
50         PreferenceController<ColoredTwoActionSwitchPreference> implements
51         SubscriptionsChangeListener.SubscriptionsChangeAction,
52         DataSubscription.DataSubscriptionChangeListener {
53     private final UserManager mUserManager;
54     private final SubscriptionsChangeListener mChangeListener;
55     private final SubscriptionManager mSubscriptionManager;
56     private final ConnectivityManager mConnectivityManager;
57     private final TelephonyManager mTelephonyManager;
58     private final int mSubscriptionId;
59     private final ContentObserver mMobileDataChangeObserver = new ContentObserver(
60             new Handler(Looper.getMainLooper())) {
61         @Override
62         public void onChange(boolean selfChange) {
63             super.onChange(selfChange);
64             refreshUi();
65         }
66     };
67     private DataSubscription mSubscription;
68 
69     @SuppressLint("MissingPermission")
MobileNetworkEntryPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)70     public MobileNetworkEntryPreferenceController(Context context, String preferenceKey,
71             FragmentController fragmentController, CarUxRestrictions uxRestrictions) {
72         super(context, preferenceKey, fragmentController, uxRestrictions);
73         mUserManager = UserManager.get(context);
74         mChangeListener = new SubscriptionsChangeListener(context, /* action= */ this);
75         mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
76         mConnectivityManager = context.getSystemService(ConnectivityManager.class);
77         mTelephonyManager = context.getSystemService(TelephonyManager.class);
78         mSubscriptionId = SubscriptionManager.getDefaultDataSubscriptionId();
79         if (isDataSubscriptionFlagEnable()) {
80             mSubscription = new DataSubscription(context);
81         }
82     }
83 
84     @Override
getPreferenceType()85     protected Class<ColoredTwoActionSwitchPreference> getPreferenceType() {
86         return ColoredTwoActionSwitchPreference.class;
87     }
88 
89     @Override
onCreateInternal()90     protected void onCreateInternal() {
91         super.onCreateInternal();
92         getPreference().setOnSecondaryActionClickListener(this::onSecondaryActionClick);
93     }
94 
95     @Override
updateState(ColoredTwoActionSwitchPreference preference)96     protected void updateState(ColoredTwoActionSwitchPreference preference) {
97         List<SubscriptionInfo> subs = SubscriptionUtils.getAvailableSubscriptions(
98                 mSubscriptionManager, mTelephonyManager);
99         preference.setEnabled(getAvailabilityStatus() == AVAILABLE);
100         preference.setSummary(getSummary(subs));
101         preference.setActionText(getActionText());
102         getPreference().setSecondaryActionChecked(mTelephonyManager.isDataEnabled());
103     }
104 
105     @Override
onStartInternal()106     protected void onStartInternal() {
107         mChangeListener.start();
108         if (mSubscriptionId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
109             getContext().getContentResolver().registerContentObserver(getObservableUri(
110                     mSubscriptionId), /* notifyForDescendants= */ false, mMobileDataChangeObserver);
111         }
112         if (mSubscription != null) {
113             mSubscription.addDataSubscriptionListener(this);
114         }
115     }
116 
117     @Override
onStopInternal()118     protected void onStopInternal() {
119         mChangeListener.stop();
120         if (mSubscriptionId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
121             getContext().getContentResolver().unregisterContentObserver(mMobileDataChangeObserver);
122         }
123         if (mSubscription != null) {
124             mSubscription.removeDataSubscriptionListener();
125         }
126     }
127 
128     @Override
getDefaultAvailabilityStatus()129     protected int getDefaultAvailabilityStatus() {
130         if (!NetworkUtils.hasMobileNetwork(mConnectivityManager)
131                 && !NetworkUtils.hasSim(mTelephonyManager)) {
132             return UNSUPPORTED_ON_DEVICE;
133         }
134         boolean isNotAdmin = !mUserManager.isAdminUser();
135         boolean hasRestriction =
136                 mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
137         if (isNotAdmin || hasRestriction) {
138             return DISABLED_FOR_PROFILE;
139         }
140         return AVAILABLE;
141     }
142 
143     @Override
handlePreferenceClicked(ColoredTwoActionSwitchPreference preference)144     protected boolean handlePreferenceClicked(ColoredTwoActionSwitchPreference preference) {
145         if (isDataSubscriptionFlagEnable()
146                 && mSubscription.isDataSubscriptionInactive()) {
147             Intent dataSubscriptionIntent = new Intent(DATA_SUBSCRIPTION_ACTION);
148             dataSubscriptionIntent.setPackage(getContext().getString(
149                     R.string.connectivity_flow_app));
150             dataSubscriptionIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
151             getContext().startActivity(dataSubscriptionIntent);
152             return true;
153         }
154         List<SubscriptionInfo> subs = SubscriptionUtils.getAvailableSubscriptions(
155                 mSubscriptionManager, mTelephonyManager);
156         if (subs.isEmpty()) {
157             return true;
158         } else if (subs.size() == 1) {
159             getFragmentController().launchFragment(
160                     MobileNetworkFragment.newInstance(subs.get(0).getSubscriptionId()));
161         } else {
162             getFragmentController().launchFragment(new MobileNetworkListFragment());
163         }
164         return true;
165     }
166 
167     @Override
handlePreferenceChanged(ColoredTwoActionSwitchPreference preference, Object newValue)168     protected boolean handlePreferenceChanged(ColoredTwoActionSwitchPreference preference,
169             Object newValue) {
170         List<SubscriptionInfo> subs = SubscriptionUtils.getAvailableSubscriptions(
171                 mSubscriptionManager, mTelephonyManager);
172         preference.setSummary(getSummary(subs));
173         preference.setActionText(getActionText());
174         return true;
175     }
176 
177     @Override
178     @CallSuper
onSubscriptionsChanged()179     public void onSubscriptionsChanged() {
180         refreshUi();
181     }
182 
getSummary(List<SubscriptionInfo> subs)183     private CharSequence getSummary(List<SubscriptionInfo> subs) {
184         if (!mTelephonyManager.isDataEnabled()) {
185             return getContext().getString(R.string.mobile_network_state_off);
186         }
187         if (isDataSubscriptionFlagEnable()
188                 && mSubscription.isDataSubscriptionInactive()) {
189             return getContext().getString(R.string.connectivity_inactive_prompt);
190         }
191         int count = subs.size();
192         if (subs.isEmpty()) {
193             return null;
194         } else if (count == 1) {
195             return subs.get(0).getDisplayName();
196         } else {
197             return StringUtil.getIcuPluralsString(getContext(), count,
198                     R.string.mobile_network_summary_count);
199         }
200     }
201 
getActionText()202     private CharSequence getActionText() {
203         if (!mTelephonyManager.isDataEnabled()) {
204             return null;
205         }
206         if (isDataSubscriptionFlagEnable()
207                 && mSubscription.isDataSubscriptionInactive()
208                 && !getUxRestrictions().isRequiresDistractionOptimization()) {
209             getPreference().setIsWarning(true);
210             return getContext().getString(R.string.connectivity_inactive_action_text);
211         }
212         return null;
213     }
214 
getObservableUri(int subId)215     private Uri getObservableUri(int subId) {
216         Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA);
217         if (mTelephonyManager.getSimCount() != 1) {
218             uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + subId);
219         }
220         return uri;
221     }
222 
223     @VisibleForTesting
onSecondaryActionClick(boolean isChecked)224     void onSecondaryActionClick(boolean isChecked) {
225         mTelephonyManager.setDataEnabled(isChecked);
226         handlePreferenceChanged(getPreference(), isChecked);
227     }
228 
229     @VisibleForTesting
setSubscription(DataSubscription subscription)230     void setSubscription(DataSubscription subscription) {
231         mSubscription = subscription;
232     }
233 
isDataSubscriptionFlagEnable()234     private boolean isDataSubscriptionFlagEnable() {
235         return com.android.car.datasubscription.Flags.dataSubscriptionPopUp();
236     }
237 
238     @Override
onChange(int value)239     public void onChange(int value) {
240         refreshUi();
241     }
242 }
243