• 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 static androidx.lifecycle.Lifecycle.Event.ON_START;
20 import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
21 
22 import android.content.Context;
23 import android.os.PersistableBundle;
24 import android.telephony.CarrierConfigManager;
25 import android.telephony.SubscriptionManager;
26 import android.telephony.TelephonyManager;
27 import android.util.Log;
28 
29 import androidx.annotation.VisibleForTesting;
30 import androidx.fragment.app.FragmentManager;
31 import androidx.lifecycle.LifecycleObserver;
32 import androidx.lifecycle.LifecycleOwner;
33 import androidx.lifecycle.OnLifecycleEvent;
34 import androidx.preference.Preference;
35 import androidx.preference.PreferenceScreen;
36 
37 import com.android.settings.network.MobileNetworkRepository;
38 import com.android.settingslib.RestrictedSwitchPreference;
39 import com.android.settingslib.core.lifecycle.Lifecycle;
40 import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
41 
42 import java.util.ArrayList;
43 import java.util.List;
44 
45 /**
46  * Preference controller for "Roaming"
47  */
48 public class RoamingPreferenceController extends TelephonyTogglePreferenceController implements
49         LifecycleObserver, MobileNetworkRepository.MobileNetworkCallback {
50     private static final String TAG = "RoamingController";
51     private static final String DIALOG_TAG = "MobileDataDialog";
52 
53     private RestrictedSwitchPreference mSwitchPreference;
54     private TelephonyManager mTelephonyManager;
55     private CarrierConfigManager mCarrierConfigManager;
56     protected MobileNetworkRepository mMobileNetworkRepository;
57     protected LifecycleOwner mLifecycleOwner;
58     private List<MobileNetworkInfoEntity> mMobileNetworkInfoEntityList = new ArrayList<>();
59 
60     @VisibleForTesting
61     FragmentManager mFragmentManager;
62     MobileNetworkInfoEntity mMobileNetworkInfoEntity;
63 
RoamingPreferenceController(Context context, String key, Lifecycle lifecycle, LifecycleOwner lifecycleOwner, int subId)64     public RoamingPreferenceController(Context context, String key, Lifecycle lifecycle,
65             LifecycleOwner lifecycleOwner, int subId) {
66         this(context, key);
67         mSubId = subId;
68         mLifecycleOwner = lifecycleOwner;
69         if (lifecycle != null) {
70             lifecycle.addObserver(this);
71         }
72     }
73 
RoamingPreferenceController(Context context, String key)74     public RoamingPreferenceController(Context context, String key) {
75         super(context, key);
76         mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
77         mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
78     }
79 
80     @Override
getAvailabilityStatus()81     public int getAvailabilityStatus() {
82         final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
83         if (carrierConfig != null && carrierConfig.getBoolean(
84                 CarrierConfigManager.KEY_FORCE_HOME_NETWORK_BOOL)) {
85             return CONDITIONALLY_UNAVAILABLE;
86         }
87         return AVAILABLE;
88     }
89 
90     @OnLifecycleEvent(ON_START)
onStart()91     public void onStart() {
92         mMobileNetworkRepository.addRegister(mLifecycleOwner, this, mSubId);
93         mMobileNetworkRepository.updateEntity();
94     }
95 
96     @OnLifecycleEvent(ON_STOP)
onStop()97     public void onStop() {
98         mMobileNetworkRepository.removeRegister(this);
99     }
100 
101     @Override
displayPreference(PreferenceScreen screen)102     public void displayPreference(PreferenceScreen screen) {
103         super.displayPreference(screen);
104         mSwitchPreference = screen.findPreference(getPreferenceKey());
105     }
106 
107     @Override
getAvailabilityStatus(int subId)108     public int getAvailabilityStatus(int subId) {
109         return mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
110                 ? AVAILABLE
111                 : AVAILABLE_UNSEARCHABLE;
112     }
113 
114     @Override
setChecked(boolean isChecked)115     public boolean setChecked(boolean isChecked) {
116         if (isDialogNeeded()) {
117             showDialog();
118         } else {
119             // Update data directly if we don't need dialog
120             mTelephonyManager.setDataRoamingEnabled(isChecked);
121             return true;
122         }
123 
124         return false;
125     }
126 
127     @Override
updateState(Preference preference)128     public void updateState(Preference preference) {
129         super.updateState(preference);
130         mSwitchPreference = (RestrictedSwitchPreference) preference;
131         update();
132     }
133 
update()134     private void update() {
135         if (mSwitchPreference == null) {
136             return;
137         }
138         if (!mSwitchPreference.isDisabledByAdmin()) {
139             mSwitchPreference.setEnabled(mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID);
140             mSwitchPreference.setChecked(isChecked());
141         }
142     }
143 
144     @VisibleForTesting
isDialogNeeded()145     boolean isDialogNeeded() {
146         final boolean isRoamingEnabled = mMobileNetworkInfoEntity == null ? false
147                 : mMobileNetworkInfoEntity.isDataRoamingEnabled;
148         final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(
149                 mSubId);
150         // Need dialog if we need to turn on roaming and the roaming charge indication is allowed
151         if (!isRoamingEnabled && (carrierConfig == null || !carrierConfig.getBoolean(
152                 CarrierConfigManager.KEY_DISABLE_CHARGE_INDICATION_BOOL))) {
153             return true;
154         }
155         return false;
156     }
157 
158     @Override
isChecked()159     public boolean isChecked() {
160         return mMobileNetworkInfoEntity == null ? false
161                 : mMobileNetworkInfoEntity.isDataRoamingEnabled;
162     }
163 
init(FragmentManager fragmentManager, int subId, MobileNetworkInfoEntity entity)164     public void init(FragmentManager fragmentManager, int subId, MobileNetworkInfoEntity entity) {
165         mFragmentManager = fragmentManager;
166         mSubId = subId;
167         mMobileNetworkInfoEntity = entity;
168         mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
169         if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
170             return;
171         }
172         final TelephonyManager telephonyManager = mTelephonyManager
173                 .createForSubscriptionId(mSubId);
174         if (telephonyManager == null) {
175             Log.w(TAG, "fail to init in sub" + mSubId);
176             mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
177             return;
178         }
179         mTelephonyManager = telephonyManager;
180     }
181 
showDialog()182     private void showDialog() {
183         final RoamingDialogFragment dialogFragment = RoamingDialogFragment.newInstance(mSubId);
184 
185         dialogFragment.show(mFragmentManager, DIALOG_TAG);
186     }
187 
188     @VisibleForTesting
setMobileNetworkInfoEntity(MobileNetworkInfoEntity mobileNetworkInfoEntity)189     public void setMobileNetworkInfoEntity(MobileNetworkInfoEntity mobileNetworkInfoEntity) {
190         mMobileNetworkInfoEntity = mobileNetworkInfoEntity;
191     }
192 
193     @Override
onAllMobileNetworkInfoChanged( List<MobileNetworkInfoEntity> mobileNetworkInfoEntityList)194     public void onAllMobileNetworkInfoChanged(
195             List<MobileNetworkInfoEntity> mobileNetworkInfoEntityList) {
196         mMobileNetworkInfoEntityList = mobileNetworkInfoEntityList;
197         mMobileNetworkInfoEntityList.forEach(entity -> {
198             if (Integer.parseInt(entity.subId) == mSubId) {
199                 mMobileNetworkInfoEntity = entity;
200                 update();
201                 refreshSummary(mSwitchPreference);
202                 return;
203             }
204         });
205     }
206 
207     @Override
onDataRoamingChanged(int subId, boolean enabled)208     public void onDataRoamingChanged(int subId, boolean enabled) {
209         if (subId != mSubId) {
210             Log.d(TAG, "onDataRoamingChanged - wrong subId : " + subId + " / " + enabled);
211             return;
212         }
213         update();
214     }
215 }
216