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 android.car.drivingstate.CarUxRestrictions;
20 import android.content.Context;
21 import android.database.ContentObserver;
22 import android.net.Uri;
23 import android.os.Handler;
24 import android.os.Looper;
25 import android.os.UserManager;
26 import android.provider.Settings;
27 import android.telephony.SubscriptionInfo;
28 import android.telephony.SubscriptionManager;
29 import android.telephony.TelephonyManager;
30 
31 import androidx.annotation.CallSuper;
32 
33 import com.android.car.settings.R;
34 import com.android.car.settings.common.FragmentController;
35 import com.android.car.settings.common.PreferenceController;
36 import com.android.car.ui.preference.CarUiTwoActionSwitchPreference;
37 import com.android.settingslib.utils.StringUtil;
38 
39 import java.util.List;
40 
41 /** Controls the preference for accessing mobile network settings. */
42 public class MobileNetworkEntryPreferenceController extends
43         PreferenceController<CarUiTwoActionSwitchPreference> implements
44         SubscriptionsChangeListener.SubscriptionsChangeAction {
45 
46     private final UserManager mUserManager;
47     private final SubscriptionsChangeListener mChangeListener;
48     private final SubscriptionManager mSubscriptionManager;
49     private final TelephonyManager mTelephonyManager;
50     private final int mSubscriptionId;
51     private final ContentObserver mMobileDataChangeObserver = new ContentObserver(
52             new Handler(Looper.getMainLooper())) {
53         @Override
54         public void onChange(boolean selfChange) {
55             super.onChange(selfChange);
56             refreshUi();
57         }
58     };
59 
MobileNetworkEntryPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)60     public MobileNetworkEntryPreferenceController(Context context, String preferenceKey,
61             FragmentController fragmentController, CarUxRestrictions uxRestrictions) {
62         super(context, preferenceKey, fragmentController, uxRestrictions);
63         mUserManager = UserManager.get(context);
64         mChangeListener = new SubscriptionsChangeListener(context, /* action= */ this);
65         mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
66         mTelephonyManager = context.getSystemService(TelephonyManager.class);
67         mSubscriptionId = SubscriptionManager.getDefaultDataSubscriptionId();
68     }
69 
70     @Override
getPreferenceType()71     protected Class<CarUiTwoActionSwitchPreference> getPreferenceType() {
72         return CarUiTwoActionSwitchPreference.class;
73     }
74 
75     @Override
onCreateInternal()76     protected void onCreateInternal() {
77         super.onCreateInternal();
78         getPreference().setOnSecondaryActionClickListener(isChecked -> {
79             mTelephonyManager.setDataEnabled(isChecked);
80         });
81     }
82 
83     @Override
updateState(CarUiTwoActionSwitchPreference preference)84     protected void updateState(CarUiTwoActionSwitchPreference preference) {
85         List<SubscriptionInfo> subs = SubscriptionUtils.getAvailableSubscriptions(
86                 mSubscriptionManager, mTelephonyManager);
87         preference.setEnabled(!subs.isEmpty());
88         preference.setSummary(getSummary(subs));
89         getPreference().setSecondaryActionChecked(mTelephonyManager.isDataEnabled());
90     }
91 
92     @Override
onStartInternal()93     protected void onStartInternal() {
94         mChangeListener.start();
95         if (mSubscriptionId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
96             getContext().getContentResolver().registerContentObserver(getObservableUri(
97                     mSubscriptionId), /* notifyForDescendants= */ false, mMobileDataChangeObserver);
98         }
99     }
100 
101     @Override
onStopInternal()102     protected void onStopInternal() {
103         mChangeListener.stop();
104         if (mSubscriptionId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
105             getContext().getContentResolver().unregisterContentObserver(mMobileDataChangeObserver);
106         }
107     }
108 
109     @Override
getAvailabilityStatus()110     protected int getAvailabilityStatus() {
111         if (!NetworkUtils.hasSim(mTelephonyManager)) {
112             return UNSUPPORTED_ON_DEVICE;
113         }
114 
115         boolean isNotAdmin = !mUserManager.isAdminUser();
116         boolean hasRestriction =
117                 mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
118         if (isNotAdmin || hasRestriction) {
119             return DISABLED_FOR_PROFILE;
120         }
121         return AVAILABLE;
122     }
123 
124     @Override
handlePreferenceClicked(CarUiTwoActionSwitchPreference preference)125     protected boolean handlePreferenceClicked(CarUiTwoActionSwitchPreference preference) {
126         List<SubscriptionInfo> subs = SubscriptionUtils.getAvailableSubscriptions(
127                 mSubscriptionManager, mTelephonyManager);
128         if (subs.isEmpty()) {
129             return true;
130         }
131 
132         if (subs.size() == 1) {
133             getFragmentController().launchFragment(
134                     MobileNetworkFragment.newInstance(subs.get(0).getSubscriptionId()));
135         } else {
136             getFragmentController().launchFragment(new MobileNetworkListFragment());
137         }
138         return true;
139     }
140 
141     @Override
142     @CallSuper
onSubscriptionsChanged()143     public void onSubscriptionsChanged() {
144         refreshUi();
145     }
146 
getSummary(List<SubscriptionInfo> subs)147     private CharSequence getSummary(List<SubscriptionInfo> subs) {
148         int count = subs.size();
149         if (subs.isEmpty()) {
150             return null;
151         } else if (count == 1) {
152             return subs.get(0).getDisplayName();
153         } else {
154             return StringUtil.getIcuPluralsString(getContext(), count,
155                     R.string.mobile_network_summary_count);
156         }
157     }
158 
getObservableUri(int subId)159     private Uri getObservableUri(int subId) {
160         Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA);
161         if (mTelephonyManager.getSimCount() != 1) {
162             uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + subId);
163         }
164         return uri;
165     }
166 }
167