1 /* 2 * Copyright (C) 2023 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.satellite; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.content.ComponentName; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.ServiceConnection; 25 import android.os.AsyncResult; 26 import android.os.Binder; 27 import android.os.Handler; 28 import android.os.IBinder; 29 import android.os.Looper; 30 import android.os.Message; 31 import android.os.RegistrantList; 32 import android.os.RemoteException; 33 import android.telephony.IBooleanConsumer; 34 import android.telephony.IIntegerConsumer; 35 import android.telephony.PersistentLogger; 36 import android.telephony.satellite.NtnSignalStrength; 37 import android.telephony.satellite.SatelliteCapabilities; 38 import android.telephony.satellite.SatelliteDatagram; 39 import android.telephony.satellite.SatelliteManager; 40 import android.telephony.satellite.SatelliteManager.SatelliteException; 41 import android.telephony.satellite.SatelliteModemEnableRequestAttributes; 42 import android.telephony.satellite.SystemSelectionSpecifier; 43 import android.telephony.satellite.stub.INtnSignalStrengthConsumer; 44 import android.telephony.satellite.stub.ISatellite; 45 import android.telephony.satellite.stub.ISatelliteCapabilitiesConsumer; 46 import android.telephony.satellite.stub.ISatelliteListener; 47 import android.telephony.satellite.stub.SatelliteModemState; 48 import android.telephony.satellite.stub.SatelliteService; 49 import android.text.TextUtils; 50 import android.util.Log; 51 import android.util.Pair; 52 53 import com.android.internal.R; 54 import com.android.internal.annotations.VisibleForTesting; 55 import com.android.internal.telephony.ExponentialBackoff; 56 import com.android.internal.telephony.flags.FeatureFlags; 57 58 import java.util.Arrays; 59 import java.util.List; 60 61 /** 62 * Satellite modem interface to manage connections with the satellite service and HAL interface. 63 */ 64 public class SatelliteModemInterface { 65 private static final String TAG = "SatelliteModemInterface"; 66 private static final long REBIND_INITIAL_DELAY = 2 * 1000; // 2 seconds 67 private static final long REBIND_MAXIMUM_DELAY = 64 * 1000; // 1 minute 68 private static final int REBIND_MULTIPLIER = 2; 69 70 @NonNull private static SatelliteModemInterface sInstance; 71 @NonNull private final Context mContext; 72 @NonNull private final DemoSimulator mDemoSimulator; 73 @NonNull private final SatelliteListener mVendorListener; 74 @NonNull private final SatelliteListener mDemoListener; 75 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) 76 @NonNull protected final ExponentialBackoff mExponentialBackoff; 77 @NonNull private final Object mLock = new Object(); 78 @NonNull private final SatelliteController mSatelliteController; 79 /** 80 * {@code true} to use the vendor satellite service and {@code false} to use the HAL. 81 */ 82 private boolean mIsSatelliteServiceSupported; 83 @Nullable private ISatellite mSatelliteService; 84 @Nullable private SatelliteServiceConnection mSatelliteServiceConnection; 85 @NonNull private String mVendorSatellitePackageName = ""; 86 private boolean mIsBound; 87 private boolean mIsBinding; 88 @Nullable private PersistentLogger mPersistentLogger = null; 89 90 @NonNull private final RegistrantList mSatellitePositionInfoChangedRegistrants = 91 new RegistrantList(); 92 @NonNull private final RegistrantList mDatagramTransferStateChangedRegistrants = 93 new RegistrantList(); 94 @NonNull private final RegistrantList mSatelliteModemStateChangedRegistrants = 95 new RegistrantList(); 96 @NonNull private final RegistrantList mPendingDatagramsRegistrants = new RegistrantList(); 97 @NonNull private final RegistrantList mSatelliteDatagramsReceivedRegistrants = 98 new RegistrantList(); 99 @NonNull private final RegistrantList mNtnSignalStrengthChangedRegistrants = 100 new RegistrantList(); 101 @NonNull private final RegistrantList mSatelliteCapabilitiesChangedRegistrants = 102 new RegistrantList(); 103 @NonNull private final RegistrantList mSatelliteSupportedStateChangedRegistrants = 104 new RegistrantList(); 105 @NonNull private final RegistrantList mSatelliteRegistrationFailureRegistrants = 106 new RegistrantList(); 107 @NonNull private final RegistrantList mTerrestrialNetworkAvailableChangedRegistrants = 108 new RegistrantList(); 109 110 private class SatelliteListener extends ISatelliteListener.Stub { 111 112 private final boolean mIsDemoListener; 113 SatelliteListener(boolean isDemoListener)114 SatelliteListener(boolean isDemoListener) { 115 mIsDemoListener = isDemoListener; 116 } 117 118 @Override onSatelliteDatagramReceived( android.telephony.satellite.stub.SatelliteDatagram datagram, int pendingCount)119 public void onSatelliteDatagramReceived( 120 android.telephony.satellite.stub.SatelliteDatagram datagram, int pendingCount) { 121 if (notifyResultIfExpectedListener()) { 122 plogd("onSatelliteDatagramReceived: pendingCount=" + pendingCount); 123 mSatelliteDatagramsReceivedRegistrants.notifyResult(new Pair<>( 124 SatelliteServiceUtils.fromSatelliteDatagram(datagram), pendingCount)); 125 } 126 } 127 128 @Override onPendingDatagrams()129 public void onPendingDatagrams() { 130 if (notifyResultIfExpectedListener()) { 131 plogd("onPendingDatagrams"); 132 mPendingDatagramsRegistrants.notifyResult(null); 133 } 134 } 135 136 @Override onSatellitePositionChanged( android.telephony.satellite.stub.PointingInfo pointingInfo)137 public void onSatellitePositionChanged( 138 android.telephony.satellite.stub.PointingInfo pointingInfo) { 139 mSatellitePositionInfoChangedRegistrants.notifyResult( 140 SatelliteServiceUtils.fromPointingInfo(pointingInfo)); 141 } 142 143 @Override onSatelliteModemStateChanged(int state)144 public void onSatelliteModemStateChanged(int state) { 145 if (notifyModemStateChanged(state)) { 146 mSatelliteModemStateChangedRegistrants.notifyResult( 147 SatelliteServiceUtils.fromSatelliteModemState(state)); 148 int datagramTransferState = 149 SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN; 150 switch (state) { 151 case SatelliteManager.SATELLITE_MODEM_STATE_IDLE: 152 datagramTransferState = 153 SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE; 154 break; 155 case SatelliteManager.SATELLITE_MODEM_STATE_LISTENING: 156 datagramTransferState = 157 SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING; 158 break; 159 case SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING: 160 datagramTransferState = 161 SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING; 162 break; 163 case SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_RETRYING: 164 // keep previous state as this could be retrying sending or receiving 165 break; 166 } 167 mDatagramTransferStateChangedRegistrants.notifyResult(datagramTransferState); 168 } 169 } 170 171 @Override onNtnSignalStrengthChanged( android.telephony.satellite.stub.NtnSignalStrength ntnSignalStrength)172 public void onNtnSignalStrengthChanged( 173 android.telephony.satellite.stub.NtnSignalStrength ntnSignalStrength) { 174 if (notifyResultIfExpectedListener()) { 175 mNtnSignalStrengthChangedRegistrants.notifyResult( 176 SatelliteServiceUtils.fromNtnSignalStrength(ntnSignalStrength)); 177 } 178 } 179 180 @Override onSatelliteCapabilitiesChanged( android.telephony.satellite.stub.SatelliteCapabilities satelliteCapabilities)181 public void onSatelliteCapabilitiesChanged( 182 android.telephony.satellite.stub.SatelliteCapabilities satelliteCapabilities) { 183 mSatelliteCapabilitiesChangedRegistrants.notifyResult( 184 SatelliteServiceUtils.fromSatelliteCapabilities(satelliteCapabilities)); 185 } 186 187 @Override onSatelliteSupportedStateChanged(boolean supported)188 public void onSatelliteSupportedStateChanged(boolean supported) { 189 mSatelliteSupportedStateChangedRegistrants.notifyResult(supported); 190 } 191 192 @Override onRegistrationFailure(int causeCode)193 public void onRegistrationFailure(int causeCode) { 194 mSatelliteRegistrationFailureRegistrants.notifyResult(causeCode); 195 } 196 197 @Override onTerrestrialNetworkAvailableChanged(boolean isAvailable)198 public void onTerrestrialNetworkAvailableChanged(boolean isAvailable) { 199 mTerrestrialNetworkAvailableChangedRegistrants.notifyResult(isAvailable); 200 } 201 notifyResultIfExpectedListener()202 private boolean notifyResultIfExpectedListener() { 203 // Demo listener should notify results only during demo mode 204 // Vendor listener should notify result only during real mode 205 return mIsDemoListener == mSatelliteController.isDemoModeEnabled(); 206 } 207 notifyModemStateChanged(int state)208 private boolean notifyModemStateChanged(int state) { 209 if (notifyResultIfExpectedListener()) { 210 return true; 211 } 212 213 return state == SatelliteModemState.SATELLITE_MODEM_STATE_OFF 214 || state == SatelliteModemState.SATELLITE_MODEM_STATE_UNAVAILABLE; 215 } 216 } 217 218 /** 219 * @return The singleton instance of SatelliteModemInterface. 220 */ getInstance()221 public static SatelliteModemInterface getInstance() { 222 if (sInstance == null) { 223 loge("SatelliteModemInterface was not yet initialized."); 224 } 225 return sInstance; 226 } 227 228 /** 229 * Create the SatelliteModemInterface singleton instance. 230 * @param context The Context to use to create the SatelliteModemInterface. 231 * @param satelliteController The singleton instance of SatelliteController. 232 * @param featureFlags The telephony feature flags. 233 * @return The singleton instance of SatelliteModemInterface. 234 */ make(@onNull Context context, SatelliteController satelliteController, @NonNull FeatureFlags featureFlags)235 public static SatelliteModemInterface make(@NonNull Context context, 236 SatelliteController satelliteController, 237 @NonNull FeatureFlags featureFlags) { 238 if (sInstance == null) { 239 sInstance = new SatelliteModemInterface( 240 context, satelliteController, Looper.getMainLooper(), featureFlags); 241 } 242 return sInstance; 243 } 244 245 /** 246 * Create a SatelliteModemInterface to manage connections to the SatelliteService. 247 * 248 * @param context The Context for the SatelliteModemInterface. 249 * @param featureFlags The telephony feature flags. 250 * @param looper The Looper to run binding retry on. 251 */ 252 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) SatelliteModemInterface(@onNull Context context, SatelliteController satelliteController, @NonNull Looper looper, @NonNull FeatureFlags featureFlags)253 protected SatelliteModemInterface(@NonNull Context context, 254 SatelliteController satelliteController, 255 @NonNull Looper looper, 256 @NonNull FeatureFlags featureFlags) { 257 mPersistentLogger = SatelliteServiceUtils.getPersistentLogger(context); 258 mContext = context; 259 mDemoSimulator = DemoSimulator.make(context, satelliteController); 260 mVendorListener = new SatelliteListener(false); 261 mDemoListener = new SatelliteListener(true); 262 mIsSatelliteServiceSupported = getSatelliteServiceSupport(); 263 mSatelliteController = satelliteController; 264 mExponentialBackoff = new ExponentialBackoff(REBIND_INITIAL_DELAY, REBIND_MAXIMUM_DELAY, 265 REBIND_MULTIPLIER, looper, () -> { 266 synchronized (mLock) { 267 if ((mIsBound && mSatelliteService != null) || mIsBinding) { 268 return; 269 } 270 } 271 if (mSatelliteServiceConnection != null) { 272 synchronized (mLock) { 273 mIsBound = false; 274 mIsBinding = false; 275 } 276 unbindService(); 277 } 278 bindService(); 279 }); 280 mExponentialBackoff.start(); 281 plogd("Created SatelliteModemInterface. Attempting to bind to SatelliteService."); 282 bindService(); 283 } 284 285 /** 286 * Get the SatelliteService interface, if it exists. 287 * 288 * @return The bound ISatellite, or {@code null} if it is not yet connected. 289 */ getService()290 @Nullable public ISatellite getService() { 291 return mSatelliteService; 292 } 293 getSatellitePackageName()294 @NonNull private String getSatellitePackageName() { 295 if (!TextUtils.isEmpty(mVendorSatellitePackageName)) { 296 return mVendorSatellitePackageName; 297 } 298 return TextUtils.emptyIfNull(mContext.getResources().getString( 299 R.string.config_satellite_service_package)); 300 } 301 getSatelliteServiceSupport()302 private boolean getSatelliteServiceSupport() { 303 return !TextUtils.isEmpty(getSatellitePackageName()); 304 } 305 306 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) bindService()307 protected void bindService() { 308 synchronized (mLock) { 309 if (mIsBinding || mIsBound) return; 310 mIsBinding = true; 311 } 312 String packageName = getSatellitePackageName(); 313 if (TextUtils.isEmpty(packageName)) { 314 ploge("Unable to bind to the satellite service because the package is undefined."); 315 // Since the package name comes from static device configs, stop retry because 316 // rebind will continue to fail without a valid package name. 317 synchronized (mLock) { 318 mIsBinding = false; 319 } 320 mExponentialBackoff.stop(); 321 return; 322 } 323 Intent intent = new Intent(SatelliteService.SERVICE_INTERFACE); 324 intent.setPackage(packageName); 325 326 mSatelliteServiceConnection = new SatelliteServiceConnection(); 327 plogd("Binding to " + packageName); 328 try { 329 boolean success = mContext.bindService( 330 intent, mSatelliteServiceConnection, Context.BIND_AUTO_CREATE); 331 if (success) { 332 plogd("Successfully bound to the satellite service."); 333 } else { 334 synchronized (mLock) { 335 mIsBinding = false; 336 } 337 mExponentialBackoff.notifyFailed(); 338 ploge("Error binding to the satellite service. Retrying in " 339 + mExponentialBackoff.getCurrentDelay() + " ms."); 340 } 341 } catch (Exception e) { 342 synchronized (mLock) { 343 mIsBinding = false; 344 } 345 mExponentialBackoff.notifyFailed(); 346 ploge("Exception binding to the satellite service. Retrying in " 347 + mExponentialBackoff.getCurrentDelay() + " ms. Exception: " + e); 348 } 349 } 350 351 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) unbindService()352 protected void unbindService() { 353 disconnectSatelliteService(); 354 mContext.unbindService(mSatelliteServiceConnection); 355 mSatelliteServiceConnection = null; 356 } 357 disconnectSatelliteService()358 private void disconnectSatelliteService() { 359 // TODO: clean up any listeners and return failed for pending callbacks 360 mSatelliteService = null; 361 } 362 363 private class SatelliteServiceConnection implements ServiceConnection { 364 @Override onServiceConnected(ComponentName name, IBinder service)365 public void onServiceConnected(ComponentName name, IBinder service) { 366 plogd("onServiceConnected: ComponentName=" + name); 367 synchronized (mLock) { 368 mIsBound = true; 369 mIsBinding = false; 370 } 371 mSatelliteService = ISatellite.Stub.asInterface(service); 372 mExponentialBackoff.stop(); 373 try { 374 mSatelliteService.setSatelliteListener(mVendorListener); 375 mDemoSimulator.setSatelliteListener(mDemoListener); 376 } catch (RemoteException e) { 377 // TODO: Retry setSatelliteListener 378 plogd("setSatelliteListener: RemoteException " + e); 379 } 380 mSatelliteController.onSatelliteServiceConnected(); 381 } 382 383 @Override onServiceDisconnected(ComponentName name)384 public void onServiceDisconnected(ComponentName name) { 385 ploge("onServiceDisconnected: Waiting for reconnect."); 386 synchronized (mLock) { 387 mIsBinding = false; 388 } 389 // Since we are still technically bound, clear the service and wait for reconnect. 390 disconnectSatelliteService(); 391 } 392 393 @Override onBindingDied(ComponentName name)394 public void onBindingDied(ComponentName name) { 395 ploge("onBindingDied: Unbinding and rebinding service."); 396 synchronized (mLock) { 397 mIsBound = false; 398 mIsBinding = false; 399 } 400 unbindService(); 401 mExponentialBackoff.start(); 402 } 403 } 404 405 /** 406 * Registers for satellite position info changed from satellite modem. 407 * 408 * @param h Handler for notification message. 409 * @param what User-defined message code. 410 * @param obj User object. 411 */ registerForSatellitePositionInfoChanged( @onNull Handler h, int what, @Nullable Object obj)412 public void registerForSatellitePositionInfoChanged( 413 @NonNull Handler h, int what, @Nullable Object obj) { 414 mSatellitePositionInfoChangedRegistrants.add(h, what, obj); 415 } 416 417 /** 418 * Unregisters for satellite position info changed from satellite modem. 419 * 420 * @param h Handler to be removed from the registrant list. 421 */ unregisterForSatellitePositionInfoChanged(@onNull Handler h)422 public void unregisterForSatellitePositionInfoChanged(@NonNull Handler h) { 423 mSatellitePositionInfoChangedRegistrants.remove(h); 424 } 425 426 /** 427 * Registers for datagram transfer state changed. 428 * 429 * @param h Handler for notification message. 430 * @param what User-defined message code. 431 * @param obj User object. 432 */ registerForDatagramTransferStateChanged( @onNull Handler h, int what, @Nullable Object obj)433 public void registerForDatagramTransferStateChanged( 434 @NonNull Handler h, int what, @Nullable Object obj) { 435 mDatagramTransferStateChangedRegistrants.add(h, what, obj); 436 } 437 438 /** 439 * Unregisters for datagram transfer state changed. 440 * 441 * @param h Handler to be removed from the registrant list. 442 */ unregisterForDatagramTransferStateChanged(@onNull Handler h)443 public void unregisterForDatagramTransferStateChanged(@NonNull Handler h) { 444 mDatagramTransferStateChangedRegistrants.remove(h); 445 } 446 447 /** 448 * Registers for modem state changed from satellite modem. 449 * 450 * @param h Handler for notification message. 451 * @param what User-defined message code. 452 * @param obj User object. 453 */ registerForSatelliteModemStateChanged( @onNull Handler h, int what, @Nullable Object obj)454 public void registerForSatelliteModemStateChanged( 455 @NonNull Handler h, int what, @Nullable Object obj) { 456 mSatelliteModemStateChangedRegistrants.add(h, what, obj); 457 } 458 459 /** 460 * Unregisters for modem state changed from satellite modem. 461 * 462 * @param h Handler to be removed from the registrant list. 463 */ unregisterForSatelliteModemStateChanged(@onNull Handler h)464 public void unregisterForSatelliteModemStateChanged(@NonNull Handler h) { 465 mSatelliteModemStateChangedRegistrants.remove(h); 466 } 467 468 /** 469 * Registers for pending datagrams indication from satellite modem. 470 * 471 * @param h Handler for notification message. 472 * @param what User-defined message code. 473 * @param obj User object. 474 */ registerForPendingDatagrams(@onNull Handler h, int what, @Nullable Object obj)475 public void registerForPendingDatagrams(@NonNull Handler h, int what, @Nullable Object obj) { 476 mPendingDatagramsRegistrants.add(h, what, obj); 477 } 478 479 /** 480 * Unregisters for pending datagrams indication from satellite modem. 481 * 482 * @param h Handler to be removed from the registrant list. 483 */ unregisterForPendingDatagrams(@onNull Handler h)484 public void unregisterForPendingDatagrams(@NonNull Handler h) { 485 mPendingDatagramsRegistrants.remove(h); 486 } 487 488 /** 489 * Registers for new datagrams received from satellite modem. 490 * 491 * @param h Handler for notification message. 492 * @param what User-defined message code. 493 * @param obj User object. 494 */ registerForSatelliteDatagramsReceived( @onNull Handler h, int what, @Nullable Object obj)495 public void registerForSatelliteDatagramsReceived( 496 @NonNull Handler h, int what, @Nullable Object obj) { 497 mSatelliteDatagramsReceivedRegistrants.add(h, what, obj); 498 } 499 500 /** 501 * Unregisters for new datagrams received from satellite modem. 502 * 503 * @param h Handler to be removed from the registrant list. 504 */ unregisterForSatelliteDatagramsReceived(@onNull Handler h)505 public void unregisterForSatelliteDatagramsReceived(@NonNull Handler h) { 506 mSatelliteDatagramsReceivedRegistrants.remove(h); 507 } 508 509 /** 510 * Registers for non-terrestrial signal strength level changed. 511 * 512 * @param h Handler for notification message. 513 * @param what User-defined message code. 514 * @param obj User object. 515 */ registerForNtnSignalStrengthChanged( @onNull Handler h, int what, @Nullable Object obj)516 public void registerForNtnSignalStrengthChanged( 517 @NonNull Handler h, int what, @Nullable Object obj) { 518 mNtnSignalStrengthChangedRegistrants.add(h, what, obj); 519 } 520 521 /** 522 * Unregisters for non-terrestrial signal strength level changed. 523 * 524 * @param h Handler to be removed from the registrant list. 525 */ unregisterForNtnSignalStrengthChanged(@onNull Handler h)526 public void unregisterForNtnSignalStrengthChanged(@NonNull Handler h) { 527 mNtnSignalStrengthChangedRegistrants.remove(h); 528 } 529 530 /** 531 * Registers for satellite capabilities changed. 532 * 533 * @param h Handler for notification message. 534 * @param what User-defined message code. 535 * @param obj User object. 536 */ registerForSatelliteCapabilitiesChanged( @onNull Handler h, int what, @Nullable Object obj)537 public void registerForSatelliteCapabilitiesChanged( 538 @NonNull Handler h, int what, @Nullable Object obj) { 539 mSatelliteCapabilitiesChangedRegistrants.add(h, what, obj); 540 } 541 542 /** 543 * Unregisters for satellite capabilities changed. 544 * 545 * @param h Handler to be removed from the registrant list. 546 */ unregisterForSatelliteCapabilitiesChanged(@onNull Handler h)547 public void unregisterForSatelliteCapabilitiesChanged(@NonNull Handler h) { 548 mSatelliteCapabilitiesChangedRegistrants.remove(h); 549 } 550 551 /** 552 * Registers for the satellite supported state changed. 553 * 554 * @param h Handler for notification message. 555 * @param what User-defined message code. 556 * @param obj User object. 557 */ registerForSatelliteSupportedStateChanged( @onNull Handler h, int what, @Nullable Object obj)558 public void registerForSatelliteSupportedStateChanged( 559 @NonNull Handler h, int what, @Nullable Object obj) { 560 mSatelliteSupportedStateChangedRegistrants.add(h, what, obj); 561 } 562 563 /** 564 * Unregisters for the satellite supported state changed. 565 * 566 * @param h Handler to be removed from the registrant list. 567 */ unregisterForSatelliteSupportedStateChanged(@onNull Handler h)568 public void unregisterForSatelliteSupportedStateChanged(@NonNull Handler h) { 569 mSatelliteSupportedStateChangedRegistrants.remove(h); 570 } 571 572 /** 573 * Registers for the satellite registration failed. 574 * 575 * @param h Handler for notification message. 576 * @param what User-defined message code. 577 * @param obj User object. 578 */ registerForSatelliteRegistrationFailure( @onNull Handler h, int what, @Nullable Object obj)579 public void registerForSatelliteRegistrationFailure( 580 @NonNull Handler h, int what, @Nullable Object obj) { 581 mSatelliteRegistrationFailureRegistrants.add(h, what, obj); 582 } 583 584 /** 585 * Unregisters for the satellite registration failed. 586 * 587 * @param h Handler to be removed from the registrant list. 588 */ unregisterForSatelliteRegistrationFailure(@onNull Handler h)589 public void unregisterForSatelliteRegistrationFailure(@NonNull Handler h) { 590 mSatelliteRegistrationFailureRegistrants.remove(h); 591 } 592 593 /** 594 * Registers for the terrestrial network available changed. 595 * 596 * @param h Handler for notification message. 597 * @param what User-defined message code. 598 * @param obj User object. 599 */ registerForTerrestrialNetworkAvailableChanged( @onNull Handler h, int what, @Nullable Object obj)600 public void registerForTerrestrialNetworkAvailableChanged( 601 @NonNull Handler h, int what, @Nullable Object obj) { 602 mTerrestrialNetworkAvailableChangedRegistrants.add(h, what, obj); 603 } 604 605 /** 606 * Unregisters for the terrestrial network available changed. 607 * 608 * @param h Handler to be removed from the registrant list. 609 */ unregisterForTerrestrialNetworkAvailableChanged(@onNull Handler h)610 public void unregisterForTerrestrialNetworkAvailableChanged(@NonNull Handler h) { 611 mTerrestrialNetworkAvailableChangedRegistrants.remove(h); 612 } 613 614 /** 615 * Request to enable or disable the satellite service listening mode. 616 * Listening mode allows the satellite service to listen for incoming pages. 617 * 618 * @param enable True to enable satellite listening mode and false to disable. 619 * @param timeout How long the satellite modem should wait for the next incoming page before 620 * disabling listening mode. 621 * @param message The Message to send to result of the operation to. 622 */ requestSatelliteListeningEnabled(boolean enable, int timeout, @Nullable Message message)623 public void requestSatelliteListeningEnabled(boolean enable, int timeout, 624 @Nullable Message message) { 625 if (mSatelliteService != null) { 626 try { 627 mSatelliteService.requestSatelliteListeningEnabled(enable, timeout, 628 new IIntegerConsumer.Stub() { 629 @Override 630 public void accept(int result) { 631 int error = SatelliteServiceUtils.fromSatelliteError(result); 632 plogd("requestSatelliteListeningEnabled: " + error); 633 Binder.withCleanCallingIdentity(() -> { 634 if (message != null) { 635 sendMessageWithResult(message, null, error); 636 } 637 }); 638 } 639 }); 640 } catch (RemoteException e) { 641 ploge("requestSatelliteListeningEnabled: RemoteException " + e); 642 if (message != null) { 643 sendMessageWithResult( 644 message, null, SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 645 } 646 } 647 } else { 648 ploge("requestSatelliteListeningEnabled: Satellite service is unavailable."); 649 if (message != null) { 650 sendMessageWithResult(message, null, 651 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 652 } 653 } 654 } 655 656 /** 657 * Allow cellular modem scanning while satellite mode is on. 658 * @param enabled {@code true} to enable cellular modem while satellite mode is on 659 * and {@code false} to disable 660 * @param message The Message to send to result of the operation to. 661 */ enableCellularModemWhileSatelliteModeIsOn(boolean enabled, @Nullable Message message)662 public void enableCellularModemWhileSatelliteModeIsOn(boolean enabled, 663 @Nullable Message message) { 664 if (mSatelliteService != null) { 665 try { 666 IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() { 667 @Override 668 public void accept(int result) { 669 int error = SatelliteServiceUtils.fromSatelliteError(result); 670 plogd("enableCellularModemWhileSatelliteModeIsOn: " + error); 671 Binder.withCleanCallingIdentity(() -> { 672 if (message != null) { 673 sendMessageWithResult(message, null, error); 674 } 675 }); 676 } 677 }; 678 679 if (mSatelliteController.isDemoModeEnabled()) { 680 mDemoSimulator.enableTerrestrialNetworkScanWhileSatelliteModeIsOn( 681 enabled, errorCallback); 682 } else { 683 mSatelliteService.enableTerrestrialNetworkScanWhileSatelliteModeIsOn( 684 enabled, errorCallback); 685 } 686 } catch (RemoteException e) { 687 ploge("enableTerrestrialNetworkScanWhileSatelliteModeIsOn: RemoteException " + e); 688 if (message != null) { 689 sendMessageWithResult( 690 message, null, SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 691 } 692 } 693 } else { 694 ploge("enableCellularModemWhileSatelliteModeIsOn: Satellite service is unavailable."); 695 if (message != null) { 696 sendMessageWithResult(message, null, 697 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 698 } 699 } 700 } 701 /** 702 * Request to enable or disable the satellite modem and demo mode. If the satellite modem 703 * is enabled, this may also disable the cellular modem, and if the satellite modem is disabled, 704 * this may also re-enable the cellular modem. 705 * 706 * @param enableAttributes info needed to allow carrier to roam to satellite. 707 * @param message The Message to send to result of the operation to. 708 */ requestSatelliteEnabled(SatelliteModemEnableRequestAttributes enableAttributes, @NonNull Message message)709 public void requestSatelliteEnabled(SatelliteModemEnableRequestAttributes enableAttributes, 710 @NonNull Message message) { 711 if (mSatelliteService != null) { 712 try { 713 mSatelliteService.requestSatelliteEnabled(SatelliteServiceUtils 714 .toSatelliteModemEnableRequestAttributes(enableAttributes), 715 new IIntegerConsumer.Stub() { 716 @Override 717 public void accept(int result) { 718 int error = SatelliteServiceUtils.fromSatelliteError(result); 719 plogd("setSatelliteEnabled: " + error); 720 Binder.withCleanCallingIdentity(() -> 721 sendMessageWithResult(message, null, error)); 722 } 723 }); 724 } catch (RemoteException e) { 725 ploge("setSatelliteEnabled: RemoteException " + e); 726 sendMessageWithResult(message, null, 727 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 728 } 729 } else { 730 ploge("setSatelliteEnabled: Satellite service is unavailable."); 731 sendMessageWithResult(message, null, 732 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 733 } 734 } 735 736 /** 737 * Request to get whether the satellite modem is enabled. 738 * 739 * @param message The Message to send to result of the operation to. 740 */ requestIsSatelliteEnabled(@onNull Message message)741 public void requestIsSatelliteEnabled(@NonNull Message message) { 742 if (mSatelliteService != null) { 743 try { 744 mSatelliteService.requestIsSatelliteEnabled(new IIntegerConsumer.Stub() { 745 @Override 746 public void accept(int result) { 747 int error = SatelliteServiceUtils.fromSatelliteError(result); 748 plogd("requestIsSatelliteEnabled: " + error); 749 Binder.withCleanCallingIdentity(() -> 750 sendMessageWithResult(message, null, error)); 751 } 752 }, new IBooleanConsumer.Stub() { 753 @Override 754 public void accept(boolean result) { 755 // Convert for compatibility with SatelliteResponse 756 // TODO: This should just report result instead. 757 int[] enabled = new int[] {result ? 1 : 0}; 758 plogd("requestIsSatelliteEnabled: " + Arrays.toString(enabled)); 759 Binder.withCleanCallingIdentity(() -> sendMessageWithResult( 760 message, enabled, SatelliteManager.SATELLITE_RESULT_SUCCESS)); 761 } 762 }); 763 } catch (RemoteException e) { 764 ploge("requestIsSatelliteEnabled: RemoteException " + e); 765 sendMessageWithResult(message, null, 766 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 767 } 768 } else { 769 ploge("requestIsSatelliteEnabled: Satellite service is unavailable."); 770 sendMessageWithResult(message, null, 771 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 772 } 773 } 774 775 /** 776 * Request to get whether the satellite service is supported on the device. 777 * 778 * @param message The Message to send to result of the operation to. 779 */ requestIsSatelliteSupported(@onNull Message message)780 public void requestIsSatelliteSupported(@NonNull Message message) { 781 if (mSatelliteService != null) { 782 try { 783 mSatelliteService.requestIsSatelliteSupported(new IIntegerConsumer.Stub() { 784 @Override 785 public void accept(int result) { 786 int error = SatelliteServiceUtils.fromSatelliteError(result); 787 plogd("requestIsSatelliteSupported: " + error); 788 Binder.withCleanCallingIdentity(() -> 789 sendMessageWithResult(message, null, error)); 790 } 791 }, new IBooleanConsumer.Stub() { 792 @Override 793 public void accept(boolean result) { 794 plogd("requestIsSatelliteSupported: " + result); 795 Binder.withCleanCallingIdentity(() -> sendMessageWithResult( 796 message, result, SatelliteManager.SATELLITE_RESULT_SUCCESS)); 797 } 798 }); 799 } catch (RemoteException e) { 800 ploge("requestIsSatelliteSupported: RemoteException " + e); 801 sendMessageWithResult(message, null, 802 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 803 } 804 } else { 805 ploge("requestIsSatelliteSupported: Satellite service is unavailable."); 806 sendMessageWithResult( 807 message, null, SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 808 } 809 } 810 811 /** 812 * Request to get the SatelliteCapabilities of the satellite service. 813 * 814 * @param message The Message to send to result of the operation to. 815 */ requestSatelliteCapabilities(@onNull Message message)816 public void requestSatelliteCapabilities(@NonNull Message message) { 817 if (mSatelliteService != null) { 818 try { 819 mSatelliteService.requestSatelliteCapabilities(new IIntegerConsumer.Stub() { 820 @Override 821 public void accept(int result) { 822 int error = SatelliteServiceUtils.fromSatelliteError(result); 823 plogd("requestSatelliteCapabilities: " + error); 824 Binder.withCleanCallingIdentity(() -> 825 sendMessageWithResult(message, null, error)); 826 } 827 }, new ISatelliteCapabilitiesConsumer.Stub() { 828 @Override 829 public void accept(android.telephony.satellite.stub.SatelliteCapabilities 830 result) { 831 SatelliteCapabilities capabilities = 832 SatelliteServiceUtils.fromSatelliteCapabilities(result); 833 plogd("requestSatelliteCapabilities: " + capabilities); 834 Binder.withCleanCallingIdentity(() -> sendMessageWithResult( 835 message, capabilities, SatelliteManager.SATELLITE_RESULT_SUCCESS)); 836 } 837 }); 838 } catch (RemoteException e) { 839 ploge("requestSatelliteCapabilities: RemoteException " + e); 840 sendMessageWithResult(message, null, 841 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 842 } 843 } else { 844 ploge("requestSatelliteCapabilities: Satellite service is unavailable."); 845 sendMessageWithResult(message, null, 846 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 847 } 848 } 849 850 /** 851 * User started pointing to the satellite. 852 * The satellite service should report the satellite pointing info via 853 * ISatelliteListener#onSatellitePositionChanged as the user device/satellite moves. 854 * 855 * @param message The Message to send to result of the operation to. 856 */ startSendingSatellitePointingInfo(@onNull Message message)857 public void startSendingSatellitePointingInfo(@NonNull Message message) { 858 if (mSatelliteService != null) { 859 try { 860 mSatelliteService.startSendingSatellitePointingInfo(new IIntegerConsumer.Stub() { 861 @Override 862 public void accept(int result) { 863 int error = SatelliteServiceUtils.fromSatelliteError(result); 864 plogd("startSendingSatellitePointingInfo: " + error); 865 Binder.withCleanCallingIdentity(() -> 866 sendMessageWithResult(message, null, error)); 867 } 868 }); 869 } catch (RemoteException e) { 870 ploge("startSendingSatellitePointingInfo: RemoteException " + e); 871 sendMessageWithResult(message, null, 872 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 873 } 874 } else { 875 ploge("startSendingSatellitePointingInfo: Satellite service is unavailable."); 876 sendMessageWithResult(message, null, 877 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 878 } 879 } 880 881 /** 882 * User stopped pointing to the satellite. 883 * The satellite service should stop reporting satellite pointing info to the framework. 884 * 885 * @param message The Message to send to result of the operation to. 886 */ stopSendingSatellitePointingInfo(@onNull Message message)887 public void stopSendingSatellitePointingInfo(@NonNull Message message) { 888 if (mSatelliteService != null) { 889 try { 890 mSatelliteService.stopSendingSatellitePointingInfo(new IIntegerConsumer.Stub() { 891 @Override 892 public void accept(int result) { 893 int error = SatelliteServiceUtils.fromSatelliteError(result); 894 plogd("stopSendingSatellitePointingInfo: " + error); 895 Binder.withCleanCallingIdentity(() -> 896 sendMessageWithResult(message, null, error)); 897 } 898 }); 899 } catch (RemoteException e) { 900 ploge("stopSendingSatellitePointingInfo: RemoteException " + e); 901 sendMessageWithResult(message, null, 902 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 903 } 904 } else { 905 ploge("stopSendingSatellitePointingInfo: Satellite service is unavailable."); 906 sendMessageWithResult(message, null, 907 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 908 } 909 } 910 911 /** 912 * Poll the pending datagrams to be received over satellite. 913 * The satellite service should check if there are any pending datagrams to be received over 914 * satellite and report them via ISatelliteListener#onSatelliteDatagramsReceived. 915 * 916 * @param message The Message to send to result of the operation to. 917 */ pollPendingSatelliteDatagrams(@onNull Message message)918 public void pollPendingSatelliteDatagrams(@NonNull Message message) { 919 if (mSatelliteService != null) { 920 try { 921 mSatelliteService.pollPendingSatelliteDatagrams(new IIntegerConsumer.Stub() { 922 @Override 923 public void accept(int result) { 924 int error = SatelliteServiceUtils.fromSatelliteError(result); 925 plogd("pollPendingDatagrams: " + error); 926 Binder.withCleanCallingIdentity(() -> 927 sendMessageWithResult(message, null, error)); 928 } 929 }); 930 } catch (RemoteException e) { 931 ploge("pollPendingDatagrams: RemoteException " + e); 932 sendMessageWithResult(message, null, 933 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 934 } 935 } else { 936 ploge("pollPendingDatagrams: Satellite service is unavailable."); 937 sendMessageWithResult(message, null, 938 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 939 } 940 } 941 942 /** 943 * Send datagram over satellite. 944 * 945 * @param datagram Datagram to send in byte format. 946 * @param isEmergency Whether this is an emergency datagram. 947 * @param needFullScreenPointingUI this is used to indicate pointingUI app to open in 948 * full screen mode. 949 * @param message The Message to send to result of the operation to. 950 */ sendSatelliteDatagram(@onNull SatelliteDatagram datagram, boolean isEmergency, boolean needFullScreenPointingUI, @NonNull Message message)951 public void sendSatelliteDatagram(@NonNull SatelliteDatagram datagram, boolean isEmergency, 952 boolean needFullScreenPointingUI, @NonNull Message message) { 953 if (mSatelliteService != null) { 954 try { 955 mSatelliteService.sendSatelliteDatagram( 956 SatelliteServiceUtils.toSatelliteDatagram(datagram), isEmergency, 957 new IIntegerConsumer.Stub() { 958 @Override 959 public void accept(int result) { 960 int error = SatelliteServiceUtils.fromSatelliteError(result); 961 plogd("sendDatagram: " + error); 962 Binder.withCleanCallingIdentity(() -> 963 sendMessageWithResult(message, null, error)); 964 } 965 }); 966 } catch (RemoteException e) { 967 ploge("sendDatagram: RemoteException " + e); 968 sendMessageWithResult(message, null, 969 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 970 } 971 } else { 972 ploge("sendDatagram: Satellite service is unavailable."); 973 sendMessageWithResult(message, null, 974 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 975 } 976 } 977 978 /** 979 * Request the current satellite modem state. 980 * The satellite service should report the current satellite modem state via 981 * ISatelliteListener#onSatelliteModemStateChanged. 982 * 983 * @param message The Message to send to result of the operation to. 984 */ requestSatelliteModemState(@onNull Message message)985 public void requestSatelliteModemState(@NonNull Message message) { 986 if (mSatelliteService != null) { 987 try { 988 mSatelliteService.requestSatelliteModemState(new IIntegerConsumer.Stub() { 989 @Override 990 public void accept(int result) { 991 int error = SatelliteServiceUtils.fromSatelliteError(result); 992 plogd("requestSatelliteModemState: " + error); 993 Binder.withCleanCallingIdentity(() -> 994 sendMessageWithResult(message, null, error)); 995 } 996 }, new IIntegerConsumer.Stub() { 997 @Override 998 public void accept(int result) { 999 // Convert SatelliteModemState from service to frameworks definition. 1000 int modemState = SatelliteServiceUtils.fromSatelliteModemState(result); 1001 plogd("requestSatelliteModemState: " + modemState); 1002 Binder.withCleanCallingIdentity(() -> sendMessageWithResult( 1003 message, modemState, SatelliteManager.SATELLITE_RESULT_SUCCESS)); 1004 } 1005 }); 1006 } catch (RemoteException e) { 1007 ploge("requestSatelliteModemState: RemoteException " + e); 1008 sendMessageWithResult(message, null, 1009 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 1010 } 1011 } else { 1012 ploge("requestSatelliteModemState: Satellite service is unavailable."); 1013 sendMessageWithResult(message, null, 1014 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 1015 } 1016 } 1017 1018 /** 1019 * Request to get the time after which the satellite will be visible. This is an int 1020 * representing the duration in seconds after which the satellite will be visible. 1021 * This will return 0 if the satellite is currently visible. 1022 * 1023 * @param message The Message to send to result of the operation to. 1024 */ requestTimeForNextSatelliteVisibility(@onNull Message message)1025 public void requestTimeForNextSatelliteVisibility(@NonNull Message message) { 1026 if (mSatelliteService != null) { 1027 try { 1028 mSatelliteService.requestTimeForNextSatelliteVisibility( 1029 new IIntegerConsumer.Stub() { 1030 @Override 1031 public void accept(int result) { 1032 int error = SatelliteServiceUtils.fromSatelliteError(result); 1033 plogd("requestTimeForNextSatelliteVisibility: " + error); 1034 Binder.withCleanCallingIdentity(() -> 1035 sendMessageWithResult(message, null, error)); 1036 } 1037 }, new IIntegerConsumer.Stub() { 1038 @Override 1039 public void accept(int result) { 1040 // Convert for compatibility with SatelliteResponse 1041 // TODO: This should just report result instead. 1042 int[] time = new int[] {result}; 1043 plogd("requestTimeForNextSatelliteVisibility: " 1044 + Arrays.toString(time)); 1045 Binder.withCleanCallingIdentity(() -> sendMessageWithResult( 1046 message, time, SatelliteManager.SATELLITE_RESULT_SUCCESS)); 1047 } 1048 }); 1049 } catch (RemoteException e) { 1050 ploge("requestTimeForNextSatelliteVisibility: RemoteException " + e); 1051 sendMessageWithResult(message, null, 1052 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 1053 } 1054 } else { 1055 ploge("requestTimeForNextSatelliteVisibility: Satellite service is unavailable."); 1056 sendMessageWithResult(message, null, 1057 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 1058 } 1059 } 1060 1061 /** 1062 * Set the non-terrestrial PLMN with lower priority than terrestrial networks. 1063 * MCC/MNC broadcast by the non-terrestrial networks will not be included in OPLMNwACT file 1064 * on SIM profile. 1065 * Acquisition of satellite based system is deemed lower priority to terrestrial networks. 1066 * Even so, UE shall make all attempts to acquire terrestrial service prior to camping on 1067 * satellite LTE service. 1068 * 1069 * @param simSlot Indicates the SIM slot to which this API will be applied. The modem will use 1070 * this information to determine the relevant carrier. 1071 * @param carrierPlmnList The list of roaming PLMN used for connecting to satellite networks 1072 * supported by user subscription. 1073 * @param allSatellitePlmnList Modem should use the allSatellitePlmnList to identify satellite 1074 * PLMNs that are not supported by the carrier and make sure not to 1075 * attach to them. 1076 * @param message The result receiver that returns whether the modem has 1077 * successfully set the satellite PLMN 1078 */ setSatellitePlmn(@onNull int simSlot, @NonNull List<String> carrierPlmnList, @NonNull List<String> allSatellitePlmnList, @NonNull Message message)1079 public void setSatellitePlmn(@NonNull int simSlot, @NonNull List<String> carrierPlmnList, 1080 @NonNull List<String> allSatellitePlmnList, @NonNull Message message) { 1081 if (mSatelliteService != null) { 1082 try { 1083 mSatelliteService.setSatellitePlmn(simSlot, carrierPlmnList, allSatellitePlmnList, 1084 new IIntegerConsumer.Stub() { 1085 @Override 1086 public void accept(int result) { 1087 int error = SatelliteServiceUtils.fromSatelliteError(result); 1088 plogd("setSatellitePlmn: " + error); 1089 Binder.withCleanCallingIdentity(() -> 1090 sendMessageWithResult(message, null, error)); 1091 } 1092 }); 1093 } catch (RemoteException e) { 1094 ploge("setSatellitePlmn: RemoteException " + e); 1095 sendMessageWithResult(message, null, 1096 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 1097 } 1098 } else { 1099 ploge("setSatellitePlmn: Satellite service is unavailable."); 1100 sendMessageWithResult(message, null, 1101 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 1102 } 1103 } 1104 1105 /** 1106 * Enable or disable satellite in the cellular modem associated with a carrier. 1107 * Refer setSatellitePlmn for the details of satellite PLMN scanning process. 1108 * 1109 * @param simSlot Indicates the SIM slot to which this API will be applied. The modem will use 1110 * this information to determine the relevant carrier. 1111 * @param enableSatellite True to enable the satellite modem and false to disable. 1112 * @param message The Message to send to result of the operation to. 1113 */ requestSetSatelliteEnabledForCarrier(@onNull int simSlot, @NonNull boolean enableSatellite, @NonNull Message message)1114 public void requestSetSatelliteEnabledForCarrier(@NonNull int simSlot, 1115 @NonNull boolean enableSatellite, @NonNull Message message) { 1116 if (mSatelliteService != null) { 1117 try { 1118 mSatelliteService.setSatelliteEnabledForCarrier(simSlot, enableSatellite, 1119 new IIntegerConsumer.Stub() { 1120 @Override 1121 public void accept(int result) { 1122 int error = SatelliteServiceUtils.fromSatelliteError(result); 1123 plogd("requestSetSatelliteEnabledForCarrier: " + error); 1124 Binder.withCleanCallingIdentity(() -> 1125 sendMessageWithResult(message, null, error)); 1126 } 1127 }); 1128 } catch (RemoteException e) { 1129 ploge("requestSetSatelliteEnabledForCarrier: RemoteException " + e); 1130 sendMessageWithResult(message, null, 1131 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 1132 } 1133 } else { 1134 ploge("requestSetSatelliteEnabledForCarrier: Satellite service is unavailable."); 1135 sendMessageWithResult(message, null, 1136 SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED); 1137 } 1138 } 1139 1140 /** 1141 * Check whether satellite is enabled in the cellular modem associated with a carrier. 1142 * 1143 * @param simSlot Indicates the SIM slot to which this API will be applied. The modem will use 1144 * this information to determine the relevant carrier. 1145 * @param message The Message to send to result of the operation to. 1146 */ requestIsSatelliteEnabledForCarrier(@onNull int simSlot, @NonNull Message message)1147 public void requestIsSatelliteEnabledForCarrier(@NonNull int simSlot, 1148 @NonNull Message message) { 1149 if (mSatelliteService != null) { 1150 try { 1151 mSatelliteService.requestIsSatelliteEnabledForCarrier(simSlot, 1152 new IIntegerConsumer.Stub() { 1153 @Override 1154 public void accept(int result) { 1155 int error = SatelliteServiceUtils.fromSatelliteError(result); 1156 plogd("requestIsSatelliteEnabledForCarrier: " + error); 1157 Binder.withCleanCallingIdentity(() -> 1158 sendMessageWithResult(message, null, error)); 1159 } 1160 }, new IBooleanConsumer.Stub() { 1161 @Override 1162 public void accept(boolean result) { 1163 plogd("requestIsSatelliteEnabledForCarrier: " + result); 1164 Binder.withCleanCallingIdentity(() -> sendMessageWithResult( 1165 message, result, 1166 SatelliteManager.SATELLITE_RESULT_SUCCESS)); 1167 } 1168 }); 1169 } catch (RemoteException e) { 1170 ploge("requestIsSatelliteEnabledForCarrier: RemoteException " + e); 1171 sendMessageWithResult(message, null, 1172 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 1173 } 1174 } else { 1175 ploge("requestIsSatelliteEnabledForCarrier: Satellite service is unavailable."); 1176 sendMessageWithResult(message, null, 1177 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 1178 } 1179 } 1180 1181 /** 1182 * Request to get the signal strength of the satellite connection. 1183 * 1184 * @param message The Message to send to result of the operation to. 1185 */ requestNtnSignalStrength(@onNull Message message)1186 public void requestNtnSignalStrength(@NonNull Message message) { 1187 if (mSatelliteService != null) { 1188 try { 1189 mSatelliteService.requestSignalStrength( 1190 new IIntegerConsumer.Stub() { 1191 @Override 1192 public void accept(int result) { 1193 int error = SatelliteServiceUtils.fromSatelliteError(result); 1194 plogd("requestNtnSignalStrength: " + error); 1195 Binder.withCleanCallingIdentity(() -> 1196 sendMessageWithResult(message, null, error)); 1197 } 1198 }, new INtnSignalStrengthConsumer.Stub() { 1199 @Override 1200 public void accept( 1201 android.telephony.satellite.stub.NtnSignalStrength result) { 1202 NtnSignalStrength ntnSignalStrength = 1203 SatelliteServiceUtils.fromNtnSignalStrength(result); 1204 plogd("requestNtnSignalStrength: " + ntnSignalStrength); 1205 Binder.withCleanCallingIdentity(() -> sendMessageWithResult( 1206 message, ntnSignalStrength, 1207 SatelliteManager.SATELLITE_RESULT_SUCCESS)); 1208 } 1209 }); 1210 } catch (RemoteException e) { 1211 ploge("requestNtnSignalStrength: RemoteException " + e); 1212 sendMessageWithResult(message, null, 1213 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 1214 } 1215 } else { 1216 ploge("requestNtnSignalStrength: Satellite service is unavailable."); 1217 sendMessageWithResult(message, null, 1218 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 1219 } 1220 } 1221 1222 /** 1223 * The satellite service should report the NTN signal strength via 1224 * ISatelliteListener#onNtnSignalStrengthChanged when the NTN signal strength changes. 1225 * 1226 * @param message The Message to send to result of the operation to. 1227 */ startSendingNtnSignalStrength(@onNull Message message)1228 public void startSendingNtnSignalStrength(@NonNull Message message) { 1229 if (mSatelliteService != null) { 1230 try { 1231 mSatelliteService.startSendingNtnSignalStrength(new IIntegerConsumer.Stub() { 1232 @Override 1233 public void accept(int result) { 1234 int error = SatelliteServiceUtils.fromSatelliteError(result); 1235 plogd("startSendingNtnSignalStrength: " + error); 1236 Binder.withCleanCallingIdentity(() -> 1237 sendMessageWithResult(message, null, error)); 1238 } 1239 }); 1240 } catch (RemoteException e) { 1241 ploge("startSendingNtnSignalStrength: RemoteException " + e); 1242 sendMessageWithResult(message, null, 1243 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 1244 } 1245 } else { 1246 ploge("startSendingNtnSignalStrength: Satellite service is unavailable."); 1247 sendMessageWithResult(message, null, 1248 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 1249 } 1250 } 1251 1252 /** 1253 * The satellite service should stop reporting NTN signal strength to the framework. 1254 * 1255 * @param message The Message to send to result of the operation to. 1256 */ stopSendingNtnSignalStrength(@onNull Message message)1257 public void stopSendingNtnSignalStrength(@NonNull Message message) { 1258 if (mSatelliteService != null) { 1259 try { 1260 mSatelliteService.stopSendingNtnSignalStrength(new IIntegerConsumer.Stub() { 1261 @Override 1262 public void accept(int result) { 1263 int error = SatelliteServiceUtils.fromSatelliteError(result); 1264 plogd("stopSendingNtnSignalStrength: " + error); 1265 Binder.withCleanCallingIdentity(() -> 1266 sendMessageWithResult(message, null, error)); 1267 } 1268 }); 1269 } catch (RemoteException e) { 1270 ploge("stopSendingNtnSignalStrength: RemoteException " + e); 1271 sendMessageWithResult(message, null, 1272 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 1273 } 1274 } else { 1275 ploge("stopSendingNtnSignalStrength: Satellite service is unavailable."); 1276 sendMessageWithResult(message, null, 1277 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 1278 } 1279 } 1280 1281 /** 1282 * The satellite service should abort all datagram-sending requests. 1283 * 1284 * @param message The Message to send to result of the operation to. 1285 */ abortSendingSatelliteDatagrams(@onNull Message message)1286 public void abortSendingSatelliteDatagrams(@NonNull Message message) { 1287 if (mSatelliteService != null) { 1288 try { 1289 mSatelliteService.abortSendingSatelliteDatagrams(new IIntegerConsumer.Stub() { 1290 @Override 1291 public void accept(int result) { 1292 int error = SatelliteServiceUtils.fromSatelliteError(result); 1293 plogd("abortSendingSatelliteDatagrams: " + error); 1294 Binder.withCleanCallingIdentity(() -> 1295 sendMessageWithResult(message, null, error)); 1296 } 1297 }); 1298 } catch (RemoteException e) { 1299 ploge("abortSendingSatelliteDatagrams: RemoteException " + e); 1300 sendMessageWithResult(message, null, 1301 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 1302 } 1303 } else { 1304 ploge("abortSendingSatelliteDatagrams: Satellite service is unavailable."); 1305 sendMessageWithResult(message, null, 1306 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 1307 } 1308 } 1309 isSatelliteServiceSupported()1310 public boolean isSatelliteServiceSupported() { 1311 return mIsSatelliteServiceSupported; 1312 } 1313 1314 /** Check if vendor satellite service is connected */ isSatelliteServiceConnected()1315 public boolean isSatelliteServiceConnected() { 1316 synchronized (mLock) { 1317 return (mSatelliteService != null); 1318 } 1319 } 1320 1321 /** 1322 * Provision UUID with a satellite provider. 1323 */ updateSatelliteSubscription(@onNull String iccId, @NonNull Message message)1324 public void updateSatelliteSubscription(@NonNull String iccId, @NonNull Message message) { 1325 if (mSatelliteService != null) { 1326 try { 1327 mSatelliteService.updateSatelliteSubscription(iccId, 1328 new IIntegerConsumer.Stub() { 1329 @Override 1330 public void accept(int result) { 1331 int error = SatelliteServiceUtils.fromSatelliteError(result); 1332 plogd("updateSatelliteSubscription: " + error); 1333 Binder.withCleanCallingIdentity(() -> 1334 sendMessageWithResult(message, null, error)); 1335 } 1336 }); 1337 } catch (RemoteException e) { 1338 ploge("updateSatelliteSubscription: RemoteException " + e); 1339 sendMessageWithResult(message, null, 1340 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 1341 } 1342 } else { 1343 ploge("updateSatelliteSubscription: Satellite service is unavailable."); 1344 sendMessageWithResult(message, null, 1345 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 1346 } 1347 } 1348 1349 /** 1350 * This API can be used by only CTS to update satellite vendor service package name. 1351 * 1352 * @param servicePackageName The package name of the satellite vendor service. 1353 * @return {@code true} if the satellite vendor service is set successfully, 1354 * {@code false} otherwise. 1355 */ 1356 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) setSatelliteServicePackageName(@ullable String servicePackageName)1357 public void setSatelliteServicePackageName(@Nullable String servicePackageName) { 1358 plogd("setSatelliteServicePackageName: config_satellite_service_package is " 1359 + "updated, new packageName=" + servicePackageName); 1360 mExponentialBackoff.stop(); 1361 if (mSatelliteServiceConnection != null) { 1362 synchronized (mLock) { 1363 mIsBound = false; 1364 mIsBinding = false; 1365 } 1366 unbindService(); 1367 } 1368 1369 if (servicePackageName == null || servicePackageName.equals("null")) { 1370 mVendorSatellitePackageName = ""; 1371 } else { 1372 mVendorSatellitePackageName = servicePackageName; 1373 } 1374 mIsSatelliteServiceSupported = getSatelliteServiceSupport(); 1375 bindService(); 1376 mExponentialBackoff.start(); 1377 } 1378 1379 /** 1380 * Request to update system selection channels 1381 * 1382 * @param systemSelectionSpecifiers system selection specifiers 1383 * @param message The Message to send to result of the operation to. 1384 */ updateSystemSelectionChannels( @onNull List<SystemSelectionSpecifier> systemSelectionSpecifiers, @Nullable Message message)1385 public void updateSystemSelectionChannels( 1386 @NonNull List<SystemSelectionSpecifier> systemSelectionSpecifiers, 1387 @Nullable Message message) { 1388 plogd("updateSystemSelectionChannels: SystemSelectionSpecifier: " 1389 + systemSelectionSpecifiers.toString()); 1390 if (mSatelliteService != null) { 1391 try { 1392 mSatelliteService.updateSystemSelectionChannels(SatelliteServiceUtils 1393 .toSystemSelectionSpecifier(systemSelectionSpecifiers), 1394 new IIntegerConsumer.Stub() { 1395 @Override 1396 public void accept(int result) { 1397 int error = SatelliteServiceUtils.fromSatelliteError(result); 1398 plogd("updateSystemSelectionChannels: " + error); 1399 Binder.withCleanCallingIdentity(() -> 1400 sendMessageWithResult(message, null, error)); 1401 } 1402 }); 1403 } catch (RemoteException e) { 1404 ploge("updateSystemSelectionChannels: RemoteException " + e); 1405 sendMessageWithResult(message, null, 1406 SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR); 1407 } 1408 } else { 1409 ploge("updateSystemSelectionChannels: Satellite service is unavailable."); 1410 sendMessageWithResult(message, null, 1411 SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE); 1412 } 1413 } 1414 1415 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) sendMessageWithResult(@onNull Message message, @Nullable Object result, @SatelliteManager.SatelliteResult int error)1416 protected static void sendMessageWithResult(@NonNull Message message, @Nullable Object result, 1417 @SatelliteManager.SatelliteResult int error) { 1418 SatelliteException exception = error == SatelliteManager.SATELLITE_RESULT_SUCCESS 1419 ? null : new SatelliteException(error); 1420 AsyncResult.forMessage(message, result, exception); 1421 message.sendToTarget(); 1422 } 1423 logd(@onNull String log)1424 private static void logd(@NonNull String log) { 1425 Log.d(TAG, log); 1426 } 1427 loge(@onNull String log)1428 private static void loge(@NonNull String log) { 1429 Log.e(TAG, log); 1430 } 1431 plogd(@onNull String log)1432 private void plogd(@NonNull String log) { 1433 Log.d(TAG, log); 1434 if (mPersistentLogger != null) { 1435 mPersistentLogger.debug(TAG, log); 1436 } 1437 } 1438 ploge(@onNull String log)1439 private void ploge(@NonNull String log) { 1440 Log.e(TAG, log); 1441 if (mPersistentLogger != null) { 1442 mPersistentLogger.error(TAG, log); 1443 } 1444 } 1445 } 1446