1 /* 2 * Copyright 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.telephony.dataconnection; 18 19 import static android.text.format.DateUtils.MINUTE_IN_MILLIS; 20 import static android.text.format.DateUtils.SECOND_IN_MILLIS; 21 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.app.AppOpsManager; 25 import android.content.BroadcastReceiver; 26 import android.content.ComponentName; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.IntentFilter; 30 import android.content.ServiceConnection; 31 import android.content.pm.PackageManager; 32 import android.content.pm.ResolveInfo; 33 import android.net.LinkProperties; 34 import android.os.AsyncResult; 35 import android.os.Handler; 36 import android.os.IBinder; 37 import android.os.Message; 38 import android.os.PersistableBundle; 39 import android.os.RegistrantList; 40 import android.os.RemoteException; 41 import android.os.UserHandle; 42 import android.permission.LegacyPermissionManager; 43 import android.telephony.AccessNetworkConstants; 44 import android.telephony.AccessNetworkConstants.TransportType; 45 import android.telephony.AnomalyReporter; 46 import android.telephony.CarrierConfigManager; 47 import android.telephony.SubscriptionManager; 48 import android.telephony.data.DataCallResponse; 49 import android.telephony.data.DataProfile; 50 import android.telephony.data.DataService; 51 import android.telephony.data.DataServiceCallback; 52 import android.telephony.data.IDataService; 53 import android.telephony.data.IDataServiceCallback; 54 import android.telephony.data.NetworkSliceInfo; 55 import android.telephony.data.TrafficDescriptor; 56 import android.text.TextUtils; 57 58 import com.android.internal.telephony.Phone; 59 import com.android.internal.telephony.PhoneConfigurationManager; 60 import com.android.internal.telephony.util.TelephonyUtils; 61 import com.android.telephony.Rlog; 62 63 import java.util.HashSet; 64 import java.util.List; 65 import java.util.Map; 66 import java.util.Set; 67 import java.util.UUID; 68 import java.util.concurrent.ConcurrentHashMap; 69 import java.util.concurrent.CountDownLatch; 70 71 /** 72 * Data service manager manages handling data requests and responses on data services (e.g. 73 * Cellular data service, IWLAN data service). 74 */ 75 public class DataServiceManager extends Handler { 76 private static final boolean DBG = true; 77 78 static final String DATA_CALL_RESPONSE = "data_call_response"; 79 80 private static final int EVENT_BIND_DATA_SERVICE = 1; 81 82 private static final int EVENT_WATCHDOG_TIMEOUT = 2; 83 84 private static final long REQUEST_UNRESPONDED_TIMEOUT = 10 * MINUTE_IN_MILLIS; // 10 mins 85 86 private static final long CHANGE_PERMISSION_TIMEOUT_MS = 15 * SECOND_IN_MILLIS; // 15 secs 87 88 private final Phone mPhone; 89 90 private final String mTag; 91 92 private final CarrierConfigManager mCarrierConfigManager; 93 private final AppOpsManager mAppOps; 94 private final LegacyPermissionManager mPermissionManager; 95 96 private final int mTransportType; 97 98 private boolean mBound; 99 100 private IDataService mIDataService; 101 102 private DataServiceManagerDeathRecipient mDeathRecipient; 103 104 private final RegistrantList mServiceBindingChangedRegistrants = new RegistrantList(); 105 106 private final Map<IBinder, Message> mMessageMap = new ConcurrentHashMap<>(); 107 108 private final RegistrantList mDataCallListChangedRegistrants = new RegistrantList(); 109 110 private final RegistrantList mApnUnthrottledRegistrants = new RegistrantList(); 111 112 private String mTargetBindingPackageName; 113 114 private CellularDataServiceConnection mServiceConnection; 115 116 private final UUID mAnomalyUUID = UUID.fromString("fc1956de-c080-45de-8431-a1faab687110"); 117 private String mLastBoundPackageName; 118 119 /** 120 * Helpful for logging 121 * @return the tag name 122 * 123 * @hide 124 */ getTag()125 public String getTag() { 126 return mTag; 127 } 128 129 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 130 @Override 131 public void onReceive(Context context, Intent intent) { 132 final String action = intent.getAction(); 133 if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action) 134 && mPhone.getPhoneId() == intent.getIntExtra( 135 CarrierConfigManager.EXTRA_SLOT_INDEX, 0)) { 136 // We should wait for carrier config changed event because the target binding 137 // package name can come from the carrier config. Note that we still get this event 138 // even when SIM is absent. 139 if (DBG) log("Carrier config changed. Try to bind data service."); 140 sendEmptyMessage(EVENT_BIND_DATA_SERVICE); 141 } 142 } 143 }; 144 145 private class DataServiceManagerDeathRecipient implements IBinder.DeathRecipient { 146 @Override binderDied()147 public void binderDied() { 148 // TODO: try to rebind the service. 149 String message = "Data service " + mLastBoundPackageName + " for transport type " 150 + AccessNetworkConstants.transportTypeToString(mTransportType) + " died."; 151 loge(message); 152 AnomalyReporter.reportAnomaly(mAnomalyUUID, message, mPhone.getCarrierId()); 153 } 154 } 155 grantPermissionsToService(String packageName)156 private void grantPermissionsToService(String packageName) { 157 final String[] pkgToGrant = {packageName}; 158 CountDownLatch latch = new CountDownLatch(1); 159 try { 160 mPermissionManager.grantDefaultPermissionsToEnabledTelephonyDataServices( 161 pkgToGrant, UserHandle.of(UserHandle.myUserId()), Runnable::run, 162 isSuccess -> { 163 if (isSuccess) { 164 latch.countDown(); 165 } else { 166 loge("Failed to grant permissions to service."); 167 } 168 }); 169 TelephonyUtils.waitUntilReady(latch, CHANGE_PERMISSION_TIMEOUT_MS); 170 mAppOps.setMode(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS, 171 UserHandle.myUserId(), pkgToGrant[0], AppOpsManager.MODE_ALLOWED); 172 mAppOps.setMode(AppOpsManager.OPSTR_FINE_LOCATION, 173 UserHandle.myUserId(), pkgToGrant[0], AppOpsManager.MODE_ALLOWED); 174 } catch (RuntimeException e) { 175 loge("Binder to package manager died, permission grant for DataService failed."); 176 throw e; 177 } 178 } 179 180 /** 181 * Loop through all DataServices installed on the system and revoke permissions from any that 182 * are not currently the WWAN or WLAN data service. 183 */ revokePermissionsFromUnusedDataServices()184 private void revokePermissionsFromUnusedDataServices() { 185 // Except the current data services from having their permissions removed. 186 Set<String> dataServices = getAllDataServicePackageNames(); 187 for (int transportType : mPhone.getAccessNetworksManager().getAvailableTransports()) { 188 dataServices.remove(getDataServicePackageName(transportType)); 189 } 190 191 CountDownLatch latch = new CountDownLatch(1); 192 try { 193 String[] dataServicesArray = new String[dataServices.size()]; 194 dataServices.toArray(dataServicesArray); 195 mPermissionManager.revokeDefaultPermissionsFromDisabledTelephonyDataServices( 196 dataServicesArray, UserHandle.of(UserHandle.myUserId()), Runnable::run, 197 isSuccess -> { 198 if (isSuccess) { 199 latch.countDown(); 200 } else { 201 loge("Failed to revoke permissions from data services."); 202 } 203 }); 204 TelephonyUtils.waitUntilReady(latch, CHANGE_PERMISSION_TIMEOUT_MS); 205 for (String pkg : dataServices) { 206 mAppOps.setMode(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS, UserHandle.myUserId(), 207 pkg, AppOpsManager.MODE_ERRORED); 208 mAppOps.setMode(AppOpsManager.OPSTR_FINE_LOCATION, UserHandle.myUserId(), 209 pkg, AppOpsManager.MODE_ERRORED); 210 } 211 } catch (RuntimeException e) { 212 loge("Binder to package manager died; failed to revoke DataService permissions."); 213 throw e; 214 } 215 } 216 217 private final class CellularDataServiceConnection implements ServiceConnection { 218 @Override onServiceConnected(ComponentName name, IBinder service)219 public void onServiceConnected(ComponentName name, IBinder service) { 220 if (DBG) log("onServiceConnected"); 221 mIDataService = IDataService.Stub.asInterface(service); 222 mDeathRecipient = new DataServiceManagerDeathRecipient(); 223 mBound = true; 224 mLastBoundPackageName = getDataServicePackageName(); 225 removeMessages(EVENT_WATCHDOG_TIMEOUT); 226 227 try { 228 service.linkToDeath(mDeathRecipient, 0); 229 mIDataService.createDataServiceProvider(mPhone.getPhoneId()); 230 mIDataService.registerForDataCallListChanged(mPhone.getPhoneId(), 231 new CellularDataServiceCallback("dataCallListChanged")); 232 mIDataService.registerForUnthrottleApn(mPhone.getPhoneId(), 233 new CellularDataServiceCallback("unthrottleApn")); 234 } catch (RemoteException e) { 235 loge("Remote exception. " + e); 236 return; 237 } 238 mServiceBindingChangedRegistrants.notifyResult(true); 239 } 240 @Override onServiceDisconnected(ComponentName name)241 public void onServiceDisconnected(ComponentName name) { 242 if (DBG) log("onServiceDisconnected"); 243 removeMessages(EVENT_WATCHDOG_TIMEOUT); 244 mIDataService = null; 245 mBound = false; 246 mServiceBindingChangedRegistrants.notifyResult(false); 247 mTargetBindingPackageName = null; 248 } 249 } 250 251 private final class CellularDataServiceCallback extends IDataServiceCallback.Stub { 252 253 private final String mTag; 254 CellularDataServiceCallback(String tag)255 CellularDataServiceCallback(String tag) { 256 mTag = tag; 257 } 258 getTag()259 public String getTag() { 260 return mTag; 261 } 262 263 @Override onSetupDataCallComplete(@ataServiceCallback.ResultCode int resultCode, DataCallResponse response)264 public void onSetupDataCallComplete(@DataServiceCallback.ResultCode int resultCode, 265 DataCallResponse response) { 266 if (DBG) { 267 log("onSetupDataCallComplete. resultCode = " + resultCode + ", response = " 268 + response); 269 } 270 removeMessages(EVENT_WATCHDOG_TIMEOUT, CellularDataServiceCallback.this); 271 Message msg = mMessageMap.remove(asBinder()); 272 if (msg != null) { 273 msg.getData().putParcelable(DATA_CALL_RESPONSE, response); 274 sendCompleteMessage(msg, resultCode); 275 } else { 276 loge("Unable to find the message for setup call response."); 277 } 278 } 279 280 @Override onDeactivateDataCallComplete(@ataServiceCallback.ResultCode int resultCode)281 public void onDeactivateDataCallComplete(@DataServiceCallback.ResultCode int resultCode) { 282 if (DBG) log("onDeactivateDataCallComplete. resultCode = " + resultCode); 283 removeMessages(EVENT_WATCHDOG_TIMEOUT, CellularDataServiceCallback.this); 284 Message msg = mMessageMap.remove(asBinder()); 285 sendCompleteMessage(msg, resultCode); 286 } 287 288 @Override onSetInitialAttachApnComplete(@ataServiceCallback.ResultCode int resultCode)289 public void onSetInitialAttachApnComplete(@DataServiceCallback.ResultCode int resultCode) { 290 if (DBG) log("onSetInitialAttachApnComplete. resultCode = " + resultCode); 291 Message msg = mMessageMap.remove(asBinder()); 292 sendCompleteMessage(msg, resultCode); 293 } 294 295 @Override onSetDataProfileComplete(@ataServiceCallback.ResultCode int resultCode)296 public void onSetDataProfileComplete(@DataServiceCallback.ResultCode int resultCode) { 297 if (DBG) log("onSetDataProfileComplete. resultCode = " + resultCode); 298 Message msg = mMessageMap.remove(asBinder()); 299 sendCompleteMessage(msg, resultCode); 300 } 301 302 @Override onRequestDataCallListComplete(@ataServiceCallback.ResultCode int resultCode, List<DataCallResponse> dataCallList)303 public void onRequestDataCallListComplete(@DataServiceCallback.ResultCode int resultCode, 304 List<DataCallResponse> dataCallList) { 305 if (DBG) log("onRequestDataCallListComplete. resultCode = " + resultCode); 306 Message msg = mMessageMap.remove(asBinder()); 307 sendCompleteMessage(msg, resultCode); 308 } 309 310 @Override onDataCallListChanged(List<DataCallResponse> dataCallList)311 public void onDataCallListChanged(List<DataCallResponse> dataCallList) { 312 mDataCallListChangedRegistrants.notifyRegistrants( 313 new AsyncResult(null, dataCallList, null)); 314 } 315 316 @Override onHandoverStarted(@ataServiceCallback.ResultCode int resultCode)317 public void onHandoverStarted(@DataServiceCallback.ResultCode int resultCode) { 318 if (DBG) log("onHandoverStarted. resultCode = " + resultCode); 319 removeMessages(EVENT_WATCHDOG_TIMEOUT, CellularDataServiceCallback.this); 320 Message msg = mMessageMap.remove(asBinder()); 321 sendCompleteMessage(msg, resultCode); 322 } 323 324 @Override onHandoverCancelled(@ataServiceCallback.ResultCode int resultCode)325 public void onHandoverCancelled(@DataServiceCallback.ResultCode int resultCode) { 326 if (DBG) log("onHandoverCancelled. resultCode = " + resultCode); 327 removeMessages(EVENT_WATCHDOG_TIMEOUT, CellularDataServiceCallback.this); 328 Message msg = mMessageMap.remove(asBinder()); 329 sendCompleteMessage(msg, resultCode); 330 } 331 332 @Override onApnUnthrottled(String apn)333 public void onApnUnthrottled(String apn) { 334 if (apn != null) { 335 mApnUnthrottledRegistrants.notifyRegistrants( 336 new AsyncResult(null, apn, null)); 337 } else { 338 loge("onApnUnthrottled: apn is null"); 339 } 340 } 341 342 @Override onDataProfileUnthrottled(DataProfile dataProfile)343 public void onDataProfileUnthrottled(DataProfile dataProfile) { 344 if (dataProfile != null) { 345 mApnUnthrottledRegistrants.notifyRegistrants( 346 new AsyncResult(null, dataProfile, null)); 347 } else { 348 loge("onDataProfileUnthrottled: dataProfile is null"); 349 } 350 } 351 } 352 353 /** 354 * Constructor 355 * 356 * @param phone The phone object 357 * @param transportType The transport type 358 * @param tagSuffix Logging tag suffix 359 */ DataServiceManager(Phone phone, @TransportType int transportType, String tagSuffix)360 public DataServiceManager(Phone phone, @TransportType int transportType, String tagSuffix) { 361 mPhone = phone; 362 mTag = "DSM" + tagSuffix; 363 mTransportType = transportType; 364 mBound = false; 365 mCarrierConfigManager = (CarrierConfigManager) phone.getContext().getSystemService( 366 Context.CARRIER_CONFIG_SERVICE); 367 // NOTE: Do NOT use AppGlobals to retrieve the permission manager; AppGlobals 368 // caches the service instance, but we need to explicitly request a new service 369 // so it can be mocked out for tests 370 mPermissionManager = (LegacyPermissionManager) phone.getContext().getSystemService( 371 Context.LEGACY_PERMISSION_SERVICE); 372 mAppOps = (AppOpsManager) phone.getContext().getSystemService(Context.APP_OPS_SERVICE); 373 374 IntentFilter intentFilter = new IntentFilter(); 375 intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); 376 try { 377 Context contextAsUser = phone.getContext().createPackageContextAsUser( 378 phone.getContext().getPackageName(), 0, UserHandle.ALL); 379 contextAsUser.registerReceiver(mBroadcastReceiver, intentFilter, 380 null /* broadcastPermission */, null); 381 } catch (PackageManager.NameNotFoundException e) { 382 loge("Package name not found: " + e.getMessage()); 383 } 384 385 PhoneConfigurationManager.registerForMultiSimConfigChange( 386 this, EVENT_BIND_DATA_SERVICE, null); 387 388 sendEmptyMessage(EVENT_BIND_DATA_SERVICE); 389 } 390 391 /** 392 * Handle message events 393 * 394 * @param msg The message to handle 395 */ 396 @Override handleMessage(Message msg)397 public void handleMessage(Message msg) { 398 switch (msg.what) { 399 case EVENT_BIND_DATA_SERVICE: 400 rebindDataService(); 401 break; 402 case EVENT_WATCHDOG_TIMEOUT: 403 handleRequestUnresponded((CellularDataServiceCallback) msg.obj); 404 break; 405 default: 406 loge("Unhandled event " + msg.what); 407 } 408 } 409 handleRequestUnresponded(CellularDataServiceCallback callback)410 private void handleRequestUnresponded(CellularDataServiceCallback callback) { 411 String message = "Request " + callback.getTag() + " unresponded on transport " 412 + AccessNetworkConstants.transportTypeToString(mTransportType) + " in " 413 + REQUEST_UNRESPONDED_TIMEOUT / 1000 + " seconds."; 414 log(message); 415 // Using fixed UUID to avoid duplicate bugreport notification 416 AnomalyReporter.reportAnomaly( 417 UUID.fromString("f5d5cbe6-9bd6-4009-b764-42b1b649b1de"), 418 message, mPhone.getCarrierId()); 419 } 420 unbindDataService()421 private void unbindDataService() { 422 // Start by cleaning up all packages that *shouldn't* have permissions. 423 revokePermissionsFromUnusedDataServices(); 424 if (mIDataService != null && mIDataService.asBinder().isBinderAlive()) { 425 log("unbinding service"); 426 // Remove the network availability updater and then unbind the service. 427 try { 428 mIDataService.removeDataServiceProvider(mPhone.getPhoneId()); 429 } catch (RemoteException e) { 430 loge("Cannot remove data service provider. " + e); 431 } 432 } 433 434 if (mServiceConnection != null) { 435 mPhone.getContext().unbindService(mServiceConnection); 436 } 437 mIDataService = null; 438 mServiceConnection = null; 439 mTargetBindingPackageName = null; 440 mBound = false; 441 } 442 bindDataService(String packageName)443 private void bindDataService(String packageName) { 444 if (mPhone == null || !SubscriptionManager.isValidPhoneId(mPhone.getPhoneId())) { 445 loge("can't bindDataService with invalid phone or phoneId."); 446 return; 447 } 448 449 if (TextUtils.isEmpty(packageName)) { 450 loge("Can't find the binding package"); 451 return; 452 } 453 454 Intent intent = null; 455 String className = getDataServiceClassName(); 456 if (TextUtils.isEmpty(className)) { 457 intent = new Intent(DataService.SERVICE_INTERFACE); 458 intent.setPackage(packageName); 459 } else { 460 ComponentName cm = new ComponentName(packageName, className); 461 intent = new Intent(DataService.SERVICE_INTERFACE).setComponent(cm); 462 } 463 464 // Then pre-emptively grant the permissions to the package we will bind. 465 grantPermissionsToService(packageName); 466 467 try { 468 mServiceConnection = new CellularDataServiceConnection(); 469 if (!mPhone.getContext().bindService( 470 intent, mServiceConnection, Context.BIND_AUTO_CREATE)) { 471 loge("Cannot bind to the data service."); 472 return; 473 } 474 mTargetBindingPackageName = packageName; 475 } catch (Exception e) { 476 loge("Cannot bind to the data service. Exception: " + e); 477 } 478 } 479 rebindDataService()480 private void rebindDataService() { 481 String packageName = getDataServicePackageName(); 482 // Do nothing if no need to rebind. 483 if (SubscriptionManager.isValidPhoneId(mPhone.getPhoneId()) 484 && TextUtils.equals(packageName, mTargetBindingPackageName)) { 485 if (DBG) log("Service " + packageName + " already bound or being bound."); 486 return; 487 } 488 489 unbindDataService(); 490 bindDataService(packageName); 491 } 492 493 @NonNull getAllDataServicePackageNames()494 private Set<String> getAllDataServicePackageNames() { 495 // Cowardly using the public PackageManager interface here. 496 // Note: This matches only packages that were installed on the system image. If we ever 497 // expand the permissions model to allow CarrierPrivileged packages, then this will need 498 // to be updated. 499 List<ResolveInfo> dataPackages = 500 mPhone.getContext().getPackageManager().queryIntentServices( 501 new Intent(DataService.SERVICE_INTERFACE), 502 PackageManager.MATCH_SYSTEM_ONLY); 503 HashSet<String> packageNames = new HashSet<>(); 504 for (ResolveInfo info : dataPackages) { 505 if (info.serviceInfo == null) continue; 506 packageNames.add(info.serviceInfo.packageName); 507 } 508 return packageNames; 509 } 510 511 /** 512 * Get the data service package name for our current transport type. 513 * 514 * @return package name of the data service package for the the current transportType. 515 */ getDataServicePackageName()516 public String getDataServicePackageName() { 517 return getDataServicePackageName(mTransportType); 518 } 519 520 /** 521 * Get the data service package by transport type. 522 * 523 * When we bind to a DataService package, we need to revoke permissions from stale 524 * packages; we need to exclude data packages for all transport types, so we need to 525 * to be able to query by transport type. 526 * 527 * @param transportType The transport type 528 * @return package name of the data service package for the specified transportType. 529 */ getDataServicePackageName(@ransportType int transportType)530 private String getDataServicePackageName(@TransportType int transportType) { 531 String packageName; 532 int resourceId; 533 String carrierConfig; 534 535 switch (transportType) { 536 case AccessNetworkConstants.TRANSPORT_TYPE_WWAN: 537 resourceId = com.android.internal.R.string.config_wwan_data_service_package; 538 carrierConfig = CarrierConfigManager 539 .KEY_CARRIER_DATA_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING; 540 break; 541 case AccessNetworkConstants.TRANSPORT_TYPE_WLAN: 542 resourceId = com.android.internal.R.string.config_wlan_data_service_package; 543 carrierConfig = CarrierConfigManager 544 .KEY_CARRIER_DATA_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING; 545 break; 546 default: 547 throw new IllegalStateException("Transport type not WWAN or WLAN. type=" 548 + AccessNetworkConstants.transportTypeToString(mTransportType)); 549 } 550 551 // Read package name from resource overlay 552 packageName = mPhone.getContext().getResources().getString(resourceId); 553 554 PersistableBundle b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId()); 555 556 if (b != null && !TextUtils.isEmpty(b.getString(carrierConfig))) { 557 // If carrier config overrides it, use the one from carrier config 558 packageName = b.getString(carrierConfig, packageName); 559 } 560 561 return packageName; 562 } 563 564 /** 565 * Get the data service class name for our current transport type. 566 * 567 * @return class name of the data service package for the the current transportType. 568 */ getDataServiceClassName()569 private String getDataServiceClassName() { 570 return getDataServiceClassName(mTransportType); 571 } 572 573 574 /** 575 * Get the data service class by transport type. 576 * 577 * @param transportType either WWAN or WLAN 578 * @return class name of the data service package for the specified transportType. 579 */ getDataServiceClassName(int transportType)580 private String getDataServiceClassName(int transportType) { 581 String className; 582 int resourceId; 583 String carrierConfig; 584 switch (transportType) { 585 case AccessNetworkConstants.TRANSPORT_TYPE_WWAN: 586 resourceId = com.android.internal.R.string.config_wwan_data_service_class; 587 carrierConfig = CarrierConfigManager 588 .KEY_CARRIER_DATA_SERVICE_WWAN_CLASS_OVERRIDE_STRING; 589 break; 590 case AccessNetworkConstants.TRANSPORT_TYPE_WLAN: 591 resourceId = com.android.internal.R.string.config_wlan_data_service_class; 592 carrierConfig = CarrierConfigManager 593 .KEY_CARRIER_DATA_SERVICE_WLAN_CLASS_OVERRIDE_STRING; 594 break; 595 default: 596 throw new IllegalStateException("Transport type not WWAN or WLAN. type=" 597 + transportType); 598 } 599 600 // Read package name from resource overlay 601 className = mPhone.getContext().getResources().getString(resourceId); 602 603 PersistableBundle b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId()); 604 605 if (b != null && !TextUtils.isEmpty(b.getString(carrierConfig))) { 606 // If carrier config overrides it, use the one from carrier config 607 className = b.getString(carrierConfig, className); 608 } 609 610 return className; 611 } 612 sendCompleteMessage(Message msg, @DataServiceCallback.ResultCode int code)613 private void sendCompleteMessage(Message msg, @DataServiceCallback.ResultCode int code) { 614 if (msg != null) { 615 msg.arg1 = code; 616 msg.sendToTarget(); 617 } 618 } 619 620 /** 621 * Setup a data connection. The data service provider must implement this method to support 622 * establishing a packet data connection. When completed or error, the service must invoke 623 * the provided callback to notify the platform. 624 * 625 * @param accessNetworkType Access network type that the data call will be established on. 626 * Must be one of {@link AccessNetworkConstants.AccessNetworkType}. 627 * @param dataProfile Data profile used for data call setup. See {@link DataProfile} 628 * @param isRoaming True if the device is data roaming. 629 * @param allowRoaming True if data roaming is allowed by the user. 630 * @param reason The reason for data setup. Must be {@link DataService#REQUEST_REASON_NORMAL} or 631 * {@link DataService#REQUEST_REASON_HANDOVER}. 632 * @param linkProperties If {@code reason} is {@link DataService#REQUEST_REASON_HANDOVER}, this 633 * is the link properties of the existing data connection, otherwise null. 634 * @param pduSessionId The pdu session id to be used for this data call. A value of -1 means 635 * no pdu session id was attached to this call. 636 * Reference: 3GPP TS 24.007 Section 11.2.3.1b 637 * @param sliceInfo The slice that represents S-NSSAI. 638 * Reference: 3GPP TS 24.501 639 * @param trafficDescriptor The traffic descriptor for this data call, used for URSP matching. 640 * Reference: 3GPP TS TS 24.526 Section 5.2 641 * @param matchAllRuleAllowed True if using the default match-all URSP rule for this request is 642 * allowed. 643 * @param onCompleteMessage The result message for this request. Null if the client does not 644 * care about the result. 645 */ setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming, boolean allowRoaming, int reason, LinkProperties linkProperties, int pduSessionId, @Nullable NetworkSliceInfo sliceInfo, @Nullable TrafficDescriptor trafficDescriptor, boolean matchAllRuleAllowed, Message onCompleteMessage)646 public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming, 647 boolean allowRoaming, int reason, LinkProperties linkProperties, int pduSessionId, 648 @Nullable NetworkSliceInfo sliceInfo, @Nullable TrafficDescriptor trafficDescriptor, 649 boolean matchAllRuleAllowed, Message onCompleteMessage) { 650 if (DBG) log("setupDataCall"); 651 if (!mBound) { 652 loge("setupDataCall: Data service not bound."); 653 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 654 return; 655 } 656 657 CellularDataServiceCallback callback = new CellularDataServiceCallback("setupDataCall"); 658 if (onCompleteMessage != null) { 659 mMessageMap.put(callback.asBinder(), onCompleteMessage); 660 } 661 try { 662 sendMessageDelayed(obtainMessage(EVENT_WATCHDOG_TIMEOUT, callback), 663 REQUEST_UNRESPONDED_TIMEOUT); 664 mIDataService.setupDataCall(mPhone.getPhoneId(), accessNetworkType, dataProfile, 665 isRoaming, allowRoaming, reason, linkProperties, pduSessionId, sliceInfo, 666 trafficDescriptor, matchAllRuleAllowed, callback); 667 } catch (RemoteException e) { 668 loge("setupDataCall: Cannot invoke setupDataCall on data service."); 669 mMessageMap.remove(callback.asBinder()); 670 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 671 } 672 } 673 674 /** 675 * Deactivate a data connection. The data service provider must implement this method to 676 * support data connection tear down. When completed or error, the service must invoke the 677 * provided callback to notify the platform. 678 * 679 * @param cid Call id returned in the callback of {@link #setupDataCall(int, DataProfile, 680 * boolean, boolean, int, LinkProperties, Message)} 681 * @param reason The reason for data deactivation. Must be 682 * {@link DataService#REQUEST_REASON_NORMAL}, {@link DataService#REQUEST_REASON_SHUTDOWN} 683 * or {@link DataService#REQUEST_REASON_HANDOVER}. 684 * @param onCompleteMessage The result message for this request. Null if the client does not 685 * care about the result. 686 */ deactivateDataCall(int cid, int reason, Message onCompleteMessage)687 public void deactivateDataCall(int cid, int reason, Message onCompleteMessage) { 688 if (DBG) log("deactivateDataCall"); 689 if (!mBound) { 690 loge("Data service not bound."); 691 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 692 return; 693 } 694 695 CellularDataServiceCallback callback = 696 new CellularDataServiceCallback("deactivateDataCall"); 697 if (onCompleteMessage != null) { 698 mMessageMap.put(callback.asBinder(), onCompleteMessage); 699 } 700 try { 701 sendMessageDelayed(obtainMessage(EVENT_WATCHDOG_TIMEOUT, callback), 702 REQUEST_UNRESPONDED_TIMEOUT); 703 mIDataService.deactivateDataCall(mPhone.getPhoneId(), cid, reason, callback); 704 } catch (RemoteException e) { 705 loge("Cannot invoke deactivateDataCall on data service."); 706 mMessageMap.remove(callback.asBinder()); 707 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 708 } 709 } 710 711 /** 712 * Indicates that a handover has begun. This is called on the source transport. 713 * 714 * Any resources being transferred cannot be released while a 715 * handover is underway. 716 * 717 * If a handover was unsuccessful, then the framework calls DataServiceManager#cancelHandover. 718 * The target transport retains ownership over any of the resources being transferred. 719 * 720 * If a handover was successful, the framework calls DataServiceManager#deactivateDataCall with 721 * reason HANDOVER. The target transport now owns the transferred resources and is 722 * responsible for releasing them. 723 * 724 * @param cid The identifier of the data call which is provided in DataCallResponse 725 * @param onCompleteMessage The result callback for this request. 726 */ startHandover(int cid, @NonNull Message onCompleteMessage)727 public void startHandover(int cid, @NonNull Message onCompleteMessage) { 728 CellularDataServiceCallback callback = 729 setupCallbackHelper("startHandover", onCompleteMessage); 730 if (callback == null) { 731 loge("startHandover: callback == null"); 732 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 733 return; 734 } 735 736 try { 737 sendMessageDelayed(obtainMessage(EVENT_WATCHDOG_TIMEOUT, callback), 738 REQUEST_UNRESPONDED_TIMEOUT); 739 mIDataService.startHandover(mPhone.getPhoneId(), cid, callback); 740 } catch (RemoteException e) { 741 loge("Cannot invoke startHandover on data service."); 742 mMessageMap.remove(callback.asBinder()); 743 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 744 } 745 } 746 747 /** 748 * Indicates that a handover was cancelled after a call to DataServiceManager#startHandover. 749 * This is called on the source transport. 750 * 751 * Since the handover was unsuccessful, the source transport retains ownership over any of 752 * the resources being transferred and is still responsible for releasing them. 753 * 754 * @param cid The identifier of the data call which is provided in DataCallResponse 755 * @param onCompleteMessage The result callback for this request. 756 */ cancelHandover(int cid, @NonNull Message onCompleteMessage)757 public void cancelHandover(int cid, @NonNull Message onCompleteMessage) { 758 CellularDataServiceCallback callback = 759 setupCallbackHelper("cancelHandover", onCompleteMessage); 760 if (callback == null) { 761 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 762 return; 763 } 764 765 try { 766 sendMessageDelayed(obtainMessage(EVENT_WATCHDOG_TIMEOUT, callback), 767 REQUEST_UNRESPONDED_TIMEOUT); 768 mIDataService.cancelHandover(mPhone.getPhoneId(), cid, callback); 769 } catch (RemoteException e) { 770 loge("Cannot invoke cancelHandover on data service."); 771 mMessageMap.remove(callback.asBinder()); 772 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 773 } 774 } 775 776 @Nullable setupCallbackHelper( @onNull final String operationName, @NonNull final Message onCompleteMessage)777 private CellularDataServiceCallback setupCallbackHelper( 778 @NonNull final String operationName, @NonNull final Message onCompleteMessage) { 779 if (DBG) log(operationName); 780 if (!mBound) { 781 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 782 return null; 783 } 784 785 CellularDataServiceCallback callback = 786 new CellularDataServiceCallback(operationName); 787 if (onCompleteMessage != null) { 788 if (DBG) log(operationName + ": onCompleteMessage set"); 789 mMessageMap.put(callback.asBinder(), onCompleteMessage); 790 } else { 791 if (DBG) log(operationName + ": onCompleteMessage not set"); 792 } 793 return callback; 794 } 795 796 /** 797 * Set an APN to initial attach network. 798 * 799 * @param dataProfile Data profile used for data call setup. See {@link DataProfile}. 800 * @param isRoaming True if the device is data roaming. 801 * @param onCompleteMessage The result message for this request. Null if the client does not 802 * care about the result. 803 */ setInitialAttachApn(DataProfile dataProfile, boolean isRoaming, Message onCompleteMessage)804 public void setInitialAttachApn(DataProfile dataProfile, boolean isRoaming, 805 Message onCompleteMessage) { 806 if (DBG) log("setInitialAttachApn"); 807 if (!mBound) { 808 loge("Data service not bound."); 809 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 810 return; 811 } 812 813 CellularDataServiceCallback callback = 814 new CellularDataServiceCallback("setInitialAttachApn"); 815 if (onCompleteMessage != null) { 816 mMessageMap.put(callback.asBinder(), onCompleteMessage); 817 } 818 try { 819 mIDataService.setInitialAttachApn(mPhone.getPhoneId(), dataProfile, isRoaming, 820 callback); 821 } catch (RemoteException e) { 822 loge("Cannot invoke setInitialAttachApn on data service."); 823 mMessageMap.remove(callback.asBinder()); 824 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 825 } 826 } 827 828 /** 829 * Send current carrier's data profiles to the data service for data call setup. This is 830 * only for CDMA carrier that can change the profile through OTA. The data service should 831 * always uses the latest data profile sent by the framework. 832 * 833 * @param dps A list of data profiles. 834 * @param isRoaming True if the device is data roaming. 835 * @param onCompleteMessage The result message for this request. Null if the client does not 836 * care about the result. 837 */ setDataProfile(List<DataProfile> dps, boolean isRoaming, Message onCompleteMessage)838 public void setDataProfile(List<DataProfile> dps, boolean isRoaming, 839 Message onCompleteMessage) { 840 if (DBG) log("setDataProfile"); 841 if (!mBound) { 842 loge("Data service not bound."); 843 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 844 return; 845 } 846 847 CellularDataServiceCallback callback = new CellularDataServiceCallback("setDataProfile"); 848 if (onCompleteMessage != null) { 849 mMessageMap.put(callback.asBinder(), onCompleteMessage); 850 } 851 try { 852 mIDataService.setDataProfile(mPhone.getPhoneId(), dps, isRoaming, callback); 853 } catch (RemoteException e) { 854 loge("Cannot invoke setDataProfile on data service."); 855 mMessageMap.remove(callback.asBinder()); 856 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 857 } 858 } 859 860 /** 861 * Get the active data call list. 862 * 863 * @param onCompleteMessage The result message for this request. Null if the client does not 864 * care about the result. 865 */ requestDataCallList(Message onCompleteMessage)866 public void requestDataCallList(Message onCompleteMessage) { 867 if (DBG) log("requestDataCallList"); 868 if (!mBound) { 869 loge("Data service not bound."); 870 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 871 return; 872 } 873 874 CellularDataServiceCallback callback = 875 new CellularDataServiceCallback("requestDataCallList"); 876 if (onCompleteMessage != null) { 877 mMessageMap.put(callback.asBinder(), onCompleteMessage); 878 } 879 try { 880 mIDataService.requestDataCallList(mPhone.getPhoneId(), callback); 881 } catch (RemoteException e) { 882 loge("Cannot invoke requestDataCallList on data service."); 883 if (callback != null) { 884 mMessageMap.remove(callback.asBinder()); 885 } 886 sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 887 } 888 } 889 890 /** 891 * Register for data call list changed event. 892 * 893 * @param h The target to post the event message to. 894 * @param what The event. 895 */ registerForDataCallListChanged(Handler h, int what)896 public void registerForDataCallListChanged(Handler h, int what) { 897 if (h != null) { 898 mDataCallListChangedRegistrants.addUnique(h, what, null); 899 } 900 } 901 902 /** 903 * Unregister for data call list changed event. 904 * 905 * @param h The handler 906 */ unregisterForDataCallListChanged(Handler h)907 public void unregisterForDataCallListChanged(Handler h) { 908 if (h != null) { 909 mDataCallListChangedRegistrants.remove(h); 910 } 911 } 912 913 /** 914 * Register apn unthrottled event 915 * 916 * @param h The target to post the event message to. 917 * @param what The event. 918 */ registerForApnUnthrottled(Handler h, int what)919 public void registerForApnUnthrottled(Handler h, int what) { 920 if (h != null) { 921 mApnUnthrottledRegistrants.addUnique(h, what, null); 922 } 923 } 924 925 /** 926 * Unregister for apn unthrottled event 927 * 928 * @param h The handler 929 */ unregisterForApnUnthrottled(Handler h)930 public void unregisterForApnUnthrottled(Handler h) { 931 if (h != null) { 932 mApnUnthrottledRegistrants.remove(h); 933 } 934 } 935 936 /** 937 * Register for data service binding status changed event. 938 * 939 * @param h The target to post the event message to. 940 * @param what The event. 941 * @param obj The user object. 942 */ registerForServiceBindingChanged(Handler h, int what, Object obj)943 public void registerForServiceBindingChanged(Handler h, int what, Object obj) { 944 if (h != null) { 945 mServiceBindingChangedRegistrants.addUnique(h, what, obj); 946 } 947 948 } 949 950 /** 951 * Unregister for data service binding status changed event. 952 * 953 * @param h The handler 954 */ unregisterForServiceBindingChanged(Handler h)955 public void unregisterForServiceBindingChanged(Handler h) { 956 if (h != null) { 957 mServiceBindingChangedRegistrants.remove(h); 958 } 959 } 960 961 /** 962 * Get the transport type. Must be a {@link TransportType}. 963 * 964 * @return 965 */ 966 @TransportType getTransportType()967 public int getTransportType() { 968 return mTransportType; 969 } 970 log(String s)971 private void log(String s) { 972 Rlog.d(mTag, s); 973 } 974 loge(String s)975 private void loge(String s) { 976 Rlog.e(mTag, s); 977 } 978 } 979