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.content.Context;
20 import android.net.ConnectivityManager;
21 import android.os.Bundle;
22 import android.provider.Settings;
23 import android.telephony.SubscriptionInfo;
24 import android.telephony.SubscriptionManager;
25 
26 import androidx.annotation.NonNull;
27 import androidx.annotation.VisibleForTesting;
28 import androidx.annotation.XmlRes;
29 
30 import com.android.car.settings.R;
31 import com.android.car.settings.common.SettingsFragment;
32 import com.android.car.settings.datausage.DataUsagePreferenceController;
33 import com.android.car.settings.datausage.DataUsageSummaryPreferenceController;
34 import com.android.car.settings.datausage.DataWarningAndLimitPreferenceController;
35 import com.android.car.settings.search.CarBaseSearchIndexProvider;
36 import com.android.car.ui.toolbar.ToolbarController;
37 import com.android.internal.telephony.flags.Flags;
38 import com.android.internal.util.CollectionUtils;
39 import com.android.settingslib.search.SearchIndexable;
40 
41 import com.google.android.collect.Lists;
42 
43 import java.util.Arrays;
44 import java.util.List;
45 
46 /** Mobile network settings homepage. */
47 @SearchIndexable
48 public class MobileNetworkFragment extends SettingsFragment implements
49         MobileNetworkUpdateManager.MobileNetworkUpdateListener {
50 
51     @VisibleForTesting
52     static final String ARG_NETWORK_SUB_ID = "network_sub_id";
53 
54     private SubscriptionManager mSubscriptionManager;
55     private MobileNetworkUpdateManager mMobileNetworkUpdateManager;
56     private CharSequence mTitle;
57 
58     /**
59      * Creates a new instance of the {@link MobileNetworkFragment}, which shows settings related to
60      * the given {@code subId}.
61      */
newInstance(int subId)62     public static MobileNetworkFragment newInstance(int subId) {
63         MobileNetworkFragment fragment = new MobileNetworkFragment();
64         Bundle args = new Bundle();
65         args.putInt(ARG_NETWORK_SUB_ID, subId);
66         fragment.setArguments(args);
67         return fragment;
68     }
69 
70     @Override
71     @XmlRes
getPreferenceScreenResId()72     protected int getPreferenceScreenResId() {
73         return R.xml.mobile_network_fragment;
74     }
75 
76     @Override
onAttach(Context context)77     public void onAttach(Context context) {
78         super.onAttach(context);
79         mSubscriptionManager = getSubscriptionManager(context);
80 
81         int subId = getArguments() != null
82                 ? getArguments().getInt(ARG_NETWORK_SUB_ID, MobileNetworkUpdateManager.SUB_ID_NULL)
83                 : MobileNetworkUpdateManager.SUB_ID_NULL;
84         mMobileNetworkUpdateManager = getMobileNetworkUpdateManager(context, subId);
85         getLifecycle().addObserver(mMobileNetworkUpdateManager);
86 
87         List<MobileNetworkUpdateManager.MobileNetworkUpdateListener> listeners =
88                 Lists.newArrayList(
89                         this,
90                         use(MobileDataTogglePreferenceController.class,
91                                 R.string.pk_mobile_data_toggle),
92                         use(RoamingPreferenceController.class, R.string.pk_mobile_roaming_toggle));
93         for (MobileNetworkUpdateManager.MobileNetworkUpdateListener listener : listeners) {
94             mMobileNetworkUpdateManager.registerListener(listener);
95         }
96 
97         List<NetworkBasePreferenceController> preferenceControllers =
98                 Arrays.asList(
99                         use(DataUsageSummaryPreferenceController.class,
100                                 R.string.pk_data_usage_summary),
101                         use(MobileDataTogglePreferenceController.class,
102                                 R.string.pk_mobile_data_toggle),
103                         use(RoamingPreferenceController.class, R.string.pk_mobile_roaming_toggle),
104                         use(DataUsagePreferenceController.class, R.string.pk_app_data_usage),
105                         use(DataWarningAndLimitPreferenceController.class,
106                                 R.string.pk_data_warning_and_limit));
107 
108         for (NetworkBasePreferenceController preferenceController :
109                 preferenceControllers) {
110             preferenceController.setFields(subId);
111         }
112     }
113 
114     @Override
setupToolbar(@onNull ToolbarController toolbar)115     protected void setupToolbar(@NonNull ToolbarController toolbar) {
116         super.setupToolbar(toolbar);
117 
118         if (mTitle != null) {
119             toolbar.setTitle(mTitle);
120         }
121     }
122 
123     @Override
onMobileNetworkUpdated(int subId)124     public void onMobileNetworkUpdated(int subId) {
125         SubscriptionInfo info = null;
126 
127         if (subId != MobileNetworkUpdateManager.SUB_ID_NULL) {
128             for (SubscriptionInfo subscriptionInfo :
129                     mSubscriptionManager.getSelectableSubscriptionInfoList()) {
130                 if (subscriptionInfo.getSubscriptionId() == subId) {
131                     info = subscriptionInfo;
132                 }
133             }
134         }
135 
136         if (info == null && !CollectionUtils.isEmpty(
137                 mSubscriptionManager.getActiveSubscriptionInfoList())) {
138             info = mSubscriptionManager.getActiveSubscriptionInfoList().get(0);
139         }
140 
141         if (info != null) {
142             // It is possible for this to be called before the activity is fully created. If so,
143             // cache the value so that it can be constructed when setupToolbar is called.
144             mTitle = info.getDisplayName();
145             if (getToolbar() != null) {
146                 getToolbar().setTitle(mTitle);
147             }
148         }
149     }
150 
151     @VisibleForTesting
getSubscriptionManager(Context context)152     SubscriptionManager getSubscriptionManager(Context context) {
153         SubscriptionManager sm = context.getSystemService(SubscriptionManager.class);
154         if (Flags.workProfileApiSplit()) {
155             sm = sm.createForAllUserProfiles();
156         }
157         return sm;
158     }
159 
160     @VisibleForTesting
getMobileNetworkUpdateManager(Context context, int subId)161     MobileNetworkUpdateManager getMobileNetworkUpdateManager(Context context, int subId) {
162         return new MobileNetworkUpdateManager(context, subId);
163     }
164 
165     public static final CarBaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
166             new CarBaseSearchIndexProvider(R.xml.mobile_network_fragment,
167                     Settings.ACTION_NETWORK_OPERATOR_SETTINGS) {
168                 @Override
169                 protected boolean isPageSearchEnabled(Context context) {
170                     return NetworkUtils.hasMobileNetwork(
171                             context.getSystemService(ConnectivityManager.class));
172                 }
173             };
174 }
175