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