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