1 /* 2 * Copyright (c) 2015, 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.phone; 18 19 import static android.service.carrier.CarrierService.ICarrierServiceWrapper.KEY_CONFIG_BUNDLE; 20 import static android.service.carrier.CarrierService.ICarrierServiceWrapper.RESULT_ERROR; 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.SharedPreferences; 32 import android.content.pm.PackageInfo; 33 import android.content.pm.PackageManager; 34 import android.os.Binder; 35 import android.os.Build; 36 import android.os.Bundle; 37 import android.os.Handler; 38 import android.os.IBinder; 39 import android.os.Looper; 40 import android.os.Message; 41 import android.os.PersistableBundle; 42 import android.os.Process; 43 import android.os.RemoteException; 44 import android.os.ResultReceiver; 45 import android.os.UserHandle; 46 import android.preference.PreferenceManager; 47 import android.service.carrier.CarrierIdentifier; 48 import android.service.carrier.CarrierService; 49 import android.service.carrier.ICarrierService; 50 import android.telephony.CarrierConfigManager; 51 import android.telephony.SubscriptionManager; 52 import android.telephony.TelephonyFrameworkInitializer; 53 import android.telephony.TelephonyManager; 54 import android.text.TextUtils; 55 import android.util.ArraySet; 56 import android.util.LocalLog; 57 import android.util.Log; 58 59 import com.android.internal.annotations.VisibleForTesting; 60 import com.android.internal.telephony.ICarrierConfigLoader; 61 import com.android.internal.telephony.IccCardConstants; 62 import com.android.internal.telephony.Phone; 63 import com.android.internal.telephony.PhoneFactory; 64 import com.android.internal.telephony.SubscriptionInfoUpdater; 65 import com.android.internal.telephony.TelephonyPermissions; 66 import com.android.internal.telephony.util.ArrayUtils; 67 import com.android.internal.util.IndentingPrintWriter; 68 69 import java.io.File; 70 import java.io.FileDescriptor; 71 import java.io.FileInputStream; 72 import java.io.FileNotFoundException; 73 import java.io.FileOutputStream; 74 import java.io.FilenameFilter; 75 import java.io.IOException; 76 import java.io.PrintWriter; 77 import java.util.ArrayList; 78 import java.util.Arrays; 79 import java.util.Collections; 80 import java.util.List; 81 import java.util.Set; 82 83 /** 84 * CarrierConfigLoader binds to privileged carrier apps to fetch carrier config overlays. 85 */ 86 public class CarrierConfigLoader extends ICarrierConfigLoader.Stub { 87 private static final String LOG_TAG = "CarrierConfigLoader"; 88 89 // Package name for platform carrier config app, bundled with system image. 90 private final String mPlatformCarrierConfigPackage; 91 92 /** The singleton instance. */ 93 private static CarrierConfigLoader sInstance; 94 // The context for phone app, passed from PhoneGlobals. 95 private Context mContext; 96 // Carrier configs from default app, indexed by phoneID. 97 private PersistableBundle[] mConfigFromDefaultApp; 98 // Carrier configs from privileged carrier config app, indexed by phoneID. 99 private PersistableBundle[] mConfigFromCarrierApp; 100 // Persistent Carrier configs that are provided via the override test API, indexed by phone ID. 101 private PersistableBundle[] mPersistentOverrideConfigs; 102 // Carrier configs that are provided via the override test API, indexed by phone ID. 103 private PersistableBundle[] mOverrideConfigs; 104 // Carrier configs to override code default when there is no SIM inserted 105 private PersistableBundle mNoSimConfig; 106 // Service connection for binding to config app. 107 private CarrierServiceConnection[] mServiceConnection; 108 // Service connection for binding to carrier config app for no SIM config. 109 private CarrierServiceConnection[] mServiceConnectionForNoSimConfig; 110 // Whether we are bound to a service for each phone 111 private boolean[] mServiceBound; 112 // Whether we are bound to a service for no SIM config 113 private boolean[] mServiceBoundForNoSimConfig; 114 // Whether we have sent config change broadcast for each phone id. 115 private boolean[] mHasSentConfigChange; 116 // Whether the broadcast was sent from EVENT_SYSTEM_UNLOCKED, to track rebroadcasts 117 private boolean[] mFromSystemUnlocked; 118 // SubscriptionInfoUpdater 119 private final SubscriptionInfoUpdater mSubscriptionInfoUpdater; 120 121 // Broadcast receiver for Boot intents, register intent filter in construtor. 122 private final BroadcastReceiver mBootReceiver = new ConfigLoaderBroadcastReceiver(); 123 // Broadcast receiver for SIM and pkg intents, register intent filter in constructor. 124 private final BroadcastReceiver mPackageReceiver = new ConfigLoaderBroadcastReceiver(); 125 private final LocalLog mCarrierConfigLoadingLog = new LocalLog(100); 126 127 128 // Message codes; see mHandler below. 129 // Request from SubscriptionInfoUpdater when SIM becomes absent or error. 130 private static final int EVENT_CLEAR_CONFIG = 0; 131 // Has connected to default app. 132 private static final int EVENT_CONNECTED_TO_DEFAULT = 3; 133 // Has connected to carrier app. 134 private static final int EVENT_CONNECTED_TO_CARRIER = 4; 135 // Config has been loaded from default app (or cache). 136 private static final int EVENT_FETCH_DEFAULT_DONE = 5; 137 // Config has been loaded from carrier app (or cache). 138 private static final int EVENT_FETCH_CARRIER_DONE = 6; 139 // Attempt to fetch from default app or read from XML. 140 private static final int EVENT_DO_FETCH_DEFAULT = 7; 141 // Attempt to fetch from carrier app or read from XML. 142 private static final int EVENT_DO_FETCH_CARRIER = 8; 143 // A package has been installed, uninstalled, or updated. 144 private static final int EVENT_PACKAGE_CHANGED = 9; 145 // Bind timed out for the default app. 146 private static final int EVENT_BIND_DEFAULT_TIMEOUT = 10; 147 // Bind timed out for a carrier app. 148 private static final int EVENT_BIND_CARRIER_TIMEOUT = 11; 149 // Check if the system fingerprint has changed. 150 private static final int EVENT_CHECK_SYSTEM_UPDATE = 12; 151 // Rerun carrier config binding after system is unlocked. 152 private static final int EVENT_SYSTEM_UNLOCKED = 13; 153 // Fetching config timed out from the default app. 154 private static final int EVENT_FETCH_DEFAULT_TIMEOUT = 14; 155 // Fetching config timed out from a carrier app. 156 private static final int EVENT_FETCH_CARRIER_TIMEOUT = 15; 157 // SubscriptionInfoUpdater has finished updating the sub for the carrier config. 158 private static final int EVENT_SUBSCRIPTION_INFO_UPDATED = 16; 159 // Multi-SIM config changed. 160 private static final int EVENT_MULTI_SIM_CONFIG_CHANGED = 17; 161 // Attempt to fetch from default app or read from XML for no SIM case. 162 private static final int EVENT_DO_FETCH_DEFAULT_FOR_NO_SIM_CONFIG = 18; 163 // No SIM config has been loaded from default app (or cache). 164 private static final int EVENT_FETCH_DEFAULT_FOR_NO_SIM_CONFIG_DONE = 19; 165 // Has connected to default app for no SIM config. 166 private static final int EVENT_CONNECTED_TO_DEFAULT_FOR_NO_SIM_CONFIG = 20; 167 // Bind timed out for the default app when trying to fetch no SIM config. 168 private static final int EVENT_BIND_DEFAULT_FOR_NO_SIM_CONFIG_TIMEOUT = 21; 169 // Fetching config timed out from the default app for no SIM config. 170 private static final int EVENT_FETCH_DEFAULT_FOR_NO_SIM_CONFIG_TIMEOUT = 22; 171 // NOTE: any new EVENT_* values must be added to method eventToString(). 172 173 private static final int BIND_TIMEOUT_MILLIS = 30000; 174 175 // Keys used for saving and restoring config bundle from file. 176 private static final String KEY_VERSION = "__carrier_config_package_version__"; 177 178 private static final String OVERRIDE_PACKAGE_ADDITION = "-override"; 179 180 // SharedPreferences key for last known build fingerprint. 181 private static final String KEY_FINGERPRINT = "build_fingerprint"; 182 183 // Argument for #dump that indicates we should also call the default and specified carrier 184 // service's #dump method. In multi-SIM devices, it's possible that carrier A is on SIM 1 and 185 // carrier B is on SIM 2, in which case we should not dump carrier B's service when carrier A 186 // requested the dump. 187 private static final String DUMP_ARG_REQUESTING_PACKAGE = "--requesting-package"; 188 189 // Handler to process various events. 190 // 191 // For each phoneId, the event sequence should be: 192 // fetch default, connected to default, fetch default (async), fetch default done, 193 // fetch carrier, connected to carrier, fetch carrier (async), fetch carrier done. 194 // 195 // If there is a saved config file for either the default app or the carrier app, we skip 196 // binding to the app and go straight from fetch to loaded. 197 // 198 // At any time, at most one connection is active. If events are not in this order, previous 199 // connection will be unbound, so only latest event takes effect. 200 // 201 // We broadcast ACTION_CARRIER_CONFIG_CHANGED after: 202 // 1. loading from carrier app (even if read from a file) 203 // 2. loading from default app if there is no carrier app (even if read from a file) 204 // 3. clearing config (e.g. due to sim removal) 205 // 4. encountering bind or IPC error 206 private class ConfigHandler extends Handler { ConfigHandler(@onNull Looper looper)207 ConfigHandler(@NonNull Looper looper) { 208 super(looper); 209 } 210 211 @Override handleMessage(Message msg)212 public void handleMessage(Message msg) { 213 final int phoneId = msg.arg1; 214 logdWithLocalLog("mHandler: " + eventToString(msg.what) + " phoneId: " + phoneId); 215 if (!SubscriptionManager.isValidPhoneId(phoneId) 216 && msg.what != EVENT_MULTI_SIM_CONFIG_CHANGED) { 217 return; 218 } 219 switch (msg.what) { 220 case EVENT_CLEAR_CONFIG: { 221 clearConfigForPhone(phoneId, true); 222 break; 223 } 224 225 case EVENT_SYSTEM_UNLOCKED: { 226 for (int i = 0; i < TelephonyManager.from(mContext).getActiveModemCount(); 227 ++i) { 228 // When the user unlocks the device, send the broadcast again (with a 229 // rebroadcast extra) if we have sent it before unlock. This will avoid 230 // trying to load the carrier config when the SIM is still loading when the 231 // unlock happens. 232 if (mHasSentConfigChange[i]) { 233 logdWithLocalLog("System unlocked"); 234 mFromSystemUnlocked[i] = true; 235 updateConfigForPhoneId(i); 236 } 237 } 238 break; 239 } 240 241 case EVENT_PACKAGE_CHANGED: { 242 final String carrierPackageName = (String) msg.obj; 243 // Only update if there are cached config removed to avoid updating config for 244 // unrelated packages. 245 if (clearCachedConfigForPackage(carrierPackageName)) { 246 int numPhones = TelephonyManager.from(mContext).getActiveModemCount(); 247 for (int i = 0; i < numPhones; ++i) { 248 logdWithLocalLog("Package changed: " + carrierPackageName 249 + ", phone=" + i); 250 updateConfigForPhoneId(i); 251 } 252 } 253 break; 254 } 255 256 case EVENT_DO_FETCH_DEFAULT: { 257 // Clear in-memory cache for carrier app config, so when carrier app gets 258 // uninstalled, no stale config is left. 259 if (mConfigFromCarrierApp[phoneId] != null 260 && getCarrierPackageForPhoneId(phoneId) == null) { 261 mConfigFromCarrierApp[phoneId] = null; 262 } 263 // Restore persistent override values. 264 PersistableBundle config = restoreConfigFromXml( 265 mPlatformCarrierConfigPackage, OVERRIDE_PACKAGE_ADDITION, phoneId); 266 if (config != null) { 267 logd("Loaded persistent override config from XML. package=" 268 + mPlatformCarrierConfigPackage 269 + " phoneId=" + phoneId); 270 mPersistentOverrideConfigs[phoneId] = config; 271 } 272 273 config = restoreConfigFromXml(mPlatformCarrierConfigPackage, "", phoneId); 274 if (config != null) { 275 logd( 276 "Loaded config from XML. package=" 277 + mPlatformCarrierConfigPackage 278 + " phoneId=" 279 + phoneId); 280 mConfigFromDefaultApp[phoneId] = config; 281 Message newMsg = obtainMessage(EVENT_FETCH_DEFAULT_DONE, phoneId, -1); 282 newMsg.getData().putBoolean("loaded_from_xml", true); 283 mHandler.sendMessage(newMsg); 284 } else { 285 // No cached config, so fetch it from the default app. 286 if (bindToConfigPackage( 287 mPlatformCarrierConfigPackage, 288 phoneId, 289 EVENT_CONNECTED_TO_DEFAULT)) { 290 sendMessageDelayed( 291 obtainMessage(EVENT_BIND_DEFAULT_TIMEOUT, phoneId, -1 /*arg2*/, 292 getMessageToken(phoneId)), 293 BIND_TIMEOUT_MILLIS); 294 } else { 295 // Put a stub bundle in place so that the rest of the logic continues 296 // smoothly. 297 mConfigFromDefaultApp[phoneId] = new PersistableBundle(); 298 // Send broadcast if bind fails. 299 notifySubscriptionInfoUpdater(phoneId); 300 // TODO: We *must* call unbindService even if bindService returns false. 301 // (And possibly if SecurityException was thrown.) 302 loge("binding to default app: " 303 + mPlatformCarrierConfigPackage + " fails"); 304 } 305 } 306 break; 307 } 308 309 case EVENT_CONNECTED_TO_DEFAULT: { 310 removeMessages(EVENT_BIND_DEFAULT_TIMEOUT, getMessageToken(phoneId)); 311 final CarrierServiceConnection conn = (CarrierServiceConnection) msg.obj; 312 // If new service connection has been created, unbind. 313 if (mServiceConnection[phoneId] != conn || conn.service == null) { 314 unbindIfBound(mContext, conn, phoneId); 315 break; 316 } 317 final CarrierIdentifier carrierId = getCarrierIdentifierForPhoneId(phoneId); 318 // ResultReceiver callback will execute in this Handler's thread. 319 final ResultReceiver resultReceiver = 320 new ResultReceiver(this) { 321 @Override 322 public void onReceiveResult(int resultCode, Bundle resultData) { 323 unbindIfBound(mContext, conn, phoneId); 324 removeMessages(EVENT_FETCH_DEFAULT_TIMEOUT, 325 getMessageToken(phoneId)); 326 // If new service connection has been created, this is stale. 327 if (mServiceConnection[phoneId] != conn) { 328 loge("Received response for stale request."); 329 return; 330 } 331 if (resultCode == RESULT_ERROR || resultData == null) { 332 // On error, abort config fetching. 333 loge("Failed to get carrier config"); 334 notifySubscriptionInfoUpdater(phoneId); 335 return; 336 } 337 PersistableBundle config = 338 resultData.getParcelable(KEY_CONFIG_BUNDLE); 339 saveConfigToXml(mPlatformCarrierConfigPackage, "", phoneId, 340 carrierId, config); 341 mConfigFromDefaultApp[phoneId] = config; 342 sendMessage( 343 obtainMessage( 344 EVENT_FETCH_DEFAULT_DONE, phoneId, -1)); 345 } 346 }; 347 // Now fetch the config asynchronously from the ICarrierService. 348 try { 349 ICarrierService carrierService = 350 ICarrierService.Stub.asInterface(conn.service); 351 carrierService.getCarrierConfig(carrierId, resultReceiver); 352 logdWithLocalLog("Fetch config for default app: " 353 + mPlatformCarrierConfigPackage 354 + " carrierid: " + carrierId.toString()); 355 } catch (RemoteException e) { 356 loge("Failed to get carrier config from default app: " + 357 mPlatformCarrierConfigPackage + " err: " + e.toString()); 358 unbindIfBound(mContext, conn, phoneId); 359 break; // So we don't set a timeout. 360 } 361 sendMessageDelayed( 362 obtainMessage(EVENT_FETCH_DEFAULT_TIMEOUT, phoneId, -1 /*arg2*/, 363 getMessageToken(phoneId)), 364 BIND_TIMEOUT_MILLIS); 365 break; 366 } 367 368 case EVENT_BIND_DEFAULT_TIMEOUT: 369 case EVENT_FETCH_DEFAULT_TIMEOUT: { 370 loge("Bind/fetch time out from " + mPlatformCarrierConfigPackage); 371 removeMessages(EVENT_FETCH_DEFAULT_TIMEOUT, getMessageToken(phoneId)); 372 // If we attempted to bind to the app, but the service connection is null due to 373 // the race condition that clear config event happens before bind/fetch complete 374 // then config was cleared while we were waiting and we should not continue. 375 if (mServiceConnection[phoneId] != null) { 376 // If a ResponseReceiver callback is in the queue when this happens, we will 377 // unbind twice and throw an exception. 378 unbindIfBound(mContext, mServiceConnection[phoneId], phoneId); 379 broadcastConfigChangedIntent(phoneId); 380 } 381 // Put a stub bundle in place so that the rest of the logic continues smoothly. 382 mConfigFromDefaultApp[phoneId] = new PersistableBundle(); 383 notifySubscriptionInfoUpdater(phoneId); 384 break; 385 } 386 387 case EVENT_FETCH_DEFAULT_DONE: { 388 // If we attempted to bind to the app, but the service connection is null, then 389 // config was cleared while we were waiting and we should not continue. 390 if (!msg.getData().getBoolean("loaded_from_xml", false) 391 && mServiceConnection[phoneId] == null) { 392 break; 393 } 394 final String carrierPackageName = getCarrierPackageForPhoneId(phoneId); 395 if (carrierPackageName != null) { 396 logd("Found carrier config app: " + carrierPackageName); 397 sendMessage(obtainMessage(EVENT_DO_FETCH_CARRIER, phoneId, -1)); 398 } else { 399 notifySubscriptionInfoUpdater(phoneId); 400 } 401 break; 402 } 403 404 case EVENT_DO_FETCH_CARRIER: { 405 final String carrierPackageName = getCarrierPackageForPhoneId(phoneId); 406 final PersistableBundle config = 407 restoreConfigFromXml(carrierPackageName, "", phoneId); 408 if (config != null) { 409 logd( 410 "Loaded config from XML. package=" 411 + carrierPackageName 412 + " phoneId=" 413 + phoneId); 414 mConfigFromCarrierApp[phoneId] = config; 415 Message newMsg = obtainMessage(EVENT_FETCH_CARRIER_DONE, phoneId, -1); 416 newMsg.getData().putBoolean("loaded_from_xml", true); 417 sendMessage(newMsg); 418 } else { 419 // No cached config, so fetch it from a carrier app. 420 if (carrierPackageName != null && bindToConfigPackage(carrierPackageName, 421 phoneId, EVENT_CONNECTED_TO_CARRIER)) { 422 sendMessageDelayed( 423 obtainMessage(EVENT_BIND_CARRIER_TIMEOUT, phoneId, -1 /*arg2*/, 424 getMessageToken(phoneId)), 425 BIND_TIMEOUT_MILLIS); 426 } else { 427 // Put a stub bundle in place so that the rest of the logic continues 428 // smoothly. 429 mConfigFromCarrierApp[phoneId] = new PersistableBundle(); 430 // Send broadcast if bind fails. 431 broadcastConfigChangedIntent(phoneId); 432 loge("Bind to carrier app: " + carrierPackageName + " fails"); 433 notifySubscriptionInfoUpdater(phoneId); 434 } 435 } 436 break; 437 } 438 439 case EVENT_CONNECTED_TO_CARRIER: { 440 removeMessages(EVENT_BIND_CARRIER_TIMEOUT, getMessageToken(phoneId)); 441 final CarrierServiceConnection conn = (CarrierServiceConnection) msg.obj; 442 // If new service connection has been created, unbind. 443 if (mServiceConnection[phoneId] != conn || conn.service == null) { 444 unbindIfBound(mContext, conn, phoneId); 445 break; 446 } 447 final CarrierIdentifier carrierId = getCarrierIdentifierForPhoneId(phoneId); 448 // ResultReceiver callback will execute in this Handler's thread. 449 final ResultReceiver resultReceiver = 450 new ResultReceiver(this) { 451 @Override 452 public void onReceiveResult(int resultCode, Bundle resultData) { 453 unbindIfBound(mContext, conn, phoneId); 454 removeMessages(EVENT_FETCH_CARRIER_TIMEOUT, 455 getMessageToken(phoneId)); 456 // If new service connection has been created, this is stale. 457 if (mServiceConnection[phoneId] != conn) { 458 loge("Received response for stale request."); 459 return; 460 } 461 if (resultCode == RESULT_ERROR || resultData == null) { 462 // On error, abort config fetching. 463 loge("Failed to get carrier config from carrier app: " 464 + getCarrierPackageForPhoneId(phoneId)); 465 broadcastConfigChangedIntent(phoneId); 466 notifySubscriptionInfoUpdater(phoneId); 467 return; 468 } 469 PersistableBundle config = 470 resultData.getParcelable(KEY_CONFIG_BUNDLE); 471 saveConfigToXml(getCarrierPackageForPhoneId(phoneId), "", 472 phoneId, carrierId, config); 473 if (config != null) { 474 mConfigFromCarrierApp[phoneId] = config; 475 } else { 476 logdWithLocalLog("Config from carrier app is null " 477 + "for phoneId " + phoneId); 478 // Put a stub bundle in place so that the rest of the logic 479 // continues smoothly. 480 mConfigFromCarrierApp[phoneId] = new PersistableBundle(); 481 } 482 sendMessage( 483 obtainMessage( 484 EVENT_FETCH_CARRIER_DONE, phoneId, -1)); 485 } 486 }; 487 // Now fetch the config asynchronously from the ICarrierService. 488 try { 489 ICarrierService carrierService = 490 ICarrierService.Stub.asInterface(conn.service); 491 carrierService.getCarrierConfig(carrierId, resultReceiver); 492 logdWithLocalLog("Fetch config for carrier app: " 493 + getCarrierPackageForPhoneId(phoneId) 494 + " carrierid: " + carrierId.toString()); 495 } catch (RemoteException e) { 496 loge("Failed to get carrier config: " + e.toString()); 497 unbindIfBound(mContext, conn, phoneId); 498 break; // So we don't set a timeout. 499 } 500 sendMessageDelayed( 501 obtainMessage(EVENT_FETCH_CARRIER_TIMEOUT, phoneId, -1 /*arg2*/, 502 getMessageToken(phoneId)), 503 BIND_TIMEOUT_MILLIS); 504 break; 505 } 506 507 case EVENT_BIND_CARRIER_TIMEOUT: 508 case EVENT_FETCH_CARRIER_TIMEOUT: { 509 loge("Bind/fetch from carrier app timeout, package=" 510 + getCarrierPackageForPhoneId(phoneId)); 511 removeMessages(EVENT_FETCH_CARRIER_TIMEOUT, getMessageToken(phoneId)); 512 // If we attempted to bind to the app, but the service connection is null due to 513 // the race condition that clear config event happens before bind/fetch complete 514 // then config was cleared while we were waiting and we should not continue. 515 if (mServiceConnection[phoneId] != null) { 516 // If a ResponseReceiver callback is in the queue when this happens, we will 517 // unbind twice and throw an exception. 518 unbindIfBound(mContext, mServiceConnection[phoneId], phoneId); 519 broadcastConfigChangedIntent(phoneId); 520 } 521 // Put a stub bundle in place so that the rest of the logic continues smoothly. 522 mConfigFromCarrierApp[phoneId] = new PersistableBundle(); 523 notifySubscriptionInfoUpdater(phoneId); 524 break; 525 } 526 case EVENT_FETCH_CARRIER_DONE: { 527 // If we attempted to bind to the app, but the service connection is null, then 528 // config was cleared while we were waiting and we should not continue. 529 if (!msg.getData().getBoolean("loaded_from_xml", false) 530 && mServiceConnection[phoneId] == null) { 531 break; 532 } 533 notifySubscriptionInfoUpdater(phoneId); 534 break; 535 } 536 537 case EVENT_CHECK_SYSTEM_UPDATE: { 538 SharedPreferences sharedPrefs = 539 PreferenceManager.getDefaultSharedPreferences(mContext); 540 final String lastFingerprint = sharedPrefs.getString(KEY_FINGERPRINT, null); 541 if (!Build.FINGERPRINT.equals(lastFingerprint)) { 542 logd( 543 "Build fingerprint changed. old: " 544 + lastFingerprint 545 + " new: " 546 + Build.FINGERPRINT); 547 clearCachedConfigForPackage(null); 548 sharedPrefs 549 .edit() 550 .putString(KEY_FINGERPRINT, Build.FINGERPRINT) 551 .apply(); 552 } 553 break; 554 } 555 556 case EVENT_SUBSCRIPTION_INFO_UPDATED: 557 broadcastConfigChangedIntent(phoneId); 558 break; 559 case EVENT_MULTI_SIM_CONFIG_CHANGED: 560 onMultiSimConfigChanged(); 561 break; 562 563 case EVENT_DO_FETCH_DEFAULT_FOR_NO_SIM_CONFIG: { 564 PersistableBundle config = 565 restoreNoSimConfigFromXml(mPlatformCarrierConfigPackage); 566 567 if (config != null) { 568 logd("Loaded no SIM config from XML. package=" 569 + mPlatformCarrierConfigPackage); 570 mNoSimConfig = config; 571 sendMessage( 572 obtainMessage( 573 EVENT_FETCH_DEFAULT_FOR_NO_SIM_CONFIG_DONE, 574 phoneId, -1)); 575 } else { 576 // No cached config, so fetch it from the default app. 577 if (bindToConfigPackage( 578 mPlatformCarrierConfigPackage, 579 phoneId, 580 EVENT_CONNECTED_TO_DEFAULT_FOR_NO_SIM_CONFIG)) { 581 sendMessageDelayed( 582 obtainMessage( 583 EVENT_BIND_DEFAULT_FOR_NO_SIM_CONFIG_TIMEOUT, 584 phoneId, -1), BIND_TIMEOUT_MILLIS); 585 } else { 586 broadcastConfigChangedIntent(phoneId, false); 587 // TODO: We *must* call unbindService even if bindService returns false. 588 // (And possibly if SecurityException was thrown.) 589 loge("binding to default app to fetch no SIM config: " 590 + mPlatformCarrierConfigPackage + " fails"); 591 } 592 } 593 break; 594 } 595 596 case EVENT_FETCH_DEFAULT_FOR_NO_SIM_CONFIG_DONE: { 597 broadcastConfigChangedIntent(phoneId, false); 598 break; 599 } 600 601 case EVENT_BIND_DEFAULT_FOR_NO_SIM_CONFIG_TIMEOUT: 602 case EVENT_FETCH_DEFAULT_FOR_NO_SIM_CONFIG_TIMEOUT: { 603 loge("Bind/fetch time out for no SIM config from " 604 + mPlatformCarrierConfigPackage); 605 removeMessages(EVENT_FETCH_DEFAULT_FOR_NO_SIM_CONFIG_TIMEOUT); 606 // If we attempted to bind to the app, but the service connection is null due to 607 // the race condition that clear config event happens before bind/fetch complete 608 // then config was cleared while we were waiting and we should not continue. 609 if (mServiceConnectionForNoSimConfig[phoneId] != null) { 610 // If a ResponseReceiver callback is in the queue when this happens, we will 611 // unbind twice and throw an exception. 612 unbindIfBoundForNoSimConfig(mContext, 613 mServiceConnectionForNoSimConfig[phoneId], phoneId); 614 } 615 broadcastConfigChangedIntent(phoneId, false); 616 break; 617 } 618 619 case EVENT_CONNECTED_TO_DEFAULT_FOR_NO_SIM_CONFIG: { 620 removeMessages(EVENT_BIND_DEFAULT_FOR_NO_SIM_CONFIG_TIMEOUT); 621 final CarrierServiceConnection conn = (CarrierServiceConnection) msg.obj; 622 // If new service connection has been created, unbind. 623 if (mServiceConnectionForNoSimConfig[phoneId] != conn || conn.service == null) { 624 unbindIfBoundForNoSimConfig(mContext, conn, phoneId); 625 break; 626 } 627 628 // ResultReceiver callback will execute in this Handler's thread. 629 final ResultReceiver resultReceiver = 630 new ResultReceiver(this) { 631 @Override 632 public void onReceiveResult(int resultCode, Bundle resultData) { 633 unbindIfBoundForNoSimConfig(mContext, conn, phoneId); 634 // If new service connection has been created, this is stale. 635 if (mServiceConnectionForNoSimConfig[phoneId] != conn) { 636 loge("Received response for stale request."); 637 return; 638 } 639 removeMessages(EVENT_FETCH_DEFAULT_FOR_NO_SIM_CONFIG_TIMEOUT); 640 if (resultCode == RESULT_ERROR || resultData == null) { 641 // On error, abort config fetching. 642 loge("Failed to get no SIM carrier config"); 643 return; 644 } 645 PersistableBundle config = 646 resultData.getParcelable(KEY_CONFIG_BUNDLE); 647 saveNoSimConfigToXml(mPlatformCarrierConfigPackage, config); 648 mNoSimConfig = config; 649 sendMessage( 650 obtainMessage( 651 EVENT_FETCH_DEFAULT_FOR_NO_SIM_CONFIG_DONE, 652 phoneId, -1)); 653 } 654 }; 655 // Now fetch the config asynchronously from the ICarrierService. 656 try { 657 ICarrierService carrierService = 658 ICarrierService.Stub.asInterface(conn.service); 659 carrierService.getCarrierConfig(null, resultReceiver); 660 logdWithLocalLog("Fetch no sim config from default app: " 661 + mPlatformCarrierConfigPackage); 662 } catch (RemoteException e) { 663 loge("Failed to get no sim carrier config from default app: " + 664 mPlatformCarrierConfigPackage + " err: " + e.toString()); 665 unbindIfBoundForNoSimConfig(mContext, conn, phoneId); 666 break; // So we don't set a timeout. 667 } 668 sendMessageDelayed( 669 obtainMessage( 670 EVENT_FETCH_DEFAULT_FOR_NO_SIM_CONFIG_TIMEOUT, 671 phoneId, -1), BIND_TIMEOUT_MILLIS); 672 break; 673 } 674 } 675 } 676 } 677 678 private final Handler mHandler; 679 680 /** 681 * Constructs a CarrierConfigLoader, registers it as a service, and registers a broadcast 682 * receiver for relevant events. 683 */ 684 @VisibleForTesting CarrierConfigLoader(Context context, SubscriptionInfoUpdater subscriptionInfoUpdater, @NonNull Looper looper)685 /* package */ CarrierConfigLoader(Context context, 686 SubscriptionInfoUpdater subscriptionInfoUpdater, @NonNull Looper looper) { 687 mContext = context; 688 mPlatformCarrierConfigPackage = 689 mContext.getString(R.string.platform_carrier_config_package); 690 mHandler = new ConfigHandler(looper); 691 692 IntentFilter bootFilter = new IntentFilter(); 693 bootFilter.addAction(Intent.ACTION_BOOT_COMPLETED); 694 context.registerReceiver(mBootReceiver, bootFilter); 695 696 // Register for package updates. Update app or uninstall app update will have all 3 intents, 697 // in the order or removed, added, replaced, all with extra_replace set to true. 698 IntentFilter pkgFilter = new IntentFilter(); 699 pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 700 pkgFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 701 pkgFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); 702 pkgFilter.addDataScheme("package"); 703 context.registerReceiver(mPackageReceiver, pkgFilter); 704 705 int numPhones = TelephonyManager.from(context).getSupportedModemCount(); 706 mConfigFromDefaultApp = new PersistableBundle[numPhones]; 707 mConfigFromCarrierApp = new PersistableBundle[numPhones]; 708 mPersistentOverrideConfigs = new PersistableBundle[numPhones]; 709 mOverrideConfigs = new PersistableBundle[numPhones]; 710 mNoSimConfig = new PersistableBundle(); 711 mServiceConnection = new CarrierServiceConnection[numPhones]; 712 mServiceBound = new boolean[numPhones]; 713 mHasSentConfigChange = new boolean[numPhones]; 714 mFromSystemUnlocked = new boolean[numPhones]; 715 mServiceConnectionForNoSimConfig = new CarrierServiceConnection[numPhones]; 716 mServiceBoundForNoSimConfig = new boolean[numPhones]; 717 logd("CarrierConfigLoader has started"); 718 mSubscriptionInfoUpdater = subscriptionInfoUpdater; 719 mHandler.sendEmptyMessage(EVENT_CHECK_SYSTEM_UPDATE); 720 } 721 722 /** 723 * Initialize the singleton CarrierConfigLoader instance. 724 * 725 * This is only done once, at startup, from {@link com.android.phone.PhoneApp#onCreate}. 726 */ init(Context context)727 /* package */ static CarrierConfigLoader init(Context context) { 728 synchronized (CarrierConfigLoader.class) { 729 if (sInstance == null) { 730 sInstance = new CarrierConfigLoader(context, 731 PhoneFactory.getSubscriptionInfoUpdater(), Looper.myLooper()); 732 // Make this service available through ServiceManager. 733 TelephonyFrameworkInitializer.getTelephonyServiceManager() 734 .getCarrierConfigServiceRegisterer().register(sInstance); 735 } else { 736 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); 737 } 738 return sInstance; 739 } 740 } 741 742 @VisibleForTesting clearConfigForPhone(int phoneId, boolean fetchNoSimConfig)743 /* package */ void clearConfigForPhone(int phoneId, boolean fetchNoSimConfig) { 744 /* Ignore clear configuration request if device is being shutdown. */ 745 Phone phone = PhoneFactory.getPhone(phoneId); 746 if (phone != null) { 747 if (phone.isShuttingDown()) { 748 return; 749 } 750 } 751 752 mConfigFromDefaultApp[phoneId] = null; 753 mConfigFromCarrierApp[phoneId] = null; 754 mServiceConnection[phoneId] = null; 755 mHasSentConfigChange[phoneId] = false; 756 757 if (fetchNoSimConfig) { 758 // To fetch no SIM config 759 mHandler.sendMessage( 760 mHandler.obtainMessage( 761 EVENT_DO_FETCH_DEFAULT_FOR_NO_SIM_CONFIG, phoneId, -1)); 762 } 763 } 764 notifySubscriptionInfoUpdater(int phoneId)765 private void notifySubscriptionInfoUpdater(int phoneId) { 766 String configPackagename; 767 PersistableBundle configToSend; 768 int carrierId = getSpecificCarrierIdForPhoneId(phoneId); 769 // Prefer the carrier privileged carrier app, but if there is not one, use the platform 770 // default carrier app. 771 if (mConfigFromCarrierApp[phoneId] != null) { 772 configPackagename = getCarrierPackageForPhoneId(phoneId); 773 configToSend = mConfigFromCarrierApp[phoneId]; 774 } else { 775 configPackagename = mPlatformCarrierConfigPackage; 776 configToSend = mConfigFromDefaultApp[phoneId]; 777 } 778 779 if (configToSend == null) { 780 configToSend = new PersistableBundle(); 781 } 782 783 // mOverrideConfigs is for testing. And it will override current configs. 784 PersistableBundle config = mOverrideConfigs[phoneId]; 785 if (config != null) { 786 configToSend = new PersistableBundle(configToSend); 787 configToSend.putAll(config); 788 } 789 790 mSubscriptionInfoUpdater.updateSubscriptionByCarrierConfigAndNotifyComplete( 791 phoneId, configPackagename, configToSend, 792 mHandler.obtainMessage(EVENT_SUBSCRIPTION_INFO_UPDATED, phoneId, -1)); 793 } 794 broadcastConfigChangedIntent(int phoneId)795 private void broadcastConfigChangedIntent(int phoneId) { 796 broadcastConfigChangedIntent(phoneId, true); 797 } 798 broadcastConfigChangedIntent(int phoneId, boolean addSubIdExtra)799 private void broadcastConfigChangedIntent(int phoneId, boolean addSubIdExtra) { 800 Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); 801 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | 802 Intent.FLAG_RECEIVER_FOREGROUND); 803 if (addSubIdExtra) { 804 int simApplicationState = TelephonyManager.SIM_STATE_UNKNOWN; 805 int[] subIds = SubscriptionManager.getSubId(phoneId); 806 if (!ArrayUtils.isEmpty(subIds)) { 807 TelephonyManager telMgr = TelephonyManager.from(mContext) 808 .createForSubscriptionId(subIds[0]); 809 simApplicationState = telMgr.getSimApplicationState(); 810 } 811 logd("Broadcast CARRIER_CONFIG_CHANGED for phone " + phoneId 812 + " simApplicationState " + simApplicationState); 813 // Include subId/carrier id extra only if SIM records are loaded 814 if (simApplicationState != TelephonyManager.SIM_STATE_UNKNOWN 815 && simApplicationState != TelephonyManager.SIM_STATE_NOT_READY) { 816 SubscriptionManager.putPhoneIdAndSubIdExtra(intent, phoneId); 817 intent.putExtra(TelephonyManager.EXTRA_SPECIFIC_CARRIER_ID, 818 getSpecificCarrierIdForPhoneId(phoneId)); 819 intent.putExtra(TelephonyManager.EXTRA_CARRIER_ID, getCarrierIdForPhoneId(phoneId)); 820 } 821 } 822 intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, phoneId); 823 intent.putExtra(CarrierConfigManager.EXTRA_REBROADCAST_ON_UNLOCK, 824 mFromSystemUnlocked[phoneId]); 825 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 826 int[] subIds = SubscriptionManager.getSubId(phoneId); 827 if (subIds != null && subIds.length > 0) { 828 logd("Broadcast CARRIER_CONFIG_CHANGED for phone " + phoneId + ", subId=" + subIds[0]); 829 } else { 830 logd("Broadcast CARRIER_CONFIG_CHANGED for phone " + phoneId); 831 } 832 mHasSentConfigChange[phoneId] = true; 833 mFromSystemUnlocked[phoneId] = false; 834 } 835 836 /** Binds to the default or carrier config app. */ bindToConfigPackage(String pkgName, int phoneId, int eventId)837 private boolean bindToConfigPackage(String pkgName, int phoneId, int eventId) { 838 logdWithLocalLog("Binding to " + pkgName + " for phone " + phoneId); 839 Intent carrierService = new Intent(CarrierService.CARRIER_SERVICE_INTERFACE); 840 carrierService.setPackage(pkgName); 841 CarrierServiceConnection serviceConnection = new CarrierServiceConnection( 842 phoneId, pkgName, eventId); 843 if (eventId == EVENT_CONNECTED_TO_DEFAULT_FOR_NO_SIM_CONFIG) { 844 mServiceConnectionForNoSimConfig[phoneId] = serviceConnection; 845 } else { 846 mServiceConnection[phoneId] = serviceConnection; 847 } 848 try { 849 if (mContext.bindService(carrierService, serviceConnection, 850 Context.BIND_AUTO_CREATE)) { 851 if (eventId == EVENT_CONNECTED_TO_DEFAULT_FOR_NO_SIM_CONFIG) { 852 mServiceBoundForNoSimConfig[phoneId] = true; 853 } else { 854 mServiceBound[phoneId] = true; 855 } 856 return true; 857 } else { 858 return false; 859 } 860 } catch (SecurityException ex) { 861 return false; 862 } 863 } 864 865 @VisibleForTesting getCarrierIdentifierForPhoneId(int phoneId)866 /* package */ CarrierIdentifier getCarrierIdentifierForPhoneId(int phoneId) { 867 String mcc = ""; 868 String mnc = ""; 869 String imsi = ""; 870 String gid1 = ""; 871 String gid2 = ""; 872 String spn = TelephonyManager.from(mContext).getSimOperatorNameForPhone(phoneId); 873 String simOperator = TelephonyManager.from(mContext).getSimOperatorNumericForPhone(phoneId); 874 int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID; 875 int specificCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; 876 // A valid simOperator should be 5 or 6 digits, depending on the length of the MNC. 877 if (simOperator != null && simOperator.length() >= 3) { 878 mcc = simOperator.substring(0, 3); 879 mnc = simOperator.substring(3); 880 } 881 Phone phone = PhoneFactory.getPhone(phoneId); 882 if (phone != null) { 883 imsi = phone.getSubscriberId(); 884 gid1 = phone.getGroupIdLevel1(); 885 gid2 = phone.getGroupIdLevel2(); 886 carrierId = phone.getCarrierId(); 887 specificCarrierId = phone.getSpecificCarrierId(); 888 } 889 return new CarrierIdentifier(mcc, mnc, spn, imsi, gid1, gid2, carrierId, specificCarrierId); 890 } 891 892 /** Returns the package name of a priveleged carrier app, or null if there is none. */ 893 @Nullable getCarrierPackageForPhoneId(int phoneId)894 private String getCarrierPackageForPhoneId(int phoneId) { 895 List<String> carrierPackageNames; 896 final long token = Binder.clearCallingIdentity(); 897 try { 898 carrierPackageNames = TelephonyManager.from(mContext) 899 .getCarrierPackageNamesForIntentAndPhone( 900 new Intent(CarrierService.CARRIER_SERVICE_INTERFACE), phoneId); 901 } finally { 902 Binder.restoreCallingIdentity(token); 903 } 904 if (carrierPackageNames != null && carrierPackageNames.size() > 0) { 905 return carrierPackageNames.get(0); 906 } else { 907 return null; 908 } 909 } 910 getIccIdForPhoneId(int phoneId)911 private String getIccIdForPhoneId(int phoneId) { 912 if (!SubscriptionManager.isValidPhoneId(phoneId)) { 913 return null; 914 } 915 Phone phone = PhoneFactory.getPhone(phoneId); 916 if (phone == null) { 917 return null; 918 } 919 return phone.getIccSerialNumber(); 920 } 921 922 /** 923 * Get the sim specific carrier id {@link TelephonyManager#getSimSpecificCarrierId()} 924 */ getSpecificCarrierIdForPhoneId(int phoneId)925 private int getSpecificCarrierIdForPhoneId(int phoneId) { 926 if (!SubscriptionManager.isValidPhoneId(phoneId)) { 927 return TelephonyManager.UNKNOWN_CARRIER_ID; 928 } 929 Phone phone = PhoneFactory.getPhone(phoneId); 930 if (phone == null) { 931 return TelephonyManager.UNKNOWN_CARRIER_ID; 932 } 933 return phone.getSpecificCarrierId(); 934 } 935 936 /** 937 * Get the sim carrier id {@link TelephonyManager#getSimCarrierId() } 938 */ getCarrierIdForPhoneId(int phoneId)939 private int getCarrierIdForPhoneId(int phoneId) { 940 if (!SubscriptionManager.isValidPhoneId(phoneId)) { 941 return TelephonyManager.UNKNOWN_CARRIER_ID; 942 } 943 Phone phone = PhoneFactory.getPhone(phoneId); 944 if (phone == null) { 945 return TelephonyManager.UNKNOWN_CARRIER_ID; 946 } 947 return phone.getCarrierId(); 948 } 949 950 /** 951 * Writes a bundle to an XML file. 952 * 953 * The bundle will be written to a file named after the package name, ICCID and 954 * specific carrier id {@link TelephonyManager#getSimSpecificCarrierId()}. the same carrier 955 * should have a single copy of XML file named after carrier id. However, it's still possible 956 * that platform doesn't recognize the current sim carrier, we will use iccid + carrierid as 957 * the canonical file name. carrierid can also handle the cases SIM OTA resolves to different 958 * carrier while iccid remains the same. 959 * 960 * The file can be restored later with {@link @restoreConfigFromXml}. The XML output will 961 * include the bundle and the current version of the specified package. 962 * 963 * In case of errors or invalid input, no file will be written. 964 * 965 * @param packageName the name of the package from which we fetched this bundle. 966 * @param extraString An extra string to be used in the XML file name. 967 * @param phoneId the phone ID. 968 * @param carrierId contains all carrier-identifying information. 969 * @param config the bundle to be written. Null will be treated as an empty bundle. 970 * @param isNoSimConfig whether this is invoked for noSimConfig or not. 971 */ saveConfigToXml(String packageName, @NonNull String extraString, int phoneId, CarrierIdentifier carrierId, PersistableBundle config, boolean isNoSimConfig)972 private void saveConfigToXml(String packageName, @NonNull String extraString, int phoneId, 973 CarrierIdentifier carrierId, PersistableBundle config, boolean isNoSimConfig) { 974 if (packageName == null) { 975 loge("Cannot save config with null packageName"); 976 return; 977 } 978 979 String fileName; 980 if (isNoSimConfig) { 981 fileName = getFilenameForNoSimConfig(packageName); 982 } else { 983 if (SubscriptionManager.getSimStateForSlotIndex(phoneId) 984 != TelephonyManager.SIM_STATE_LOADED) { 985 loge("Skip save config because SIM records are not loaded."); 986 return; 987 } 988 989 final String iccid = getIccIdForPhoneId(phoneId); 990 final int cid = carrierId.getSpecificCarrierId(); 991 if (iccid == null) { 992 loge("Cannot save config with null iccid."); 993 return; 994 } 995 fileName = getFilenameForConfig(packageName, extraString, iccid, cid); 996 } 997 998 // b/32668103 Only save to file if config isn't empty. 999 // In case of failure, not caching an empty bundle will 1000 // try loading config again on next power on or sim loaded. 1001 // Downside is for genuinely empty bundle, will bind and load 1002 // on every power on. 1003 if (config == null || config.isEmpty()) { 1004 return; 1005 } 1006 1007 final String version = getPackageVersion(packageName); 1008 if (version == null) { 1009 loge("Failed to get package version for: " + packageName); 1010 return; 1011 } 1012 1013 logdWithLocalLog( 1014 "Save config to xml, packagename: " + packageName + " phoneId: " + phoneId); 1015 1016 FileOutputStream outFile = null; 1017 try { 1018 outFile = new FileOutputStream(new File(mContext.getFilesDir(), fileName)); 1019 config.putString(KEY_VERSION, version); 1020 config.writeToStream(outFile); 1021 outFile.flush(); 1022 outFile.close(); 1023 } catch (IOException e) { 1024 loge(e.toString()); 1025 } 1026 } 1027 1028 @VisibleForTesting saveConfigToXml(String packageName, @NonNull String extraString, int phoneId, CarrierIdentifier carrierId, PersistableBundle config)1029 /* package */ void saveConfigToXml(String packageName, @NonNull String extraString, int phoneId, 1030 CarrierIdentifier carrierId, PersistableBundle config) { 1031 saveConfigToXml(packageName, extraString, phoneId, carrierId, config, false); 1032 } 1033 1034 @VisibleForTesting saveNoSimConfigToXml(String packageName, PersistableBundle config)1035 /* package */ void saveNoSimConfigToXml(String packageName, PersistableBundle config) { 1036 saveConfigToXml(packageName, "", -1, null, config, true); 1037 } 1038 1039 /** 1040 * Reads a bundle from an XML file. 1041 * 1042 * This restores a bundle that was written with {@link #saveConfigToXml}. This returns the saved 1043 * config bundle for the given package and phone ID. 1044 * 1045 * In case of errors, or if the saved config is from a different package version than the 1046 * current version, then null will be returned. 1047 * 1048 * @param packageName the name of the package from which we fetched this bundle. 1049 * @param extraString An extra string to be used in the XML file name. 1050 * @param phoneId the phone ID. 1051 * @param isNoSimConfig whether this is invoked for noSimConfig or not. 1052 * @return the bundle from the XML file. Returns null if there is no saved config, the saved 1053 * version does not match, or reading config fails. 1054 */ restoreConfigFromXml(String packageName, @NonNull String extraString, int phoneId, boolean isNoSimConfig)1055 private PersistableBundle restoreConfigFromXml(String packageName, @NonNull String extraString, 1056 int phoneId, boolean isNoSimConfig) { 1057 if (packageName == null) { 1058 loge("Cannot restore config with null packageName"); 1059 } 1060 final String version = getPackageVersion(packageName); 1061 if (version == null) { 1062 loge("Failed to get package version for: " + packageName); 1063 return null; 1064 } 1065 1066 String fileName; 1067 if (isNoSimConfig) { 1068 fileName = getFilenameForNoSimConfig(packageName); 1069 } else { 1070 if (SubscriptionManager.getSimStateForSlotIndex(phoneId) 1071 != TelephonyManager.SIM_STATE_LOADED) { 1072 loge("Skip restore config because SIM records are not loaded."); 1073 return null; 1074 } 1075 1076 final String iccid = getIccIdForPhoneId(phoneId); 1077 final int cid = getSpecificCarrierIdForPhoneId(phoneId); 1078 if (iccid == null) { 1079 loge("Cannot restore config with null iccid."); 1080 return null; 1081 } 1082 fileName = getFilenameForConfig(packageName, extraString, iccid, cid); 1083 } 1084 1085 PersistableBundle restoredBundle = null; 1086 File file = null; 1087 FileInputStream inFile = null; 1088 try { 1089 file = new File(mContext.getFilesDir(),fileName); 1090 inFile = new FileInputStream(file); 1091 1092 restoredBundle = PersistableBundle.readFromStream(inFile); 1093 String savedVersion = restoredBundle.getString(KEY_VERSION); 1094 restoredBundle.remove(KEY_VERSION); 1095 1096 if (!version.equals(savedVersion)) { 1097 loge("Saved version mismatch: " + version + " vs " + savedVersion); 1098 restoredBundle = null; 1099 } 1100 1101 inFile.close(); 1102 } catch (FileNotFoundException e) { 1103 // Missing file is normal occurrence that might occur with a new sim or when restoring 1104 // an override file during boot and should not be treated as an error. 1105 if (file != null) logd("File not found: " + file.getPath()); 1106 } catch (IOException e) { 1107 loge(e.toString()); 1108 } 1109 1110 return restoredBundle; 1111 } 1112 restoreConfigFromXml(String packageName, @NonNull String extraString, int phoneId)1113 private PersistableBundle restoreConfigFromXml(String packageName, @NonNull String extraString, 1114 int phoneId) { 1115 return restoreConfigFromXml(packageName, extraString, phoneId, false); 1116 } 1117 restoreNoSimConfigFromXml(String packageName)1118 private PersistableBundle restoreNoSimConfigFromXml(String packageName) { 1119 return restoreConfigFromXml(packageName, "", -1, true); 1120 } 1121 1122 /** 1123 * Clears cached carrier config. 1124 * This deletes all saved XML files associated with the given package name. If packageName is 1125 * null, then it deletes all saved XML files. 1126 * 1127 * @param packageName the name of a carrier package, or null if all cached config should be 1128 * cleared. 1129 * @return true iff one or more files were deleted. 1130 */ clearCachedConfigForPackage(final String packageName)1131 private boolean clearCachedConfigForPackage(final String packageName) { 1132 File dir = mContext.getFilesDir(); 1133 File[] packageFiles = dir.listFiles(new FilenameFilter() { 1134 public boolean accept(File dir, String filename) { 1135 if (packageName != null) { 1136 return filename.startsWith("carrierconfig-" + packageName + "-"); 1137 } else { 1138 return filename.startsWith("carrierconfig-"); 1139 } 1140 } 1141 }); 1142 if (packageFiles == null || packageFiles.length < 1) return false; 1143 for (File f : packageFiles) { 1144 logd("Deleting " + f.getName()); 1145 f.delete(); 1146 } 1147 return true; 1148 } 1149 1150 /** Builds a canonical file name for a config file. */ getFilenameForConfig( @onNull String packageName, @NonNull String extraString, @NonNull String iccid, int cid)1151 private static String getFilenameForConfig( 1152 @NonNull String packageName, @NonNull String extraString, 1153 @NonNull String iccid, int cid) { 1154 // the same carrier should have a single copy of XML file named after carrier id. 1155 // However, it's still possible that platform doesn't recognize the current sim carrier, 1156 // we will use iccid + carrierid as the canonical file name. carrierid can also handle the 1157 // cases SIM OTA resolves to different carrier while iccid remains the same. 1158 return "carrierconfig-" + packageName + extraString + "-" + iccid + "-" + cid + ".xml"; 1159 } 1160 1161 /** Builds a canonical file name for no SIM config file. */ getFilenameForNoSimConfig(@onNull String packageName)1162 private String getFilenameForNoSimConfig(@NonNull String packageName) { 1163 return "carrierconfig-" + packageName + "-" + "nosim" + ".xml"; 1164 } 1165 1166 /** Return the current version code of a package, or null if the name is not found. */ getPackageVersion(String packageName)1167 private String getPackageVersion(String packageName) { 1168 try { 1169 PackageInfo info = mContext.getPackageManager().getPackageInfo(packageName, 0); 1170 return Long.toString(info.getLongVersionCode()); 1171 } catch (PackageManager.NameNotFoundException e) { 1172 return null; 1173 } 1174 } 1175 1176 /** 1177 * Read up to date config. 1178 * 1179 * This reads config bundles for the given phoneId. That means getting the latest bundle from 1180 * the default app and a privileged carrier app, if present. This will not bind to an app if we 1181 * have a saved config file to use instead. 1182 */ updateConfigForPhoneId(int phoneId)1183 private void updateConfigForPhoneId(int phoneId) { 1184 mHandler.sendMessage(mHandler.obtainMessage(EVENT_DO_FETCH_DEFAULT, phoneId, -1)); 1185 } 1186 onMultiSimConfigChanged()1187 private void onMultiSimConfigChanged() { 1188 for (int i = TelephonyManager.from(mContext).getActiveModemCount(); 1189 i < mConfigFromDefaultApp.length; i++) { 1190 clearConfigForPhone(i, false); 1191 } 1192 } 1193 1194 @Override 1195 @NonNull getConfigForSubId(int subscriptionId, String callingPackage)1196 public PersistableBundle getConfigForSubId(int subscriptionId, String callingPackage) { 1197 return getConfigForSubIdWithFeature(subscriptionId, callingPackage, null); 1198 } 1199 1200 @Override 1201 @NonNull getConfigForSubIdWithFeature(int subscriptionId, String callingPackage, String callingFeatureId)1202 public PersistableBundle getConfigForSubIdWithFeature(int subscriptionId, String callingPackage, 1203 String callingFeatureId) { 1204 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subscriptionId, 1205 callingPackage, callingFeatureId, "getCarrierConfig")) { 1206 return new PersistableBundle(); 1207 } 1208 1209 int phoneId = SubscriptionManager.getPhoneId(subscriptionId); 1210 PersistableBundle retConfig = CarrierConfigManager.getDefaultConfig(); 1211 if (SubscriptionManager.isValidPhoneId(phoneId)) { 1212 PersistableBundle config = mConfigFromDefaultApp[phoneId]; 1213 if (config != null) { 1214 retConfig.putAll(config); 1215 } 1216 config = mConfigFromCarrierApp[phoneId]; 1217 if (config != null) { 1218 retConfig.putAll(config); 1219 } 1220 config = mPersistentOverrideConfigs[phoneId]; 1221 if (config != null) { 1222 retConfig.putAll(config); 1223 } 1224 config = mOverrideConfigs[phoneId]; 1225 if (config != null) { 1226 retConfig.putAll(config); 1227 } 1228 // Ignore the theoretical case of the default app not being present since that won't 1229 // work in CarrierConfigLoader today. 1230 final boolean allConfigsApplied = 1231 (mConfigFromCarrierApp[phoneId] != null 1232 || getCarrierPackageForPhoneId(phoneId) == null) 1233 && mConfigFromDefaultApp[phoneId] != null; 1234 retConfig.putBoolean( 1235 CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, allConfigsApplied); 1236 } else { 1237 if (mNoSimConfig != null) { 1238 retConfig.putAll(mNoSimConfig); 1239 } 1240 } 1241 return retConfig; 1242 } 1243 1244 @Override overrideConfig(int subscriptionId, @Nullable PersistableBundle overrides, boolean persistent)1245 public void overrideConfig(int subscriptionId, @Nullable PersistableBundle overrides, 1246 boolean persistent) { 1247 mContext.enforceCallingOrSelfPermission( 1248 android.Manifest.permission.MODIFY_PHONE_STATE, null); 1249 //TODO: Also check for SHELL UID to restrict this method to testing only (b/131326259) 1250 int phoneId = SubscriptionManager.getPhoneId(subscriptionId); 1251 if (!SubscriptionManager.isValidPhoneId(phoneId)) { 1252 logd("Ignore invalid phoneId: " + phoneId + " for subId: " + subscriptionId); 1253 throw new IllegalArgumentException( 1254 "Invalid phoneId " + phoneId + " for subId " + subscriptionId); 1255 } 1256 // Post to run on handler thread on which all states should be confined. 1257 mHandler.post(() -> { 1258 overrideConfig(mOverrideConfigs, phoneId, overrides); 1259 1260 if (persistent) { 1261 overrideConfig(mPersistentOverrideConfigs, phoneId, overrides); 1262 1263 if (overrides != null) { 1264 final CarrierIdentifier carrierId = getCarrierIdentifierForPhoneId(phoneId); 1265 saveConfigToXml(mPlatformCarrierConfigPackage, OVERRIDE_PACKAGE_ADDITION, 1266 phoneId, 1267 carrierId, mPersistentOverrideConfigs[phoneId]); 1268 } else { 1269 final String iccid = getIccIdForPhoneId(phoneId); 1270 final int cid = getSpecificCarrierIdForPhoneId(phoneId); 1271 String fileName = getFilenameForConfig(mPlatformCarrierConfigPackage, 1272 OVERRIDE_PACKAGE_ADDITION, iccid, cid); 1273 File fileToDelete = new File(mContext.getFilesDir(), fileName); 1274 fileToDelete.delete(); 1275 } 1276 } 1277 notifySubscriptionInfoUpdater(phoneId); 1278 }); 1279 } 1280 overrideConfig(@onNull PersistableBundle[] currentOverrides, int phoneId, @Nullable PersistableBundle overrides)1281 private void overrideConfig(@NonNull PersistableBundle[] currentOverrides, int phoneId, 1282 @Nullable PersistableBundle overrides) { 1283 if (overrides == null) { 1284 currentOverrides[phoneId] = new PersistableBundle(); 1285 } else if (currentOverrides[phoneId] == null) { 1286 currentOverrides[phoneId] = overrides; 1287 } else { 1288 currentOverrides[phoneId].putAll(overrides); 1289 } 1290 } 1291 1292 @Override notifyConfigChangedForSubId(int subscriptionId)1293 public void notifyConfigChangedForSubId(int subscriptionId) { 1294 // Requires the calling app to be either a carrier privileged app for this subId or 1295 // system privileged app with MODIFY_PHONE_STATE permission. 1296 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mContext, 1297 subscriptionId, "Require carrier privileges or MODIFY_PHONE_STATE permission."); 1298 1299 int phoneId = SubscriptionManager.getPhoneId(subscriptionId); 1300 if (!SubscriptionManager.isValidPhoneId(phoneId)) { 1301 logd("Ignore invalid phoneId: " + phoneId + " for subId: " + subscriptionId); 1302 throw new IllegalArgumentException( 1303 "Invalid phoneId " + phoneId + " for subId " + subscriptionId); 1304 } 1305 1306 // This method should block until deleting has completed, so that an error which prevents us 1307 // from clearing the cache is passed back to the carrier app. With the files successfully 1308 // deleted, this can return and we will eventually bind to the carrier app. 1309 String callingPackageName = mContext.getPackageManager().getNameForUid( 1310 Binder.getCallingUid()); 1311 clearCachedConfigForPackage(callingPackageName); 1312 updateConfigForPhoneId(phoneId); 1313 } 1314 1315 @Override updateConfigForPhoneId(int phoneId, String simState)1316 public void updateConfigForPhoneId(int phoneId, String simState) { 1317 mContext.enforceCallingOrSelfPermission( 1318 android.Manifest.permission.MODIFY_PHONE_STATE, null); 1319 logdWithLocalLog("Update config for phoneId: " + phoneId + " simState: " + simState); 1320 if (!SubscriptionManager.isValidPhoneId(phoneId)) { 1321 throw new IllegalArgumentException("Invalid phoneId: " + phoneId); 1322 } 1323 // requires Java 7 for switch on string. 1324 switch (simState) { 1325 case IccCardConstants.INTENT_VALUE_ICC_ABSENT: 1326 case IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR: 1327 case IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED: 1328 case IccCardConstants.INTENT_VALUE_ICC_UNKNOWN: 1329 case IccCardConstants.INTENT_VALUE_ICC_NOT_READY: 1330 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CLEAR_CONFIG, phoneId, -1)); 1331 break; 1332 case IccCardConstants.INTENT_VALUE_ICC_LOADED: 1333 case IccCardConstants.INTENT_VALUE_ICC_LOCKED: 1334 updateConfigForPhoneId(phoneId); 1335 break; 1336 } 1337 } 1338 1339 @Override getDefaultCarrierServicePackageName()1340 public String getDefaultCarrierServicePackageName() { 1341 mContext.enforceCallingOrSelfPermission( 1342 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 1343 "getDefaultCarrierServicePackageName"); 1344 return mPlatformCarrierConfigPackage; 1345 } 1346 1347 @VisibleForTesting getHandler()1348 /* package */ Handler getHandler() { 1349 return mHandler; 1350 } 1351 1352 @VisibleForTesting getConfigFromDefaultApp(int phoneId)1353 /* package */ PersistableBundle getConfigFromDefaultApp(int phoneId) { 1354 return mConfigFromDefaultApp[phoneId]; 1355 } 1356 1357 @VisibleForTesting getConfigFromCarrierApp(int phoneId)1358 /* package */ PersistableBundle getConfigFromCarrierApp(int phoneId) { 1359 return mConfigFromCarrierApp[phoneId]; 1360 } 1361 1362 @VisibleForTesting getNoSimConfig()1363 /* package */ PersistableBundle getNoSimConfig() { 1364 return mNoSimConfig; 1365 } 1366 1367 @VisibleForTesting getOverrideConfig(int phoneId)1368 /* package */ PersistableBundle getOverrideConfig(int phoneId) { 1369 return mOverrideConfigs[phoneId]; 1370 } 1371 unbindIfBound(Context context, CarrierServiceConnection conn, int phoneId)1372 private void unbindIfBound(Context context, CarrierServiceConnection conn, 1373 int phoneId) { 1374 if (mServiceBound[phoneId]) { 1375 mServiceBound[phoneId] = false; 1376 context.unbindService(conn); 1377 } 1378 } 1379 unbindIfBoundForNoSimConfig(Context context, CarrierServiceConnection conn, int phoneId)1380 private void unbindIfBoundForNoSimConfig(Context context, CarrierServiceConnection conn, 1381 int phoneId) { 1382 if (mServiceBoundForNoSimConfig[phoneId]) { 1383 mServiceBoundForNoSimConfig[phoneId] = false; 1384 context.unbindService(conn); 1385 } 1386 } 1387 1388 /** 1389 * Returns a boxed Integer object for phoneId, services as message token to distinguish messages 1390 * with same code when calling {@link Handler#removeMessages(int, Object)}. 1391 */ getMessageToken(int phoneId)1392 private Integer getMessageToken(int phoneId) { 1393 if (phoneId < -128 || phoneId > 127) { 1394 throw new IllegalArgumentException("phoneId should be in range [-128, 127], inclusive"); 1395 } 1396 // Integer#valueOf guarantees the integers within [-128, 127] are cached and thus memory 1397 // comparison (==) returns true for the same integer. 1398 return Integer.valueOf(phoneId); 1399 } 1400 1401 /** 1402 * If {@code args} contains {@link #DUMP_ARG_REQUESTING_PACKAGE} and a following package name, 1403 * we'll also call {@link IBinder#dump} on the default carrier service (if bound) and the 1404 * specified carrier service (if bound). Typically, this is done for connectivity bug reports 1405 * where we don't call {@code dumpsys activity service all-non-platform} because that contains 1406 * too much info, but we still want to let carrier apps include their diagnostics. 1407 */ 1408 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1409 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1410 IndentingPrintWriter indentPW = new IndentingPrintWriter(pw, " "); 1411 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 1412 != PackageManager.PERMISSION_GRANTED) { 1413 indentPW.println("Permission Denial: can't dump carrierconfig from from pid=" 1414 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 1415 return; 1416 } 1417 String requestingPackage = null; 1418 int requestingPackageIndex = ArrayUtils.indexOf(args, DUMP_ARG_REQUESTING_PACKAGE); 1419 if (requestingPackageIndex >= 0 && requestingPackageIndex < args.length - 1 1420 && !TextUtils.isEmpty(args[requestingPackageIndex + 1])) { 1421 requestingPackage = args[requestingPackageIndex + 1]; 1422 // Throws a SecurityException if the caller is impersonating another app in an effort to 1423 // dump extra info (which may contain PII the caller doesn't have a right to). 1424 enforceCallerIsSystemOrRequestingPackage(requestingPackage); 1425 } 1426 1427 indentPW.println("CarrierConfigLoader: " + this); 1428 for (int i = 0; i < TelephonyManager.from(mContext).getActiveModemCount(); i++) { 1429 indentPW.println("Phone Id = " + i); 1430 // display default values in CarrierConfigManager 1431 printConfig(CarrierConfigManager.getDefaultConfig(), indentPW, 1432 "Default Values from CarrierConfigManager"); 1433 // display ConfigFromDefaultApp 1434 printConfig(mConfigFromDefaultApp[i], indentPW, "mConfigFromDefaultApp"); 1435 // display ConfigFromCarrierApp 1436 printConfig(mConfigFromCarrierApp[i], indentPW, "mConfigFromCarrierApp"); 1437 printConfig(mPersistentOverrideConfigs[i], indentPW, "mPersistentOverrideConfigs"); 1438 printConfig(mOverrideConfigs[i], indentPW, "mOverrideConfigs"); 1439 } 1440 1441 printConfig(mNoSimConfig, indentPW, "mNoSimConfig"); 1442 indentPW.println("CarrierConfigLoadingLog="); 1443 mCarrierConfigLoadingLog.dump(fd, indentPW, args); 1444 1445 if (requestingPackage != null) { 1446 logd("Including default and requesting package " + requestingPackage 1447 + " carrier services in dump"); 1448 indentPW.println(""); 1449 indentPW.println("Connected services"); 1450 dumpCarrierServiceIfBound(fd, indentPW, "Default config package", 1451 mPlatformCarrierConfigPackage, false /* considerCarrierPrivileges */); 1452 dumpCarrierServiceIfBound(fd, indentPW, "Requesting package", requestingPackage, 1453 true /* considerCarrierPrivileges */); 1454 } 1455 } 1456 printConfig(PersistableBundle configApp, IndentingPrintWriter indentPW, String name)1457 private void printConfig(PersistableBundle configApp, IndentingPrintWriter indentPW, 1458 String name) { 1459 indentPW.increaseIndent(); 1460 if (configApp == null) { 1461 indentPW.println(name + " : null "); 1462 indentPW.decreaseIndent(); 1463 indentPW.println(""); 1464 return; 1465 } 1466 indentPW.println(name + " : "); 1467 List<String> sortedKeys = new ArrayList<String>(configApp.keySet()); 1468 Collections.sort(sortedKeys); 1469 indentPW.increaseIndent(); 1470 indentPW.increaseIndent(); 1471 for (String key : sortedKeys) { 1472 if (configApp.get(key) != null && configApp.get(key) instanceof Object[]) { 1473 indentPW.println(key + " = " + 1474 Arrays.toString((Object[]) configApp.get(key))); 1475 } else if (configApp.get(key) != null && configApp.get(key) instanceof int[]) { 1476 indentPW.println(key + " = " + Arrays.toString((int[]) configApp.get(key))); 1477 } else { 1478 indentPW.println(key + " = " + configApp.get(key)); 1479 } 1480 } 1481 indentPW.decreaseIndent(); 1482 indentPW.decreaseIndent(); 1483 indentPW.decreaseIndent(); 1484 indentPW.println(""); 1485 } 1486 1487 /** 1488 * Passes without problem when one of these conditions is true: 1489 * - The caller is a privileged UID (e.g. for dumpstate.cpp generating a bug report, where the 1490 * system knows the true caller plumbed in through the {@link android.os.BugreportManager} API). 1491 * - The caller's UID matches the supplied package. 1492 * 1493 * @throws SecurityException if none of the above conditions are met. 1494 */ enforceCallerIsSystemOrRequestingPackage(String requestingPackage)1495 private void enforceCallerIsSystemOrRequestingPackage(String requestingPackage) 1496 throws SecurityException { 1497 final int callingUid = Binder.getCallingUid(); 1498 if (callingUid == Process.ROOT_UID || callingUid == Process.SYSTEM_UID 1499 || callingUid == Process.SHELL_UID || callingUid == Process.PHONE_UID) { 1500 // Bug reports (dumpstate.cpp) run as SHELL, and let some other privileged UIDs through 1501 // as well. 1502 return; 1503 } 1504 // An app is trying to dump extra detail, block it if they aren't who they claim to be. 1505 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class); 1506 if (appOps == null) { 1507 throw new SecurityException("No AppOps"); 1508 } 1509 // Will throw a SecurityException if the UID and package don't match. 1510 appOps.checkPackage(callingUid, requestingPackage); 1511 } 1512 1513 /** 1514 * Searches for one or more appropriate {@link CarrierService} instances to dump based on the 1515 * current connections. 1516 * 1517 * @param targetPkgName the target package name to dump carrier services for 1518 * @param considerCarrierPrivileges if true, allow a carrier service to be dumped if it shares 1519 * carrier privileges with {@code targetPkgName}; 1520 * otherwise, only dump a carrier service if it is {@code 1521 * targetPkgName} 1522 */ dumpCarrierServiceIfBound(FileDescriptor fd, IndentingPrintWriter indentPW, String prefix, String targetPkgName, boolean considerCarrierPrivileges)1523 private void dumpCarrierServiceIfBound(FileDescriptor fd, IndentingPrintWriter indentPW, 1524 String prefix, String targetPkgName, boolean considerCarrierPrivileges) { 1525 // Null package is possible if it's early in the boot process, there was a recent crash, we 1526 // loaded the config from XML most recently, or a SIM slot is empty. Carrier apps with 1527 // long-lived bindings should typically get dumped here regardless. Even if an app is being 1528 // used for multiple phoneIds, we assume that it's smart enough to handle that on its own, 1529 // and that in most cases we'd just be dumping duplicate information and bloating a report. 1530 indentPW.increaseIndent(); 1531 indentPW.println(prefix + " : " + targetPkgName); 1532 Set<String> dumpedPkgNames = new ArraySet<>(mServiceConnection.length); 1533 for (CarrierServiceConnection connection : mServiceConnection) { 1534 if (connection == null || !SubscriptionManager.isValidPhoneId(connection.phoneId) 1535 || TextUtils.isEmpty(connection.pkgName)) { 1536 continue; 1537 } 1538 final String servicePkgName = connection.pkgName; 1539 // Note: we intentionally ignore system components here because we should NOT match the 1540 // shell caller that's typically used for bug reports via non-BugreportManager triggers. 1541 final boolean exactPackageMatch = TextUtils.equals(targetPkgName, servicePkgName); 1542 final boolean carrierPrivilegesMatch = 1543 considerCarrierPrivileges && hasCarrierPrivileges(targetPkgName, 1544 connection.phoneId); 1545 if (!exactPackageMatch && !carrierPrivilegesMatch) continue; 1546 // Make sure this service is actually alive before trying to dump it. We don't pay 1547 // attention to mServiceBound[connection.phoneId] because typically carrier apps will 1548 // request long-lived bindings, and even if we unbind the app, it may still be alive due 1549 // to CarrierServiceBindHelper. Pull it out as a reference so even if it gets set to 1550 // null within the ServiceConnection during unbinding we can avoid an NPE. 1551 final IBinder service = connection.service; 1552 if (service == null || !service.isBinderAlive() || !service.pingBinder()) continue; 1553 // We've got a live service. Last check is just to make sure we don't dump a package 1554 // multiple times. 1555 if (!dumpedPkgNames.add(servicePkgName)) continue; 1556 if (!exactPackageMatch) { 1557 logd(targetPkgName + " has carrier privileges on phoneId " + connection.phoneId 1558 + ", service provided by " + servicePkgName); 1559 indentPW.increaseIndent(); 1560 indentPW.println("Proxy : " + servicePkgName); 1561 indentPW.decreaseIndent(); 1562 } 1563 // Flush before we let the app output anything to ensure correct ordering of output. 1564 // Internally, Binder#dump calls flush on its printer after finishing so we don't 1565 // need to do anything after. 1566 indentPW.flush(); 1567 try { 1568 logd("Dumping " + servicePkgName); 1569 // We don't need to give the carrier service any args. 1570 connection.service.dump(fd, null /* args */); 1571 logd("Done with " + servicePkgName); 1572 } catch (RemoteException e) { 1573 logd("RemoteException from " + servicePkgName, e); 1574 indentPW.increaseIndent(); 1575 indentPW.println("RemoteException"); 1576 indentPW.increaseIndent(); 1577 e.printStackTrace(indentPW); 1578 indentPW.decreaseIndent(); 1579 indentPW.decreaseIndent(); 1580 // We won't retry this package again because now it's in dumpedPkgNames. 1581 } 1582 indentPW.println(""); 1583 } 1584 if (dumpedPkgNames.isEmpty()) { 1585 indentPW.increaseIndent(); 1586 indentPW.println("Not bound"); 1587 indentPW.decreaseIndent(); 1588 indentPW.println(""); 1589 } 1590 indentPW.decreaseIndent(); 1591 } 1592 hasCarrierPrivileges(String pkgName, int phoneId)1593 private boolean hasCarrierPrivileges(String pkgName, int phoneId) { 1594 int[] subIds = SubscriptionManager.getSubId(phoneId); 1595 if (ArrayUtils.isEmpty(subIds)) { 1596 return false; 1597 } 1598 return TelephonyManager.from(mContext).createForSubscriptionId( 1599 subIds[0]).checkCarrierPrivilegesForPackage(pkgName) 1600 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; 1601 } 1602 1603 private class CarrierServiceConnection implements ServiceConnection { 1604 final int phoneId; 1605 final String pkgName; 1606 final int eventId; 1607 IBinder service; 1608 CarrierServiceConnection(int phoneId, String pkgName, int eventId)1609 CarrierServiceConnection(int phoneId, String pkgName, int eventId) { 1610 this.phoneId = phoneId; 1611 this.pkgName = pkgName; 1612 this.eventId = eventId; 1613 } 1614 1615 @Override onServiceConnected(ComponentName name, IBinder service)1616 public void onServiceConnected(ComponentName name, IBinder service) { 1617 logd("Connected to config app: " + name.flattenToShortString()); 1618 this.service = service; 1619 mHandler.sendMessage(mHandler.obtainMessage(eventId, phoneId, -1, this)); 1620 } 1621 1622 @Override onServiceDisconnected(ComponentName name)1623 public void onServiceDisconnected(ComponentName name) { 1624 logd("Disconnected from config app: " + name.flattenToShortString()); 1625 this.service = null; 1626 } 1627 1628 @Override onBindingDied(ComponentName name)1629 public void onBindingDied(ComponentName name) { 1630 logd("Binding died from config app: " + name.flattenToShortString()); 1631 this.service = null; 1632 } 1633 1634 @Override onNullBinding(ComponentName name)1635 public void onNullBinding(ComponentName name) { 1636 logd("Null binding from config app: " + name.flattenToShortString()); 1637 this.service = null; 1638 } 1639 } 1640 1641 private class ConfigLoaderBroadcastReceiver extends BroadcastReceiver { 1642 @Override onReceive(Context context, Intent intent)1643 public void onReceive(Context context, Intent intent) { 1644 String action = intent.getAction(); 1645 boolean replace = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 1646 // If replace is true, only care ACTION_PACKAGE_REPLACED. 1647 if (replace && !Intent.ACTION_PACKAGE_REPLACED.equals(action)) { 1648 return; 1649 } 1650 1651 switch (action) { 1652 case Intent.ACTION_BOOT_COMPLETED: 1653 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SYSTEM_UNLOCKED, null)); 1654 break; 1655 1656 case Intent.ACTION_PACKAGE_ADDED: 1657 case Intent.ACTION_PACKAGE_REMOVED: 1658 case Intent.ACTION_PACKAGE_REPLACED: 1659 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 1660 String packageName = mContext.getPackageManager().getNameForUid(uid); 1661 if (packageName != null) { 1662 // We don't have a phoneId for arg1. 1663 mHandler.sendMessage( 1664 mHandler.obtainMessage(EVENT_PACKAGE_CHANGED, packageName)); 1665 } 1666 break; 1667 } 1668 } 1669 } 1670 1671 // Get readable string for the message code supported in this class. eventToString(int code)1672 private static String eventToString(int code) { 1673 switch (code) { 1674 case EVENT_CLEAR_CONFIG: 1675 return "EVENT_CLEAR_CONFIG"; 1676 case EVENT_CONNECTED_TO_DEFAULT: 1677 return "EVENT_CONNECTED_TO_DEFAULT"; 1678 case EVENT_CONNECTED_TO_CARRIER: 1679 return "EVENT_CONNECTED_TO_CARRIER"; 1680 case EVENT_FETCH_DEFAULT_DONE: 1681 return "EVENT_FETCH_DEFAULT_DONE"; 1682 case EVENT_FETCH_CARRIER_DONE: 1683 return "EVENT_FETCH_CARRIER_DONE"; 1684 case EVENT_DO_FETCH_DEFAULT: 1685 return "EVENT_DO_FETCH_DEFAULT"; 1686 case EVENT_DO_FETCH_CARRIER: 1687 return "EVENT_DO_FETCH_CARRIER"; 1688 case EVENT_PACKAGE_CHANGED: 1689 return "EVENT_PACKAGE_CHANGED"; 1690 case EVENT_BIND_DEFAULT_TIMEOUT: 1691 return "EVENT_BIND_DEFAULT_TIMEOUT"; 1692 case EVENT_BIND_CARRIER_TIMEOUT: 1693 return "EVENT_BIND_CARRIER_TIMEOUT"; 1694 case EVENT_CHECK_SYSTEM_UPDATE: 1695 return "EVENT_CHECK_SYSTEM_UPDATE"; 1696 case EVENT_SYSTEM_UNLOCKED: 1697 return "EVENT_SYSTEM_UNLOCKED"; 1698 case EVENT_FETCH_DEFAULT_TIMEOUT: 1699 return "EVENT_FETCH_DEFAULT_TIMEOUT"; 1700 case EVENT_FETCH_CARRIER_TIMEOUT: 1701 return "EVENT_FETCH_CARRIER_TIMEOUT"; 1702 case EVENT_SUBSCRIPTION_INFO_UPDATED: 1703 return "EVENT_SUBSCRIPTION_INFO_UPDATED"; 1704 case EVENT_MULTI_SIM_CONFIG_CHANGED: 1705 return "EVENT_MULTI_SIM_CONFIG_CHANGED"; 1706 case EVENT_DO_FETCH_DEFAULT_FOR_NO_SIM_CONFIG: 1707 return "EVENT_DO_FETCH_DEFAULT_FOR_NO_SIM_CONFIG"; 1708 case EVENT_FETCH_DEFAULT_FOR_NO_SIM_CONFIG_DONE: 1709 return "EVENT_FETCH_DEFAULT_FOR_NO_SIM_CONFIG_DONE"; 1710 case EVENT_CONNECTED_TO_DEFAULT_FOR_NO_SIM_CONFIG: 1711 return "EVENT_CONNECTED_TO_DEFAULT_FOR_NO_SIM_CONFIG"; 1712 case EVENT_BIND_DEFAULT_FOR_NO_SIM_CONFIG_TIMEOUT: 1713 return "EVENT_BIND_DEFAULT_FOR_NO_SIM_CONFIG_TIMEOUT"; 1714 case EVENT_FETCH_DEFAULT_FOR_NO_SIM_CONFIG_TIMEOUT: 1715 return "EVENT_FETCH_DEFAULT_FOR_NO_SIM_CONFIG_TIMEOUT"; 1716 default: 1717 return "UNKNOWN(" + code + ")"; 1718 } 1719 } 1720 logd(String msg)1721 private void logd(String msg) { 1722 Log.d(LOG_TAG, msg); 1723 } 1724 logd(String msg, Throwable tr)1725 private void logd(String msg, Throwable tr) { 1726 Log.d(LOG_TAG, msg, tr); 1727 } 1728 logdWithLocalLog(String msg)1729 private void logdWithLocalLog(String msg) { 1730 Log.d(LOG_TAG, msg); 1731 mCarrierConfigLoadingLog.log(msg); 1732 } 1733 loge(String msg)1734 private void loge(String msg) { 1735 Log.e(LOG_TAG, msg); 1736 mCarrierConfigLoadingLog.log(msg); 1737 } 1738 } 1739