• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.telephony;
18 
19 import android.content.Context;
20 import android.os.PersistableBundle;
21 import android.provider.Settings;
22 import android.telephony.CarrierConfigManager;
23 import android.telephony.SubscriptionManager;
24 import android.telephony.TelephonyManager;
25 import android.util.Log;
26 
27 import androidx.annotation.VisibleForTesting;
28 import androidx.fragment.app.FragmentManager;
29 import androidx.preference.Preference;
30 import androidx.preference.PreferenceScreen;
31 
32 import com.android.settings.network.GlobalSettingsChangeListener;
33 import com.android.settingslib.RestrictedSwitchPreference;
34 import com.android.settingslib.core.lifecycle.LifecycleObserver;
35 import com.android.settingslib.core.lifecycle.events.OnStart;
36 import com.android.settingslib.core.lifecycle.events.OnStop;
37 
38 /**
39  * Preference controller for "Roaming"
40  */
41 public class RoamingPreferenceController extends TelephonyTogglePreferenceController implements
42         LifecycleObserver, OnStart, OnStop {
43 
44     private static final String TAG = "RoamingController";
45     private static final String DIALOG_TAG = "MobileDataDialog";
46 
47     private RestrictedSwitchPreference mSwitchPreference;
48     private TelephonyManager mTelephonyManager;
49     private CarrierConfigManager mCarrierConfigManager;
50 
51     /**
52      * There're 2 listeners both activated at the same time.
53      * For project that access DATA_ROAMING, only first listener is functional.
54      * For project that access "DATA_ROAMING + subId", first listener will be stopped when receiving
55      * any onChange from second listener.
56      */
57     private GlobalSettingsChangeListener mListener;
58     private GlobalSettingsChangeListener mListenerForSubId;
59 
60     @VisibleForTesting
61     FragmentManager mFragmentManager;
62 
RoamingPreferenceController(Context context, String key)63     public RoamingPreferenceController(Context context, String key) {
64         super(context, key);
65         mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
66     }
67 
68     @Override
onStart()69     public void onStart() {
70         if (mListener == null) {
71             mListener = new GlobalSettingsChangeListener(mContext,
72                     Settings.Global.DATA_ROAMING) {
73                 public void onChanged(String field) {
74                     updateState(mSwitchPreference);
75                 }
76             };
77         }
78         stopMonitorSubIdSpecific();
79 
80         if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
81             return;
82         }
83 
84         mListenerForSubId = new GlobalSettingsChangeListener(mContext,
85                 Settings.Global.DATA_ROAMING + mSubId) {
86             public void onChanged(String field) {
87                 stopMonitor();
88                 updateState(mSwitchPreference);
89             }
90         };
91     }
92 
93     @Override
onStop()94     public void onStop() {
95         stopMonitor();
96         stopMonitorSubIdSpecific();
97     }
98 
99     @Override
displayPreference(PreferenceScreen screen)100     public void displayPreference(PreferenceScreen screen) {
101         super.displayPreference(screen);
102         mSwitchPreference = screen.findPreference(getPreferenceKey());
103     }
104 
105     @Override
getAvailabilityStatus(int subId)106     public int getAvailabilityStatus(int subId) {
107         return subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
108                 ? AVAILABLE
109                 : AVAILABLE_UNSEARCHABLE;
110     }
111 
112     @Override
setChecked(boolean isChecked)113     public boolean setChecked(boolean isChecked) {
114         if (isDialogNeeded()) {
115             showDialog();
116         } else {
117             // Update data directly if we don't need dialog
118             mTelephonyManager.setDataRoamingEnabled(isChecked);
119             return true;
120         }
121 
122         return false;
123     }
124 
125     @Override
updateState(Preference preference)126     public void updateState(Preference preference) {
127         super.updateState(preference);
128         final RestrictedSwitchPreference switchPreference = (RestrictedSwitchPreference) preference;
129         if (!switchPreference.isDisabledByAdmin()) {
130             switchPreference.setEnabled(mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID);
131             switchPreference.setChecked(isChecked());
132         }
133     }
134 
135     @VisibleForTesting
isDialogNeeded()136     boolean isDialogNeeded() {
137         final boolean isRoamingEnabled = mTelephonyManager.isDataRoamingEnabled();
138         final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(
139                 mSubId);
140 
141         // Need dialog if we need to turn on roaming and the roaming charge indication is allowed
142         if (!isRoamingEnabled && (carrierConfig == null || !carrierConfig.getBoolean(
143                 CarrierConfigManager.KEY_DISABLE_CHARGE_INDICATION_BOOL))) {
144             return true;
145         }
146         return false;
147     }
148 
149     @Override
isChecked()150     public boolean isChecked() {
151         return mTelephonyManager.isDataRoamingEnabled();
152     }
153 
init(FragmentManager fragmentManager, int subId)154     public void init(FragmentManager fragmentManager, int subId) {
155         mFragmentManager = fragmentManager;
156         mSubId = subId;
157         mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
158         if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
159             return;
160         }
161         final TelephonyManager telephonyManager = mTelephonyManager
162                 .createForSubscriptionId(mSubId);
163         if (telephonyManager == null) {
164             Log.w(TAG, "fail to init in sub" + mSubId);
165             mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
166             return;
167         }
168         mTelephonyManager = telephonyManager;
169     }
170 
showDialog()171     private void showDialog() {
172         final RoamingDialogFragment dialogFragment = RoamingDialogFragment.newInstance(mSubId);
173 
174         dialogFragment.show(mFragmentManager, DIALOG_TAG);
175     }
176 
stopMonitor()177     private void stopMonitor() {
178         if (mListener != null) {
179             mListener.close();
180             mListener = null;
181         }
182     }
183 
stopMonitorSubIdSpecific()184     private void stopMonitorSubIdSpecific() {
185         if (mListenerForSubId != null) {
186             mListenerForSubId.close();
187             mListenerForSubId = null;
188         }
189     }
190 }
191