1 /* 2 * Copyright 2021 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.internal.telephony.data; 18 19 import android.annotation.CallbackExecutor; 20 import android.annotation.NonNull; 21 import android.content.ContentResolver; 22 import android.content.Context; 23 import android.content.SharedPreferences; 24 import android.os.Handler; 25 import android.os.Looper; 26 import android.os.Message; 27 import android.os.SystemProperties; 28 import android.preference.PreferenceManager; 29 import android.provider.Settings; 30 import android.sysprop.TelephonyProperties; 31 import android.telephony.CarrierConfigManager; 32 import android.telephony.SubscriptionInfo; 33 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; 34 import android.telephony.TelephonyManager; 35 import android.telephony.TelephonyRegistryManager; 36 import android.telephony.data.ApnSetting; 37 import android.telephony.data.ApnSetting.ApnType; 38 import android.util.ArrayMap; 39 import android.util.ArraySet; 40 import android.util.IndentingPrintWriter; 41 import android.util.LocalLog; 42 43 import com.android.internal.telephony.GlobalSettingsHelper; 44 import com.android.internal.telephony.Phone; 45 import com.android.internal.telephony.SettingsObserver; 46 import com.android.internal.telephony.SubscriptionController; 47 import com.android.internal.telephony.data.DataConfigManager.DataConfigManagerCallback; 48 import com.android.telephony.Rlog; 49 50 import java.io.FileDescriptor; 51 import java.io.PrintWriter; 52 import java.util.Map; 53 import java.util.Set; 54 import java.util.concurrent.Executor; 55 import java.util.stream.Collectors; 56 57 /** 58 * DataSettingsManager maintains the data related settings, for example, data enabled settings, 59 * data roaming settings, etc... 60 */ 61 public class DataSettingsManager extends Handler { 62 /** Event for call state changed. */ 63 private static final int EVENT_CALL_STATE_CHANGED = 2; 64 /** Event for subscriptions updated. */ 65 private static final int EVENT_SUBSCRIPTIONS_CHANGED = 4; 66 /** Event for set data enabled for reason. */ 67 private static final int EVENT_SET_DATA_ENABLED_FOR_REASON = 5; 68 /** Event for set data roaming enabled. */ 69 private static final int EVENT_SET_DATA_ROAMING_ENABLED = 6; 70 /** Event for set always allow MMS data. */ 71 private static final int EVENT_SET_ALWAYS_ALLOW_MMS_DATA = 7; 72 /** Event for set allow data during voice call. */ 73 private static final int EVENT_SET_ALLOW_DATA_DURING_VOICE_CALL = 8; 74 /** Event for device provisioned changed. */ 75 private static final int EVENT_PROVISIONED_CHANGED = 9; 76 /** Event for provisioning data enabled setting changed. */ 77 private static final int EVENT_PROVISIONING_DATA_ENABLED_CHANGED = 10; 78 /** Event for initializing DataSettingsManager. */ 79 private static final int EVENT_INITIALIZE = 11; 80 81 private final Phone mPhone; 82 private final ContentResolver mResolver; 83 private final SettingsObserver mSettingsObserver; 84 private final String mLogTag; 85 private final LocalLog mLocalLog = new LocalLog(128); 86 private int mSubId; 87 private DataEnabledOverride mDataEnabledOverride; 88 89 /** Data config manager */ 90 private final @NonNull DataConfigManager mDataConfigManager; 91 92 /** Data settings manager callbacks. */ 93 private final @NonNull Set<DataSettingsManagerCallback> mDataSettingsManagerCallbacks = 94 new ArraySet<>(); 95 96 /** Mapping of {@link TelephonyManager.DataEnabledReason} to data enabled values. */ 97 private final Map<Integer, Boolean> mDataEnabledSettings = new ArrayMap<>(); 98 99 /** 100 * Flag indicating whether data is allowed or not for the device. 101 * It can be disabled by user, carrier, policy or thermal. 102 */ 103 private boolean mIsDataEnabled; 104 105 /** 106 * Used to indicate that the initial value for mIsDataEnabled was set. 107 * Prevent race condition where the initial value might be incorrect. 108 */ 109 private boolean mInitialized = false; 110 111 /** 112 * Data settings manager callback. This should be only used by {@link DataNetworkController}. 113 */ 114 public static class DataSettingsManagerCallback extends DataCallback { 115 /** 116 * Constructor 117 * 118 * @param executor The executor of the callback. 119 */ DataSettingsManagerCallback(@onNull @allbackExecutor Executor executor)120 public DataSettingsManagerCallback(@NonNull @CallbackExecutor Executor executor) { 121 super(executor); 122 } 123 124 /** 125 * Called when overall data enabled state changed. 126 * 127 * @param enabled {@code true} indicates mobile data is enabled. 128 * @param reason {@link TelephonyManager.DataEnabledChangedReason} indicating the reason why 129 * mobile data enabled changed. 130 * @param callingPackage The package that changed the data enabled state. 131 */ onDataEnabledChanged(boolean enabled, @TelephonyManager.DataEnabledChangedReason int reason, @NonNull String callingPackage)132 public void onDataEnabledChanged(boolean enabled, 133 @TelephonyManager.DataEnabledChangedReason int reason, 134 @NonNull String callingPackage) {} 135 136 /** 137 * Called when data enabled override changed. 138 * 139 * @param enabled {@code true} indicates data enabled override is enabled. 140 * @param policy {@link TelephonyManager.MobileDataPolicy} indicating the policy that was 141 * enabled or disabled. 142 */ onDataEnabledOverrideChanged(boolean enabled, @TelephonyManager.MobileDataPolicy int policy)143 public void onDataEnabledOverrideChanged(boolean enabled, 144 @TelephonyManager.MobileDataPolicy int policy) {} 145 146 /** 147 * Called when data roaming enabled state changed. 148 * 149 * @param enabled {@code true} indicates data roaming is enabled. 150 */ onDataRoamingEnabledChanged(boolean enabled)151 public void onDataRoamingEnabledChanged(boolean enabled) {} 152 } 153 154 /** 155 * Constructor 156 * 157 * @param phone The phone instance. 158 * @param dataNetworkController Data network controller. 159 * @param looper The looper to be used by the handler. Currently the handler thread is the 160 * phone process's main thread. 161 * @param callback Data settings manager callback. 162 */ DataSettingsManager(@onNull Phone phone, @NonNull DataNetworkController dataNetworkController, @NonNull Looper looper, @NonNull DataSettingsManagerCallback callback)163 public DataSettingsManager(@NonNull Phone phone, 164 @NonNull DataNetworkController dataNetworkController, @NonNull Looper looper, 165 @NonNull DataSettingsManagerCallback callback) { 166 super(looper); 167 mPhone = phone; 168 mLogTag = "DSMGR-" + mPhone.getPhoneId(); 169 log("DataSettingsManager created."); 170 mSubId = mPhone.getSubId(); 171 mResolver = mPhone.getContext().getContentResolver(); 172 registerCallback(callback); 173 mDataConfigManager = dataNetworkController.getDataConfigManager(); 174 mDataEnabledOverride = getDataEnabledOverride(); 175 mSettingsObserver = new SettingsObserver(mPhone.getContext(), this); 176 mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_POLICY, true); 177 mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_CARRIER, true); 178 mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_THERMAL, true); 179 180 // Instead of calling onInitialize directly from the constructor, send the event. 181 // The reason is that getImsPhone is null when we are still in the constructor here. 182 sendEmptyMessage(EVENT_INITIALIZE); 183 } 184 185 @Override handleMessage(Message msg)186 public void handleMessage(Message msg) { 187 switch (msg.what) { 188 case EVENT_CALL_STATE_CHANGED: { 189 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_OVERRIDE); 190 break; 191 } 192 case EVENT_SUBSCRIPTIONS_CHANGED: { 193 mSubId = (int) msg.obj; 194 mDataEnabledOverride = getDataEnabledOverride(); 195 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_USER); 196 mPhone.notifyUserMobileDataStateChanged(isUserDataEnabled()); 197 break; 198 } 199 case EVENT_SET_DATA_ENABLED_FOR_REASON: { 200 String callingPackage = (String) msg.obj; 201 boolean enabled = msg.arg2 == 1; 202 switch (msg.arg1) { 203 case TelephonyManager.DATA_ENABLED_REASON_USER: 204 setUserDataEnabled(enabled, callingPackage); 205 break; 206 case TelephonyManager.DATA_ENABLED_REASON_CARRIER: 207 setCarrierDataEnabled(enabled, callingPackage); 208 break; 209 case TelephonyManager.DATA_ENABLED_REASON_POLICY: 210 setPolicyDataEnabled(enabled, callingPackage); 211 break; 212 case TelephonyManager.DATA_ENABLED_REASON_THERMAL: 213 setThermalDataEnabled(enabled, callingPackage); 214 break; 215 default: 216 log("Cannot set data enabled for reason: " 217 + dataEnabledChangedReasonToString(msg.arg1)); 218 break; 219 } 220 break; 221 } 222 case EVENT_SET_DATA_ROAMING_ENABLED: { 223 boolean enabled = (boolean) msg.obj; 224 setDataRoamingEnabledInternal(enabled); 225 setDataRoamingFromUserAction(); 226 break; 227 } 228 case EVENT_SET_ALWAYS_ALLOW_MMS_DATA: { 229 boolean alwaysAllow = (boolean) msg.obj; 230 if (alwaysAllow == isMmsAlwaysAllowed()) { 231 break; 232 } 233 logl("AlwaysAllowMmsData changed to " + alwaysAllow); 234 mDataEnabledOverride.setAlwaysAllowMms(alwaysAllow); 235 if (SubscriptionController.getInstance() 236 .setDataEnabledOverrideRules(mSubId, mDataEnabledOverride.getRules())) { 237 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_OVERRIDE); 238 notifyDataEnabledOverrideChanged(alwaysAllow, 239 TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED); 240 } 241 break; 242 } 243 case EVENT_SET_ALLOW_DATA_DURING_VOICE_CALL: { 244 boolean allow = (boolean) msg.obj; 245 if (allow == isDataAllowedInVoiceCall()) { 246 break; 247 } 248 logl("AllowDataDuringVoiceCall changed to " + allow); 249 mDataEnabledOverride.setDataAllowedInVoiceCall(allow); 250 if (SubscriptionController.getInstance() 251 .setDataEnabledOverrideRules(mSubId, mDataEnabledOverride.getRules())) { 252 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_OVERRIDE); 253 notifyDataEnabledOverrideChanged(allow, TelephonyManager 254 .MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL); 255 } 256 break; 257 } 258 case EVENT_PROVISIONED_CHANGED: 259 case EVENT_PROVISIONING_DATA_ENABLED_CHANGED: { 260 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_UNKNOWN); 261 break; 262 } 263 case EVENT_INITIALIZE: { 264 onInitialize(); 265 break; 266 } 267 default: 268 loge("Unknown msg.what: " + msg.what); 269 } 270 } 271 272 /** 273 * Called when needed to register for all events that data network controller is interested. 274 */ onInitialize()275 private void onInitialize() { 276 mDataConfigManager.registerCallback(new DataConfigManagerCallback(this::post) { 277 @Override 278 public void onCarrierConfigChanged() { 279 if (mDataConfigManager.isConfigCarrierSpecific()) { 280 setDefaultDataRoamingEnabled(); 281 } 282 } 283 }); 284 mSettingsObserver.observe(Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), 285 EVENT_PROVISIONED_CHANGED); 286 mSettingsObserver.observe( 287 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED), 288 EVENT_PROVISIONING_DATA_ENABLED_CHANGED); 289 mPhone.getCallTracker().registerForVoiceCallStarted(this, EVENT_CALL_STATE_CHANGED, null); 290 mPhone.getCallTracker().registerForVoiceCallEnded(this, EVENT_CALL_STATE_CHANGED, null); 291 if (mPhone.getImsPhone() != null) { 292 mPhone.getImsPhone().getCallTracker().registerForVoiceCallStarted( 293 this, EVENT_CALL_STATE_CHANGED, null); 294 mPhone.getImsPhone().getCallTracker().registerForVoiceCallEnded( 295 this, EVENT_CALL_STATE_CHANGED, null); 296 } 297 mPhone.getContext().getSystemService(TelephonyRegistryManager.class) 298 .addOnSubscriptionsChangedListener(new OnSubscriptionsChangedListener() { 299 @Override 300 public void onSubscriptionsChanged() { 301 if (mSubId != mPhone.getSubId()) { 302 log("onSubscriptionsChanged: " + mSubId + " to " + mPhone.getSubId()); 303 obtainMessage(EVENT_SUBSCRIPTIONS_CHANGED, mPhone.getSubId()) 304 .sendToTarget(); 305 } 306 } 307 }, this::post); 308 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_UNKNOWN); 309 } 310 311 /** 312 * Enable or disable data for a specific {@link TelephonyManager.DataEnabledReason}. 313 * @param reason The reason the data enabled change is taking place. 314 * @param enabled {@code true} to enable data for the given reason and {@code false} to disable. 315 * @param callingPackage The package that changed the data enabled state. 316 */ setDataEnabled(@elephonyManager.DataEnabledReason int reason, boolean enabled, String callingPackage)317 public void setDataEnabled(@TelephonyManager.DataEnabledReason int reason, boolean enabled, 318 String callingPackage) { 319 obtainMessage(EVENT_SET_DATA_ENABLED_FOR_REASON, reason, enabled ? 1 : 0, callingPackage) 320 .sendToTarget(); 321 } 322 323 /** 324 * Check whether the data is enabled for a specific {@link TelephonyManager.DataEnabledReason}. 325 * @return {@code true} if data is enabled for the given reason and {@code false} otherwise. 326 */ isDataEnabledForReason(@elephonyManager.DataEnabledReason int reason)327 public boolean isDataEnabledForReason(@TelephonyManager.DataEnabledReason int reason) { 328 if (reason == TelephonyManager.DATA_ENABLED_REASON_USER) { 329 return isUserDataEnabled(); 330 } else { 331 return mDataEnabledSettings.get(reason); 332 } 333 } 334 updateDataEnabledAndNotify(@elephonyManager.DataEnabledChangedReason int reason)335 private void updateDataEnabledAndNotify(@TelephonyManager.DataEnabledChangedReason int reason) { 336 updateDataEnabledAndNotify(reason, mPhone.getContext().getOpPackageName()); 337 } 338 updateDataEnabledAndNotify(@elephonyManager.DataEnabledChangedReason int reason, @NonNull String callingPackage)339 private void updateDataEnabledAndNotify(@TelephonyManager.DataEnabledChangedReason int reason, 340 @NonNull String callingPackage) { 341 boolean prevDataEnabled = mIsDataEnabled; 342 mIsDataEnabled = isDataEnabled(ApnSetting.TYPE_ALL); 343 log("mIsDataEnabled=" + mIsDataEnabled + ", prevDataEnabled=" + prevDataEnabled); 344 if (!mInitialized || prevDataEnabled != mIsDataEnabled) { 345 if (!mInitialized) mInitialized = true; 346 notifyDataEnabledChanged(mIsDataEnabled, reason, callingPackage); 347 } 348 } 349 350 /** 351 * Check whether the user data is enabled when the device is in the provisioning stage. 352 * In provisioning, we might want to enable mobile data depending on the value of 353 * Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, which is set by setupwizard. 354 * @return {@code true} if user data is enabled when provisioning and {@code false} otherwise. 355 */ isProvisioningDataEnabled()356 private boolean isProvisioningDataEnabled() { 357 final String prov_property = SystemProperties.get("ro.com.android.prov_mobiledata", 358 "false"); 359 boolean retVal = "true".equalsIgnoreCase(prov_property); 360 361 final int prov_mobile_data = Settings.Global.getInt(mResolver, 362 Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, 363 retVal ? 1 : 0); 364 retVal = prov_mobile_data != 0; 365 log("getDataEnabled during provisioning retVal=" + retVal + " - (" + prov_property 366 + ", " + prov_mobile_data + ")"); 367 368 return retVal; 369 } 370 371 /** 372 * Check whether the overall data is enabled for the device. Note that this value will only 373 * be accurate if {@link #isDataInitialized} is {@code true}. 374 * @return {@code true} if the overall data is enabled and {@code false} otherwise. 375 */ isDataEnabled()376 public boolean isDataEnabled() { 377 return mIsDataEnabled; 378 } 379 380 /** 381 * Check whether data enabled value has been initialized. If this is {@code false}, then 382 * {@link #isDataEnabled} is not guaranteed to be accurate. Once data is initialized, 383 * {@link DataSettingsManagerCallback#onDataEnabledChanged} will be invoked with reason 384 * {@link TelephonyManager#DATA_ENABLED_REASON_UNKNOWN}. 385 * @return {@code true} if the data enabled value is initialized and {@code false} otherwise. 386 */ isDataInitialized()387 public boolean isDataInitialized() { 388 // TODO: Create a new DATA_ENABLED_REASON_INITIALIZED for initial value broadcast 389 return mInitialized; 390 } 391 392 /** 393 * Check whether the overall data is enabled for the device for the given APN type. 394 * @param apnType A single APN type to check data enabled for. 395 * @return {@code true} if the overall data is enabled for the APN and {@code false} otherwise. 396 */ isDataEnabled(@pnType int apnType)397 public boolean isDataEnabled(@ApnType int apnType) { 398 if (Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0) { 399 return isProvisioningDataEnabled(); 400 } else { 401 boolean userDataEnabled = isUserDataEnabled(); 402 // Check if we should temporarily enable data in certain conditions. 403 boolean isDataEnabledOverridden = mDataEnabledOverride 404 .shouldOverrideDataEnabledSettings(mPhone, apnType); 405 406 return ((userDataEnabled || isDataEnabledOverridden) 407 && mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_POLICY) 408 && mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_CARRIER) 409 && mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_THERMAL)); 410 } 411 } 412 isStandAloneOpportunistic(int subId, Context context)413 private static boolean isStandAloneOpportunistic(int subId, Context context) { 414 SubscriptionInfo info = SubscriptionController.getInstance().getActiveSubscriptionInfo( 415 subId, context.getOpPackageName(), context.getAttributionTag()); 416 return (info != null) && info.isOpportunistic() && info.getGroupUuid() == null; 417 } 418 419 /** 420 * Enable or disable user data. 421 * @param enabled {@code true} to enable user data and {@code false} to disable. 422 * @param callingPackage The package that changed the data enabled state. 423 */ setUserDataEnabled(boolean enabled, String callingPackage)424 private void setUserDataEnabled(boolean enabled, String callingPackage) { 425 // Can't disable data for stand alone opportunistic subscription. 426 if (isStandAloneOpportunistic(mSubId, mPhone.getContext()) && !enabled) return; 427 boolean changed = GlobalSettingsHelper.setInt(mPhone.getContext(), 428 Settings.Global.MOBILE_DATA, mSubId, (enabled ? 1 : 0)); 429 log("Set user data enabled to " + enabled + ", changed=" + changed + ", callingPackage=" 430 + callingPackage); 431 if (changed) { 432 logl("UserDataEnabled changed to " + enabled); 433 mPhone.notifyUserMobileDataStateChanged(enabled); 434 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_USER, callingPackage); 435 } 436 } 437 438 /** 439 * Check whether user data is enabled for the device. 440 * @return {@code true} if user data is enabled and {@code false} otherwise. 441 */ isUserDataEnabled()442 private boolean isUserDataEnabled() { 443 if (Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0) { 444 return isProvisioningDataEnabled(); 445 } 446 447 // User data should always be true for opportunistic subscription. 448 if (isStandAloneOpportunistic(mSubId, mPhone.getContext())) return true; 449 450 boolean defaultVal = TelephonyProperties.mobile_data().orElse(true); 451 452 return GlobalSettingsHelper.getBoolean(mPhone.getContext(), 453 Settings.Global.MOBILE_DATA, mSubId, defaultVal); 454 } 455 456 /** 457 * Enable or disable policy data. 458 * @param enabled {@code true} to enable policy data and {@code false} to disable. 459 * @param callingPackage The package that changed the data enabled state. 460 */ setPolicyDataEnabled(boolean enabled, String callingPackage)461 private void setPolicyDataEnabled(boolean enabled, String callingPackage) { 462 if (mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_POLICY) != enabled) { 463 logl("PolicyDataEnabled changed to " + enabled + ", callingPackage=" + callingPackage); 464 mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_POLICY, enabled); 465 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_POLICY, callingPackage); 466 } 467 } 468 469 /** 470 * Enable or disable carrier data. 471 * @param enabled {@code true} to enable carrier data and {@code false} to disable. 472 * @param callingPackage The package that changed the data enabled state. 473 */ setCarrierDataEnabled(boolean enabled, String callingPackage)474 private void setCarrierDataEnabled(boolean enabled, String callingPackage) { 475 if (mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_CARRIER) != enabled) { 476 logl("CarrierDataEnabled changed to " + enabled + ", callingPackage=" + callingPackage); 477 mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_CARRIER, enabled); 478 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_CARRIER, 479 callingPackage); 480 } 481 } 482 483 /** 484 * Enable or disable thermal data. 485 * @param enabled {@code true} to enable thermal data and {@code false} to disable. 486 * @param callingPackage The package that changed the data enabled state. 487 */ setThermalDataEnabled(boolean enabled, String callingPackage)488 private void setThermalDataEnabled(boolean enabled, String callingPackage) { 489 if (mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_THERMAL) != enabled) { 490 logl("ThermalDataEnabled changed to " + enabled + ", callingPackage=" + callingPackage); 491 mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_THERMAL, enabled); 492 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_THERMAL, 493 callingPackage); 494 } 495 } 496 497 /** 498 * Enable or disable data roaming from user settings. 499 * @param enabled {@code true} to enable data roaming and {@code false} to disable. 500 */ setDataRoamingEnabled(boolean enabled)501 public void setDataRoamingEnabled(boolean enabled) { 502 obtainMessage(EVENT_SET_DATA_ROAMING_ENABLED, enabled).sendToTarget(); 503 } 504 505 /** 506 * Enable or disable data roaming. 507 * @param enabled {@code true} to enable data roaming and {@code false} to disable. 508 */ setDataRoamingEnabledInternal(boolean enabled)509 private void setDataRoamingEnabledInternal(boolean enabled) { 510 // Will trigger handleDataOnRoamingChange() through observer 511 boolean changed = GlobalSettingsHelper.setBoolean(mPhone.getContext(), 512 Settings.Global.DATA_ROAMING, mSubId, enabled); 513 if (changed) { 514 logl("DataRoamingEnabled changed to " + enabled); 515 mDataSettingsManagerCallbacks.forEach(callback -> callback.invokeFromExecutor( 516 () -> callback.onDataRoamingEnabledChanged(enabled))); 517 } 518 } 519 520 /** 521 * Check whether data roaming is enabled for the device based on the current 522 * {@link Settings.Global#DATA_ROAMING} value. 523 * @return {@code true} if data roaming is enabled and {@code false} otherwise. 524 */ isDataRoamingEnabled()525 public boolean isDataRoamingEnabled() { 526 return GlobalSettingsHelper.getBoolean(mPhone.getContext(), 527 Settings.Global.DATA_ROAMING, mSubId, isDefaultDataRoamingEnabled()); 528 } 529 530 /** 531 * Check whether data roaming is enabled by default. 532 * This is true if {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} 533 * or the system property "ro.com.android.dataroaming" are true. 534 * @return {@code true} if data roaming is enabled by default and {@code false} otherwise. 535 */ isDefaultDataRoamingEnabled()536 public boolean isDefaultDataRoamingEnabled() { 537 return "true".equalsIgnoreCase(SystemProperties.get("ro.com.android.dataroaming", "false")) 538 || mPhone.getDataNetworkController().getDataConfigManager() 539 .isDataRoamingEnabledByDefault(); 540 } 541 542 /** 543 * Set default value for {@link android.provider.Settings.Global#DATA_ROAMING} if the user 544 * has not manually set the value. The default value is {@link #isDefaultDataRoamingEnabled()}. 545 */ setDefaultDataRoamingEnabled()546 public void setDefaultDataRoamingEnabled() { 547 // If the user has not manually set the value, use the default value. 548 if (!isDataRoamingFromUserAction()) { 549 setDataRoamingEnabledInternal(isDefaultDataRoamingEnabled()); 550 } 551 } 552 553 /** 554 * Get whether the user has manually enabled or disabled data roaming from settings for the 555 * current subscription. 556 * @return {@code true} if the user has manually enabled data roaming for the current 557 * subscription and {@code false} if they have not. 558 */ isDataRoamingFromUserAction()559 private boolean isDataRoamingFromUserAction() { 560 String key = Phone.DATA_ROAMING_IS_USER_SETTING_KEY + mPhone.getSubId(); 561 final SharedPreferences sp = 562 PreferenceManager.getDefaultSharedPreferences(mPhone.getContext()); 563 564 // Set the default roaming from user action value if the preference doesn't exist 565 if (!sp.contains(key)) { 566 if (sp.contains(Phone.DATA_ROAMING_IS_USER_SETTING_KEY)) { 567 log("Reusing previous roaming from user action value for backwards compatibility."); 568 sp.edit().putBoolean(key, true).commit(); 569 } else { 570 log("Clearing roaming from user action value for new or upgrading devices."); 571 sp.edit().putBoolean(key, false).commit(); 572 } 573 } 574 575 boolean isUserSetting = sp.getBoolean(key, true); 576 log("isDataRoamingFromUserAction: key=" + key + ", isUserSetting=" + isUserSetting); 577 return isUserSetting; 578 } 579 580 /** 581 * Indicate that the user has manually enabled or disabled the data roaming value from settings. 582 * If the user has not manually set the data roaming value, the default value from 583 * {@link #isDefaultDataRoamingEnabled()} will continue to be used. 584 */ setDataRoamingFromUserAction()585 private void setDataRoamingFromUserAction() { 586 String key = Phone.DATA_ROAMING_IS_USER_SETTING_KEY + mPhone.getSubId(); 587 log("setDataRoamingFromUserAction: key=" + key); 588 final SharedPreferences.Editor sp = 589 PreferenceManager.getDefaultSharedPreferences(mPhone.getContext()).edit(); 590 sp.putBoolean(key, true).commit(); 591 } 592 getDataEnabledOverride()593 private @NonNull DataEnabledOverride getDataEnabledOverride() { 594 return new DataEnabledOverride(SubscriptionController.getInstance() 595 .getDataEnabledOverrideRules(mSubId)); 596 } 597 598 /** 599 * Set whether to always allow the MMS data connection. 600 * @param alwaysAllow {@code true} if MMS data is always allowed and {@code false} otherwise. 601 */ setAlwaysAllowMmsData(boolean alwaysAllow)602 public void setAlwaysAllowMmsData(boolean alwaysAllow) { 603 obtainMessage(EVENT_SET_ALWAYS_ALLOW_MMS_DATA, alwaysAllow).sendToTarget(); 604 } 605 606 /** 607 * Check whether MMS is always allowed. 608 * @return {@code true} if MMS is always allowed and {@code false} otherwise. 609 */ isMmsAlwaysAllowed()610 public boolean isMmsAlwaysAllowed() { 611 return mDataEnabledOverride.isMmsAlwaysAllowed(); 612 } 613 614 /** 615 * Set whether to allow mobile data during voice call. This is used for allowing data on the 616 * non-default data SIM. When a voice call is placed on the non-default data SIM on DSDS 617 * devices, users will not be able to use mobile data. By calling this API, data will be 618 * temporarily enabled on the non-default data SIM during the life cycle of the voice call. 619 * @param allow {@code true} if data is allowed during a voice call and {@code false} otherwise. 620 */ setAllowDataDuringVoiceCall(boolean allow)621 public void setAllowDataDuringVoiceCall(boolean allow) { 622 obtainMessage(EVENT_SET_ALLOW_DATA_DURING_VOICE_CALL, allow).sendToTarget(); 623 } 624 625 /** 626 * Check whether data is allowed during a voice call. 627 * @return {@code true} if data is allowed during voice call and {@code false} otherwise. 628 */ isDataAllowedInVoiceCall()629 public boolean isDataAllowedInVoiceCall() { 630 return mDataEnabledOverride.isDataAllowedInVoiceCall(); 631 } 632 633 /** 634 * Check whether data stall recovery on bad network is enabled. 635 * @return {@code true} if data stall recovery is enabled and {@code false} otherwise. 636 */ isRecoveryOnBadNetworkEnabled()637 public boolean isRecoveryOnBadNetworkEnabled() { 638 return Settings.Global.getInt(mResolver, 639 Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 1) == 1; 640 } 641 notifyDataEnabledChanged(boolean enabled, @TelephonyManager.DataEnabledChangedReason int reason, @NonNull String callingPackage)642 private void notifyDataEnabledChanged(boolean enabled, 643 @TelephonyManager.DataEnabledChangedReason int reason, @NonNull String callingPackage) { 644 logl("notifyDataEnabledChanged: enabled=" + enabled + ", reason=" 645 + dataEnabledChangedReasonToString(reason) + ", callingPackage=" + callingPackage); 646 mDataSettingsManagerCallbacks.forEach(callback -> callback.invokeFromExecutor( 647 () -> callback.onDataEnabledChanged(enabled, reason, callingPackage))); 648 mPhone.notifyDataEnabled(enabled, reason); 649 } 650 notifyDataEnabledOverrideChanged(boolean enabled, @TelephonyManager.MobileDataPolicy int policy)651 private void notifyDataEnabledOverrideChanged(boolean enabled, 652 @TelephonyManager.MobileDataPolicy int policy) { 653 logl("notifyDataEnabledOverrideChanged: enabled=" + enabled); 654 mDataSettingsManagerCallbacks.forEach(callback -> callback.invokeFromExecutor( 655 () -> callback.onDataEnabledOverrideChanged(enabled, policy))); 656 } 657 658 /** 659 * Register the callback for receiving information from {@link DataSettingsManager}. 660 * 661 * @param callback The callback. 662 */ registerCallback(@onNull DataSettingsManagerCallback callback)663 public void registerCallback(@NonNull DataSettingsManagerCallback callback) { 664 mDataSettingsManagerCallbacks.add(callback); 665 } 666 667 /** 668 * Unregister the callback for receiving information from {@link DataSettingsManager}. 669 * 670 * @param callback The callback. 671 */ unregisterCallback(@onNull DataSettingsManagerCallback callback)672 public void unregisterCallback(@NonNull DataSettingsManagerCallback callback) { 673 mDataSettingsManagerCallbacks.remove(callback); 674 } 675 dataEnabledChangedReasonToString( @elephonyManager.DataEnabledChangedReason int reason)676 private static String dataEnabledChangedReasonToString( 677 @TelephonyManager.DataEnabledChangedReason int reason) { 678 switch (reason) { 679 case TelephonyManager.DATA_ENABLED_REASON_USER: 680 return "USER"; 681 case TelephonyManager.DATA_ENABLED_REASON_POLICY: 682 return "POLICY"; 683 case TelephonyManager.DATA_ENABLED_REASON_CARRIER: 684 return "CARRIER"; 685 case TelephonyManager.DATA_ENABLED_REASON_THERMAL: 686 return "THERMAL"; 687 case TelephonyManager.DATA_ENABLED_REASON_OVERRIDE: 688 return "OVERRIDE"; 689 default: 690 return "UNKNOWN"; 691 } 692 } 693 694 @Override toString()695 public String toString() { 696 return "[isUserDataEnabled=" + isUserDataEnabled() 697 + ", isProvisioningDataEnabled=" + isProvisioningDataEnabled() 698 + ", mIsDataEnabled=" + mIsDataEnabled 699 + ", mDataEnabledSettings=" + mDataEnabledSettings 700 + ", mDataEnabledOverride=" + mDataEnabledOverride 701 + "]"; 702 } 703 704 /** 705 * Log debug messages. 706 * @param s debug messages 707 */ log(@onNull String s)708 private void log(@NonNull String s) { 709 Rlog.d(mLogTag, s); 710 } 711 712 /** 713 * Log error messages. 714 * @param s error messages 715 */ loge(@onNull String s)716 private void loge(@NonNull String s) { 717 Rlog.e(mLogTag, s); 718 } 719 720 /** 721 * Log debug messages and also log into the local log. 722 * @param s debug messages 723 */ logl(@onNull String s)724 private void logl(@NonNull String s) { 725 log(s); 726 mLocalLog.log(s); 727 } 728 729 /** 730 * Dump the state of DataSettingsManager 731 * 732 * @param fd File descriptor 733 * @param printWriter Print writer 734 * @param args Arguments 735 */ dump(FileDescriptor fd, PrintWriter printWriter, String[] args)736 public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { 737 IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); 738 pw.println(DataSettingsManager.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":"); 739 pw.increaseIndent(); 740 pw.println("mIsDataEnabled=" + mIsDataEnabled); 741 pw.println("isDataEnabled(internet)=" + isDataEnabled(ApnSetting.TYPE_DEFAULT)); 742 pw.println("isDataEnabled(mms)=" + isDataEnabled(ApnSetting.TYPE_MMS)); 743 pw.println("isUserDataEnabled=" + isUserDataEnabled()); 744 pw.println("isDataRoamingEnabled=" + isDataRoamingEnabled()); 745 pw.println("isDefaultDataRoamingEnabled=" + isDefaultDataRoamingEnabled()); 746 pw.println("isDataRoamingFromUserAction=" + isDataRoamingFromUserAction()); 747 pw.println("device_provisioned=" + Settings.Global.getInt( 748 mResolver, Settings.Global.DEVICE_PROVISIONED, 0)); 749 pw.println("isProvisioningDataEnabled=" + isProvisioningDataEnabled()); 750 pw.println("data_stall_recovery_on_bad_network=" + Settings.Global.getInt( 751 mResolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 1)); 752 pw.println("mDataEnabledSettings=" + mDataEnabledSettings.entrySet().stream() 753 .map(entry -> 754 dataEnabledChangedReasonToString(entry.getKey()) + "=" + entry.getValue()) 755 .collect(Collectors.joining(", "))); 756 pw.println("mDataEnabledOverride=" + mDataEnabledOverride); 757 pw.println("Local logs:"); 758 pw.increaseIndent(); 759 mLocalLog.dump(fd, pw, args); 760 pw.decreaseIndent(); 761 pw.decreaseIndent(); 762 } 763 } 764