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 mSubId = (int) msg.obj; 220 refreshEnabledMobileDataPolicy(); 221 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_USER, 222 mPhone.getContext().getOpPackageName(), 223 SubscriptionManager.isValidSubscriptionId(mSubId)); 224 mPhone.notifyUserMobileDataStateChanged(isUserDataEnabled()); 225 break; 226 } 227 case EVENT_SET_DATA_ENABLED_FOR_REASON: { 228 String callingPackage = (String) msg.obj; 229 boolean enabled = msg.arg2 == 1; 230 switch (msg.arg1) { 231 case TelephonyManager.DATA_ENABLED_REASON_USER: 232 setUserDataEnabled(enabled, callingPackage); 233 break; 234 case TelephonyManager.DATA_ENABLED_REASON_CARRIER: 235 setCarrierDataEnabled(enabled, callingPackage); 236 break; 237 case TelephonyManager.DATA_ENABLED_REASON_POLICY: 238 setPolicyDataEnabled(enabled, callingPackage); 239 break; 240 case TelephonyManager.DATA_ENABLED_REASON_THERMAL: 241 setThermalDataEnabled(enabled, callingPackage); 242 break; 243 default: 244 log("Cannot set data enabled for reason: " 245 + dataEnabledChangedReasonToString(msg.arg1)); 246 break; 247 } 248 break; 249 } 250 case EVENT_SET_DATA_ROAMING_ENABLED: { 251 boolean enabled = (boolean) msg.obj; 252 setDataRoamingEnabledInternal(enabled); 253 setDataRoamingFromUserAction(); 254 break; 255 } 256 case EVENT_SET_MOBILE_DATA_POLICY: { 257 int mobileDataPolicy = msg.arg1; 258 boolean enable = msg.arg2 == 1; 259 onSetMobileDataPolicy(mobileDataPolicy, enable); 260 break; 261 } 262 case EVENT_PROVISIONED_CHANGED: 263 case EVENT_PROVISIONING_DATA_ENABLED_CHANGED: { 264 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_UNKNOWN); 265 break; 266 } 267 case EVENT_INITIALIZE: { 268 onInitialize(); 269 break; 270 } 271 default: 272 loge("Unknown msg.what: " + msg.what); 273 } 274 } 275 hasCalling()276 private boolean hasCalling() { 277 if (!TelephonyCapabilities.minimalTelephonyCdmCheck(mFeatureFlags)) return true; 278 return mPhone.getContext().getPackageManager().hasSystemFeature( 279 PackageManager.FEATURE_TELEPHONY_CALLING); 280 } 281 282 /** 283 * Called when needed to register for all events that data network controller is interested. 284 */ onInitialize()285 private void onInitialize() { 286 mDataConfigManager.registerCallback(new DataConfigManagerCallback(this::post) { 287 @Override 288 public void onCarrierConfigChanged() { 289 if (mDataConfigManager.isConfigCarrierSpecific()) { 290 setDefaultDataRoamingEnabled(); 291 } 292 } 293 }); 294 mSettingsObserver.observe(Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), 295 EVENT_PROVISIONED_CHANGED); 296 mSettingsObserver.observe( 297 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED), 298 EVENT_PROVISIONING_DATA_ENABLED_CHANGED); 299 if (hasCalling()) { 300 mPhone.getCallTracker().registerForVoiceCallStarted(this, EVENT_CALL_STATE_CHANGED, 301 null); 302 mPhone.getCallTracker().registerForVoiceCallEnded(this, EVENT_CALL_STATE_CHANGED, null); 303 } 304 if (hasCalling() && mPhone.getImsPhone() != null) { 305 mPhone.getImsPhone().getCallTracker().registerForVoiceCallStarted( 306 this, EVENT_CALL_STATE_CHANGED, null); 307 mPhone.getImsPhone().getCallTracker().registerForVoiceCallEnded( 308 this, EVENT_CALL_STATE_CHANGED, null); 309 } 310 mPhone.getContext().getSystemService(TelephonyRegistryManager.class) 311 .addOnSubscriptionsChangedListener(new OnSubscriptionsChangedListener() { 312 @Override 313 public void onSubscriptionsChanged() { 314 if (mSubId != mPhone.getSubId()) { 315 log("onSubscriptionsChanged: " + mSubId + " to " + mPhone.getSubId()); 316 obtainMessage(EVENT_SUBSCRIPTIONS_CHANGED, mPhone.getSubId()) 317 .sendToTarget(); 318 } 319 } 320 }, this::post); 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 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_UNKNOWN); 339 } 340 341 /** 342 * Enable or disable data for a specific {@link TelephonyManager.DataEnabledReason}. 343 * @param reason The reason the data enabled change is taking place. 344 * @param enabled {@code true} to enable data for the given reason and {@code false} to disable. 345 * @param callingPackage The package that changed the data enabled state. 346 */ setDataEnabled(@elephonyManager.DataEnabledReason int reason, boolean enabled, String callingPackage)347 public void setDataEnabled(@TelephonyManager.DataEnabledReason int reason, boolean enabled, 348 String callingPackage) { 349 obtainMessage(EVENT_SET_DATA_ENABLED_FOR_REASON, reason, enabled ? 1 : 0, callingPackage) 350 .sendToTarget(); 351 } 352 353 /** 354 * Check whether the data is enabled for a specific {@link TelephonyManager.DataEnabledReason}. 355 * @return {@code true} if data is enabled for the given reason and {@code false} otherwise. 356 */ isDataEnabledForReason(@elephonyManager.DataEnabledReason int reason)357 public boolean isDataEnabledForReason(@TelephonyManager.DataEnabledReason int reason) { 358 if (reason == TelephonyManager.DATA_ENABLED_REASON_USER) { 359 return isUserDataEnabled(); 360 } else { 361 return mDataEnabledSettings.get(reason); 362 } 363 } 364 updateDataEnabledAndNotify(@elephonyManager.DataEnabledChangedReason int reason)365 private void updateDataEnabledAndNotify(@TelephonyManager.DataEnabledChangedReason int reason) { 366 updateDataEnabledAndNotify(reason, mPhone.getContext().getOpPackageName(), false); 367 } 368 updateDataEnabledAndNotify(@elephonyManager.DataEnabledChangedReason int reason, @NonNull String callingPackage, boolean shouldNotify)369 private void updateDataEnabledAndNotify(@TelephonyManager.DataEnabledChangedReason int reason, 370 @NonNull String callingPackage, boolean shouldNotify) { 371 boolean prevDataEnabled = mIsDataEnabled; 372 mIsDataEnabled = isDataEnabled(ApnSetting.TYPE_ALL); 373 log("mIsDataEnabled=" + mIsDataEnabled + ", prevDataEnabled=" + prevDataEnabled); 374 if (!mInitialized || shouldNotify || prevDataEnabled != mIsDataEnabled) { 375 if (!mInitialized) mInitialized = true; 376 notifyDataEnabledChanged(mIsDataEnabled, reason, callingPackage); 377 } 378 } 379 380 /** 381 * Check whether the user data is enabled when the device is in the provisioning stage. 382 * In provisioning, we might want to enable mobile data depending on the value of 383 * Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, which is set by setupwizard. 384 * @return {@code true} if user data is enabled when provisioning and {@code false} otherwise. 385 */ isProvisioningDataEnabled()386 private boolean isProvisioningDataEnabled() { 387 final String prov_property = SystemProperties.get("ro.com.android.prov_mobiledata", 388 "false"); 389 boolean retVal = "true".equalsIgnoreCase(prov_property); 390 391 final int prov_mobile_data = Settings.Global.getInt(mResolver, 392 Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, 393 retVal ? 1 : 0); 394 retVal = prov_mobile_data != 0; 395 log("getDataEnabled during provisioning retVal=" + retVal + " - (" + prov_property 396 + ", " + prov_mobile_data + ")"); 397 398 return retVal; 399 } 400 401 /** 402 * Check whether the overall data is enabled for the device. Note that this value will only 403 * be accurate if {@link #isDataInitialized} is {@code true}. 404 * @return {@code true} if the overall data is enabled and {@code false} otherwise. 405 */ isDataEnabled()406 public boolean isDataEnabled() { 407 return mIsDataEnabled; 408 } 409 410 /** 411 * Check whether data enabled value has been initialized. If this is {@code false}, then 412 * {@link #isDataEnabled} is not guaranteed to be accurate. Once data is initialized, 413 * {@link DataSettingsManagerCallback#onDataEnabledChanged} will be invoked with reason 414 * {@link TelephonyManager#DATA_ENABLED_REASON_UNKNOWN}. 415 * @return {@code true} if the data enabled value is initialized and {@code false} otherwise. 416 */ isDataInitialized()417 public boolean isDataInitialized() { 418 // TODO: Create a new DATA_ENABLED_REASON_INITIALIZED for initial value broadcast 419 return mInitialized; 420 } 421 422 /** 423 * Check whether the overall data is enabled for the device for the given APN type. 424 * @param apnType A single APN type to check data enabled for. 425 * @return {@code true} if the overall data is enabled for the APN and {@code false} otherwise. 426 */ isDataEnabled(@pnType int apnType)427 public boolean isDataEnabled(@ApnType int apnType) { 428 if (Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0) { 429 return isProvisioningDataEnabled(); 430 } else { 431 boolean userDataEnabled = isUserDataEnabled(); 432 // Check if we should temporarily enable data based on mobile data policy. 433 boolean isDataEnabledOverridden = isDataEnabledOverriddenForApn(apnType); 434 435 436 return ((userDataEnabled || isDataEnabledOverridden) 437 && mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_POLICY) 438 && mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_CARRIER) 439 && mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_THERMAL)); 440 } 441 } 442 isStandAloneOpportunistic(int subId)443 private boolean isStandAloneOpportunistic(int subId) { 444 SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance() 445 .getSubscriptionInfoInternal(subId); 446 return subInfo != null && subInfo.isOpportunistic() 447 && TextUtils.isEmpty(subInfo.getGroupUuid()); 448 } 449 450 /** 451 * Enable or disable user data. 452 * @param enabled {@code true} to enable user data and {@code false} to disable. 453 * @param callingPackage The package that changed the data enabled state. 454 */ setUserDataEnabled(boolean enabled, String callingPackage)455 private void setUserDataEnabled(boolean enabled, String callingPackage) { 456 // Can't disable data for stand alone opportunistic subscription. 457 if (isStandAloneOpportunistic(mSubId) && !enabled) return; 458 boolean changed = GlobalSettingsHelper.setInt(mPhone.getContext(), 459 Settings.Global.MOBILE_DATA, mSubId, (enabled ? 1 : 0)); 460 log("Set user data enabled to " + enabled + ", changed=" + changed + ", callingPackage=" 461 + callingPackage); 462 if (changed) { 463 logl("UserDataEnabled changed to " + enabled); 464 mPhone.notifyUserMobileDataStateChanged(enabled); 465 mDataSettingsManagerCallbacks.forEach(callback -> callback.invokeFromExecutor( 466 () -> callback.onUserDataEnabledChanged(enabled, callingPackage))); 467 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_USER, 468 callingPackage, false); 469 } 470 } 471 472 /** 473 * Check whether user data is enabled for the device. 474 * @return {@code true} if user data is enabled and {@code false} otherwise. 475 */ isUserDataEnabled()476 private boolean isUserDataEnabled() { 477 if (Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0) { 478 return isProvisioningDataEnabled(); 479 } 480 481 // User data should always be true for opportunistic subscription. 482 if (isStandAloneOpportunistic(mSubId)) return true; 483 484 boolean defaultVal = TelephonyProperties.mobile_data().orElse(true); 485 486 return GlobalSettingsHelper.getBoolean(mPhone.getContext(), 487 Settings.Global.MOBILE_DATA, mSubId, defaultVal); 488 } 489 490 /** 491 * Enable or disable policy data. 492 * @param enabled {@code true} to enable policy data and {@code false} to disable. 493 * @param callingPackage The package that changed the data enabled state. 494 */ setPolicyDataEnabled(boolean enabled, String callingPackage)495 private void setPolicyDataEnabled(boolean enabled, String callingPackage) { 496 if (mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_POLICY) != enabled) { 497 logl("PolicyDataEnabled changed to " + enabled + ", callingPackage=" + callingPackage); 498 mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_POLICY, enabled); 499 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_POLICY, 500 callingPackage, false); 501 } 502 } 503 504 /** 505 * Enable or disable carrier data. 506 * @param enabled {@code true} to enable carrier data and {@code false} to disable. 507 * @param callingPackage The package that changed the data enabled state. 508 */ setCarrierDataEnabled(boolean enabled, String callingPackage)509 private void setCarrierDataEnabled(boolean enabled, String callingPackage) { 510 if (mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_CARRIER) != enabled) { 511 logl("CarrierDataEnabled changed to " + enabled + ", callingPackage=" + callingPackage); 512 mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_CARRIER, enabled); 513 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_CARRIER, 514 callingPackage, false); 515 } 516 } 517 518 /** 519 * Enable or disable thermal data. 520 * @param enabled {@code true} to enable thermal data and {@code false} to disable. 521 * @param callingPackage The package that changed the data enabled state. 522 */ setThermalDataEnabled(boolean enabled, String callingPackage)523 private void setThermalDataEnabled(boolean enabled, String callingPackage) { 524 if (mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_THERMAL) != enabled) { 525 logl("ThermalDataEnabled changed to " + enabled + ", callingPackage=" + callingPackage); 526 mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_THERMAL, enabled); 527 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_THERMAL, 528 callingPackage, false); 529 } 530 } 531 532 /** 533 * Enable or disable data roaming from user settings. 534 * @param enabled {@code true} to enable data roaming and {@code false} to disable. 535 */ setDataRoamingEnabled(boolean enabled)536 public void setDataRoamingEnabled(boolean enabled) { 537 obtainMessage(EVENT_SET_DATA_ROAMING_ENABLED, enabled).sendToTarget(); 538 } 539 540 /** 541 * Enable or disable data roaming. 542 * @param enabled {@code true} to enable data roaming and {@code false} to disable. 543 */ setDataRoamingEnabledInternal(boolean enabled)544 private void setDataRoamingEnabledInternal(boolean enabled) { 545 // Will trigger handleDataOnRoamingChange() through observer 546 boolean changed = GlobalSettingsHelper.setBoolean(mPhone.getContext(), 547 Settings.Global.DATA_ROAMING, mSubId, enabled); 548 if (changed) { 549 logl("DataRoamingEnabled changed to " + enabled); 550 mDataSettingsManagerCallbacks.forEach(callback -> callback.invokeFromExecutor( 551 () -> callback.onDataRoamingEnabledChanged(enabled))); 552 } 553 } 554 555 /** 556 * Check whether data roaming is enabled for the device based on the current 557 * {@link Settings.Global#DATA_ROAMING} value. 558 * @return {@code true} if data roaming is enabled and {@code false} otherwise. 559 */ isDataRoamingEnabled()560 public boolean isDataRoamingEnabled() { 561 return GlobalSettingsHelper.getBoolean(mPhone.getContext(), 562 Settings.Global.DATA_ROAMING, mSubId, isDefaultDataRoamingEnabled()); 563 } 564 565 /** 566 * Check whether data roaming is enabled by default. 567 * This is true if {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} 568 * or the system property "ro.com.android.dataroaming" are true. 569 * @return {@code true} if data roaming is enabled by default and {@code false} otherwise. 570 */ isDefaultDataRoamingEnabled()571 public boolean isDefaultDataRoamingEnabled() { 572 return "true".equalsIgnoreCase(SystemProperties.get("ro.com.android.dataroaming", "false")) 573 || mPhone.getDataNetworkController().getDataConfigManager() 574 .isDataRoamingEnabledByDefault(); 575 } 576 577 /** 578 * Set default value for {@link android.provider.Settings.Global#DATA_ROAMING} if the user 579 * has not manually set the value. The default value is {@link #isDefaultDataRoamingEnabled()}. 580 */ setDefaultDataRoamingEnabled()581 public void setDefaultDataRoamingEnabled() { 582 // If the user has not manually set the value, use the default value. 583 if (!isDataRoamingFromUserAction()) { 584 setDataRoamingEnabledInternal(isDefaultDataRoamingEnabled()); 585 } 586 } 587 588 /** 589 * Get whether the user has manually enabled or disabled data roaming from settings for the 590 * current subscription. 591 * @return {@code true} if the user has manually enabled data roaming for the current 592 * subscription and {@code false} if they have not. 593 */ isDataRoamingFromUserAction()594 private boolean isDataRoamingFromUserAction() { 595 String key = Phone.DATA_ROAMING_IS_USER_SETTING_KEY + mPhone.getSubId(); 596 final SharedPreferences sp = 597 PreferenceManager.getDefaultSharedPreferences(mPhone.getContext()); 598 599 // Set the default roaming from user action value if the preference doesn't exist 600 if (!sp.contains(key)) { 601 if (sp.contains(Phone.DATA_ROAMING_IS_USER_SETTING_KEY)) { 602 log("Reusing previous roaming from user action value for backwards compatibility."); 603 sp.edit().putBoolean(key, true).commit(); 604 } else { 605 log("Clearing roaming from user action value for new or upgrading devices."); 606 sp.edit().putBoolean(key, false).commit(); 607 } 608 } 609 610 boolean isUserSetting = sp.getBoolean(key, true); 611 log("isDataRoamingFromUserAction: key=" + key + ", isUserSetting=" + isUserSetting); 612 return isUserSetting; 613 } 614 615 /** 616 * Indicate that the user has manually enabled or disabled the data roaming value from settings. 617 * If the user has not manually set the data roaming value, the default value from 618 * {@link #isDefaultDataRoamingEnabled()} will continue to be used. 619 */ setDataRoamingFromUserAction()620 private void setDataRoamingFromUserAction() { 621 String key = Phone.DATA_ROAMING_IS_USER_SETTING_KEY + mPhone.getSubId(); 622 log("setDataRoamingFromUserAction: key=" + key); 623 final SharedPreferences.Editor sp = 624 PreferenceManager.getDefaultSharedPreferences(mPhone.getContext()).edit(); 625 sp.putBoolean(key, true).commit(); 626 } 627 628 /** Refresh the enabled mobile data policies from Telephony database */ refreshEnabledMobileDataPolicy()629 private void refreshEnabledMobileDataPolicy() { 630 SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance() 631 .getSubscriptionInfoInternal(mSubId); 632 if (subInfo != null) { 633 mEnabledMobileDataPolicy = getMobileDataPolicyEnabled( 634 subInfo.getEnabledMobileDataPolicies()); 635 } 636 } 637 638 /** 639 * @return {@code true} If the mobile data policy is enabled 640 */ isMobileDataPolicyEnabled(@obileDataPolicy int mobileDataPolicy)641 public boolean isMobileDataPolicyEnabled(@MobileDataPolicy int mobileDataPolicy) { 642 return mEnabledMobileDataPolicy.contains(mobileDataPolicy); 643 } 644 645 /** 646 * Set mobile data policy enabled status 647 * @param mobileDataPolicy The mobile data policy to set 648 * @param enable {@code true} to enable the policy; {@code false} to disable. 649 */ setMobileDataPolicy(@obileDataPolicy int mobileDataPolicy, boolean enable)650 public void setMobileDataPolicy(@MobileDataPolicy int mobileDataPolicy, boolean enable) { 651 obtainMessage(EVENT_SET_MOBILE_DATA_POLICY, mobileDataPolicy, enable ? 1 : 0) 652 .sendToTarget(); 653 } 654 655 /** 656 * Store data mobile policy to Telephony database. 657 * 658 * @param mobileDataPolicy The mobile data policy that overrides user data enabled setting. 659 * @param enable {@code true} to enable the policy; {@code false} to remove the policy. 660 */ onSetMobileDataPolicy(@obileDataPolicy int mobileDataPolicy, boolean enable)661 private void onSetMobileDataPolicy(@MobileDataPolicy int mobileDataPolicy, boolean enable) { 662 if (enable == isMobileDataPolicyEnabled(mobileDataPolicy)) { 663 return; 664 } 665 metricsRecordSetMobileDataPolicy(mobileDataPolicy); 666 667 if (enable) { 668 mEnabledMobileDataPolicy.add(mobileDataPolicy); 669 } else { 670 mEnabledMobileDataPolicy.remove(mobileDataPolicy); 671 } 672 673 String enabledMobileDataPolicies = mEnabledMobileDataPolicy.stream().map(String::valueOf) 674 .collect(Collectors.joining(",")); 675 SubscriptionManagerService.getInstance().setEnabledMobileDataPolicies(mSubId, 676 enabledMobileDataPolicies); 677 logl(TelephonyUtils.mobileDataPolicyToString(mobileDataPolicy) + " changed to " 678 + enable); 679 updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_OVERRIDE); 680 notifyDataEnabledOverrideChanged(enable, mobileDataPolicy); 681 } 682 683 /** 684 * Record the number of times a mobile data policy is toggled to metrics. 685 * @param mobileDataPolicy The mobile data policy that's toggled 686 */ metricsRecordSetMobileDataPolicy(@obileDataPolicy int mobileDataPolicy)687 private void metricsRecordSetMobileDataPolicy(@MobileDataPolicy int mobileDataPolicy) { 688 if (mobileDataPolicy == TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH) { 689 DeviceTelephonyPropertiesStats.recordAutoDataSwitchFeatureToggle(); 690 } 691 } 692 693 /** 694 * Check whether data stall recovery on bad network is enabled. 695 * @return {@code true} if data stall recovery is enabled and {@code false} otherwise. 696 */ isRecoveryOnBadNetworkEnabled()697 public boolean isRecoveryOnBadNetworkEnabled() { 698 return Settings.Global.getInt(mResolver, 699 Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 1) == 1; 700 } 701 notifyDataEnabledChanged(boolean enabled, @TelephonyManager.DataEnabledChangedReason int reason, @NonNull String callingPackage)702 private void notifyDataEnabledChanged(boolean enabled, 703 @TelephonyManager.DataEnabledChangedReason int reason, @NonNull String callingPackage) { 704 logl("notifyDataEnabledChanged: enabled=" + enabled + ", reason=" 705 + dataEnabledChangedReasonToString(reason) + ", callingPackage=" + callingPackage); 706 mDataSettingsManagerCallbacks.forEach(callback -> callback.invokeFromExecutor( 707 () -> callback.onDataEnabledChanged(enabled, reason, callingPackage))); 708 mPhone.notifyDataEnabled(enabled, reason); 709 } 710 notifyDataEnabledOverrideChanged(boolean enabled, @TelephonyManager.MobileDataPolicy int policy)711 private void notifyDataEnabledOverrideChanged(boolean enabled, 712 @TelephonyManager.MobileDataPolicy int policy) { 713 logl("notifyDataEnabledOverrideChanged: enabled=" + enabled); 714 mDataSettingsManagerCallbacks.forEach(callback -> callback.invokeFromExecutor( 715 () -> callback.onDataEnabledOverrideChanged(enabled, policy))); 716 } 717 718 /** 719 * Return the parsed mobile data policies. 720 * 721 * @param policies New mobile data policies in String format. 722 * @return A Set of parsed mobile data policies. 723 */ 724 @NonNull 725 @MobileDataPolicy getMobileDataPolicyEnabled(@onNull String policies)726 public Set<Integer> getMobileDataPolicyEnabled(@NonNull String policies) { 727 Set<Integer> mobileDataPolicies = new HashSet<>(); 728 String[] rulesString = policies.trim().split("\\s*,\\s*"); 729 for (String rule : rulesString) { 730 if (!TextUtils.isEmpty(rule)) { 731 int parsedDataPolicy = parsePolicyFrom(rule); 732 if (parsedDataPolicy != INVALID_MOBILE_DATA_POLICY) { 733 mobileDataPolicies.add(parsedDataPolicy); 734 } 735 } 736 } 737 return mobileDataPolicies; 738 } 739 740 /** 741 * Parse a mobile data policy retrieved from Telephony db. 742 * If the policy is in legacy format, convert it into the corresponding mobile data policy. 743 * 744 * @param policy Mobile data policy to be parsed from. 745 * @return Parsed mobile data policy. {@link #INVALID_MOBILE_DATA_POLICY} if string can't be 746 * parsed into a mobile data policy. 747 */ 748 @MobileDataPolicy parsePolicyFrom(@onNull String policy)749 private int parsePolicyFrom(@NonNull String policy) { 750 int dataPolicy; 751 try { 752 // parse as new override policy 753 dataPolicy = Integer.parseInt(policy); 754 } catch (NumberFormatException e) { 755 dataPolicy = INVALID_MOBILE_DATA_POLICY; 756 loge("parsePolicyFrom: invalid mobile data policy format: " + policy); 757 } 758 return dataPolicy; 759 } 760 761 /** 762 * Check if data enabled is temporarily overridden in certain conditions. 763 * 764 * @param apnType The APN type to check. 765 * @return {@code true} if data enabled should be overridden. 766 */ isDataEnabledOverriddenForApn(@pnType int apnType)767 private boolean isDataEnabledOverriddenForApn(@ApnType int apnType) { 768 boolean overridden = false; 769 770 // mobile data policy : MMS always allowed 771 if (isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED)) { 772 overridden = apnType == ApnSetting.TYPE_MMS; 773 } 774 775 boolean isNonDds = mPhone.getSubId() != SubscriptionManagerService.getInstance() 776 .getDefaultDataSubId(); 777 778 Phone defaultDataPhone = PhoneFactory.getPhone(SubscriptionManagerService.getInstance() 779 .getPhoneId(SubscriptionManagerService.getInstance() 780 .getDefaultDataSubId())); 781 boolean isDdsUserEnabled = defaultDataPhone != null && defaultDataPhone.isUserDataEnabled(); 782 783 // mobile data policy : data during call 784 if (isMobileDataPolicyEnabled(TelephonyManager 785 .MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL)) { 786 overridden |= isNonDds && isDdsUserEnabled 787 && mPhone.getState() != PhoneConstants.State.IDLE; 788 } 789 790 // mobile data policy : auto data switch 791 if (isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH)) { 792 // check user enabled data on the default data phone 793 overridden |= isNonDds && isDdsUserEnabled; 794 } 795 return overridden; 796 } 797 798 /** 799 * Register the callback for receiving information from {@link DataSettingsManager}. 800 * 801 * @param callback The callback. 802 */ registerCallback(@onNull DataSettingsManagerCallback callback)803 public void registerCallback(@NonNull DataSettingsManagerCallback callback) { 804 mDataSettingsManagerCallbacks.add(callback); 805 } 806 807 /** 808 * Unregister the callback for receiving information from {@link DataSettingsManager}. 809 * 810 * @param callback The callback. 811 */ unregisterCallback(@onNull DataSettingsManagerCallback callback)812 public void unregisterCallback(@NonNull DataSettingsManagerCallback callback) { 813 mDataSettingsManagerCallbacks.remove(callback); 814 } 815 dataEnabledChangedReasonToString( @elephonyManager.DataEnabledChangedReason int reason)816 private static String dataEnabledChangedReasonToString( 817 @TelephonyManager.DataEnabledChangedReason int reason) { 818 return switch (reason) { 819 case TelephonyManager.DATA_ENABLED_REASON_USER -> "USER"; 820 case TelephonyManager.DATA_ENABLED_REASON_POLICY -> "POLICY"; 821 case TelephonyManager.DATA_ENABLED_REASON_CARRIER -> "CARRIER"; 822 case TelephonyManager.DATA_ENABLED_REASON_THERMAL -> "THERMAL"; 823 case TelephonyManager.DATA_ENABLED_REASON_OVERRIDE -> "OVERRIDE"; 824 default -> "UNKNOWN"; 825 }; 826 } 827 828 @Override toString()829 public String toString() { 830 return "[isUserDataEnabled=" + isUserDataEnabled() 831 + ", isProvisioningDataEnabled=" + isProvisioningDataEnabled() 832 + ", mIsDataEnabled=" + mIsDataEnabled 833 + ", mDataEnabledSettings=" + mDataEnabledSettings 834 + ", mEnabledMobileDataPolicy=" + mEnabledMobileDataPolicy.stream() 835 .map(TelephonyUtils::mobileDataPolicyToString).collect(Collectors.joining(",")) 836 + "]"; 837 } 838 839 /** 840 * Log debug messages. 841 * @param s debug messages 842 */ log(@onNull String s)843 private void log(@NonNull String s) { 844 Rlog.d(mLogTag, s); 845 } 846 847 /** 848 * Log error messages. 849 * @param s error messages 850 */ loge(@onNull String s)851 private void loge(@NonNull String s) { 852 Rlog.e(mLogTag, s); 853 } 854 855 /** 856 * Log debug messages and also log into the local log. 857 * @param s debug messages 858 */ logl(@onNull String s)859 private void logl(@NonNull String s) { 860 log(s); 861 mLocalLog.log(s); 862 } 863 864 /** 865 * Dump the state of DataSettingsManager 866 * 867 * @param fd File descriptor 868 * @param printWriter Print writer 869 * @param args Arguments 870 */ dump(FileDescriptor fd, PrintWriter printWriter, String[] args)871 public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { 872 IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); 873 pw.println(DataSettingsManager.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":"); 874 pw.increaseIndent(); 875 pw.println("mIsDataEnabled=" + mIsDataEnabled); 876 pw.println("isDataEnabled(internet)=" + isDataEnabled(ApnSetting.TYPE_DEFAULT)); 877 pw.println("isDataEnabled(mms)=" + isDataEnabled(ApnSetting.TYPE_MMS)); 878 pw.println("isUserDataEnabled=" + isUserDataEnabled()); 879 pw.println("isDataRoamingEnabled=" + isDataRoamingEnabled()); 880 pw.println("isDefaultDataRoamingEnabled=" + isDefaultDataRoamingEnabled()); 881 pw.println("isDataRoamingFromUserAction=" + isDataRoamingFromUserAction()); 882 pw.println("device_provisioned=" + Settings.Global.getInt( 883 mResolver, Settings.Global.DEVICE_PROVISIONED, 0)); 884 pw.println("isProvisioningDataEnabled=" + isProvisioningDataEnabled()); 885 pw.println("data_stall_recovery_on_bad_network=" + Settings.Global.getInt( 886 mResolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 1)); 887 pw.println("mDataEnabledSettings=" + mDataEnabledSettings.entrySet().stream() 888 .map(entry -> 889 dataEnabledChangedReasonToString(entry.getKey()) + "=" + entry.getValue()) 890 .collect(Collectors.joining(", "))); 891 pw.println("mEnabledMobileDataPolicy=" + mEnabledMobileDataPolicy.stream() 892 .map(TelephonyUtils::mobileDataPolicyToString).collect(Collectors.joining(","))); 893 pw.println("Local logs:"); 894 pw.increaseIndent(); 895 mLocalLog.dump(fd, pw, args); 896 pw.decreaseIndent(); 897 pw.decreaseIndent(); 898 } 899 } 900