1 /* 2 * Copyright (C) 2024 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.testapps.satellitetestapp; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.content.Intent; 22 import android.os.Binder; 23 import android.os.IBinder; 24 import android.telephony.IBooleanConsumer; 25 import android.telephony.IIntegerConsumer; 26 import android.telephony.satellite.AntennaDirection; 27 import android.telephony.satellite.AntennaPosition; 28 import android.telephony.satellite.SatelliteManager; 29 import android.telephony.satellite.stub.ISatelliteCapabilitiesConsumer; 30 import android.telephony.satellite.stub.ISatelliteListener; 31 import android.telephony.satellite.stub.NTRadioTechnology; 32 import android.telephony.satellite.stub.PointingInfo; 33 import android.telephony.satellite.stub.SatelliteCapabilities; 34 import android.telephony.satellite.stub.SatelliteDatagram; 35 import android.telephony.satellite.stub.SatelliteImplBase; 36 import android.telephony.satellite.stub.SatelliteModemState; 37 import android.telephony.satellite.stub.SatelliteResult; 38 import android.telephony.satellite.stub.SatelliteService; 39 import android.telephony.satellite.stub.SystemSelectionSpecifier; 40 import android.util.Log; 41 42 import com.android.internal.util.FunctionalUtils; 43 import com.android.telephony.Rlog; 44 45 import java.util.ArrayList; 46 import java.util.HashMap; 47 import java.util.List; 48 import java.util.Map; 49 import java.util.concurrent.Executor; 50 import java.util.concurrent.atomic.AtomicBoolean; 51 52 /** 53 * Test service for Satellite to verify end to end flow via testapp. 54 */ 55 public class TestSatelliteService extends SatelliteImplBase { 56 private static final String TAG = "TestSatelliteService"; 57 58 // Hardcoded values below 59 private static final int SATELLITE_ALWAYS_VISIBLE = 0; 60 /** SatelliteCapabilities constant indicating that the radio technology is proprietary. */ 61 private static final int[] SUPPORTED_RADIO_TECHNOLOGIES = 62 new int[]{NTRadioTechnology.PROPRIETARY}; 63 /** SatelliteCapabilities constant indicating that pointing to satellite is required. */ 64 private static final boolean POINTING_TO_SATELLITE_REQUIRED = true; 65 /** SatelliteCapabilities constant indicating the maximum number of characters per datagram. */ 66 private static final int MAX_BYTES_PER_DATAGRAM = 339; 67 /** SatelliteCapabilities constant keys which are used to fill mAntennaPositionMap. */ 68 private static final int[] ANTENNA_POSITION_KEYS = new int[]{ 69 SatelliteManager.DISPLAY_MODE_OPENED, SatelliteManager.DISPLAY_MODE_CLOSED}; 70 /** SatelliteCapabilities constant values which are used to fill mAntennaPositionMap. */ 71 private static final AntennaPosition[] ANTENNA_POSITION_VALUES = new AntennaPosition[] { 72 new AntennaPosition(new AntennaDirection(1, 1, 1), 73 SatelliteManager.DEVICE_HOLD_POSITION_PORTRAIT), 74 new AntennaPosition(new AntennaDirection(2, 2, 2), 75 SatelliteManager.DEVICE_HOLD_POSITION_LANDSCAPE_LEFT) 76 }; 77 78 @NonNull 79 private final Map<IBinder, ISatelliteListener> mRemoteListeners = new HashMap<>(); 80 @Nullable private ILocalSatelliteListener mLocalListener; 81 private final LocalBinder mBinder = new LocalBinder(); 82 @SatelliteResult 83 private int mErrorCode = SatelliteResult.SATELLITE_RESULT_SUCCESS; 84 private final AtomicBoolean mShouldNotifyRemoteServiceConnected = 85 new AtomicBoolean(false); 86 87 // For local access of this Service. 88 class LocalBinder extends Binder { getService()89 TestSatelliteService getService() { 90 return TestSatelliteService.this; 91 } 92 } 93 94 private boolean mIsCommunicationAllowedInLocation; 95 private boolean mIsEnabled; 96 private boolean mIsProvisioned; 97 private boolean mIsSupported; 98 private int mModemState; 99 private boolean mIsCellularModemEnabledMode; 100 private List<String> mCarrierPlmnList = new ArrayList<>(); 101 private List<String> mAllPlmnList = new ArrayList<>(); 102 private boolean mIsSatelliteEnabledForCarrier; 103 private boolean mIsRequestIsSatelliteEnabledForCarrier; 104 private boolean mIsEmergnecy; 105 106 /** 107 * Create TestSatelliteService using the Executor specified for methods being called from 108 * the framework. 109 * 110 * @param executor The executor for the framework to use when executing satellite methods. 111 */ TestSatelliteService(@onNull Executor executor)112 public TestSatelliteService(@NonNull Executor executor) { 113 super(executor); 114 mIsCommunicationAllowedInLocation = true; 115 mIsEnabled = false; 116 mIsProvisioned = false; 117 mIsSupported = true; 118 mModemState = SatelliteModemState.SATELLITE_MODEM_STATE_OFF; 119 mIsCellularModemEnabledMode = false; 120 mIsSatelliteEnabledForCarrier = false; 121 mIsRequestIsSatelliteEnabledForCarrier = false; 122 mIsEmergnecy = false; 123 } 124 125 /** 126 * Zero-argument constructor to prevent service binding exception. 127 */ TestSatelliteService()128 public TestSatelliteService() { 129 this(Runnable::run); 130 } 131 132 @Override onBind(Intent intent)133 public IBinder onBind(Intent intent) { 134 if (SatelliteService.SERVICE_INTERFACE.equals(intent.getAction())) { 135 logd("Remote service bound"); 136 return getBinder(); 137 } 138 logd("Local service bound"); 139 return mBinder; 140 } 141 142 @Override onCreate()143 public void onCreate() { 144 super.onCreate(); 145 logd("onCreate"); 146 } 147 148 @Override onDestroy()149 public void onDestroy() { 150 super.onDestroy(); 151 logd("onDestroy"); 152 } 153 154 @Override setSatelliteListener(@onNull ISatelliteListener listener)155 public void setSatelliteListener(@NonNull ISatelliteListener listener) { 156 logd("setSatelliteListener"); 157 mRemoteListeners.put(listener.asBinder(), listener); 158 notifyRemoteServiceConnected(); 159 } 160 161 @Override requestSatelliteListeningEnabled(boolean enabled, int timeout, @NonNull IIntegerConsumer errorCallback)162 public void requestSatelliteListeningEnabled(boolean enabled, int timeout, 163 @NonNull IIntegerConsumer errorCallback) { 164 logd("requestSatelliteListeningEnabled: mErrorCode=" + mErrorCode); 165 166 if (mLocalListener != null) { 167 runWithExecutor(() -> mLocalListener.onSatelliteListeningEnabled(enabled)); 168 } else { 169 loge("requestSatelliteListeningEnabled: mLocalListener is null"); 170 } 171 172 if (!verifySatelliteModemState(errorCallback)) { 173 return; 174 } 175 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 176 runWithExecutor(() -> errorCallback.accept(mErrorCode)); 177 return; 178 } 179 180 if (enabled) { 181 updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_LISTENING); 182 } else { 183 updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_IDLE); 184 } 185 runWithExecutor(() -> errorCallback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS)); 186 } 187 188 @Override requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode, boolean isEmergency, @NonNull IIntegerConsumer errorCallback)189 public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode, 190 boolean isEmergency, @NonNull IIntegerConsumer errorCallback) { 191 logd("requestSatelliteEnabled: mErrorCode=" + mErrorCode + " enable = " + enableSatellite 192 + " isEmergency=" + isEmergency); 193 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 194 runWithExecutor(() -> errorCallback.accept(mErrorCode)); 195 return; 196 } 197 198 if (enableSatellite) { 199 enableSatellite(errorCallback); 200 } else { 201 disableSatellite(errorCallback); 202 } 203 mIsEmergnecy = isEmergency; 204 } 205 enableSatellite(@onNull IIntegerConsumer errorCallback)206 private void enableSatellite(@NonNull IIntegerConsumer errorCallback) { 207 mIsEnabled = true; 208 updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_IDLE); 209 runWithExecutor(() -> errorCallback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS)); 210 } 211 disableSatellite(@onNull IIntegerConsumer errorCallback)212 private void disableSatellite(@NonNull IIntegerConsumer errorCallback) { 213 mIsEnabled = false; 214 updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_OFF); 215 runWithExecutor(() -> errorCallback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS)); 216 } 217 218 @Override requestIsSatelliteEnabled(@onNull IIntegerConsumer errorCallback, @NonNull IBooleanConsumer callback)219 public void requestIsSatelliteEnabled(@NonNull IIntegerConsumer errorCallback, 220 @NonNull IBooleanConsumer callback) { 221 logd("requestIsSatelliteEnabled: mErrorCode=" + mErrorCode); 222 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 223 runWithExecutor(() -> errorCallback.accept(mErrorCode)); 224 return; 225 } 226 runWithExecutor(() -> callback.accept(mIsEnabled)); 227 } 228 229 @Override requestIsSatelliteSupported(@onNull IIntegerConsumer errorCallback, @NonNull IBooleanConsumer callback)230 public void requestIsSatelliteSupported(@NonNull IIntegerConsumer errorCallback, 231 @NonNull IBooleanConsumer callback) { 232 logd("requestIsSatelliteSupported"); 233 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 234 runWithExecutor(() -> errorCallback.accept(mErrorCode)); 235 return; 236 } 237 runWithExecutor(() -> callback.accept(mIsSupported)); 238 } 239 240 @Override requestSatelliteCapabilities(@onNull IIntegerConsumer errorCallback, @NonNull ISatelliteCapabilitiesConsumer callback)241 public void requestSatelliteCapabilities(@NonNull IIntegerConsumer errorCallback, 242 @NonNull ISatelliteCapabilitiesConsumer callback) { 243 logd("requestSatelliteCapabilities: mErrorCode=" + mErrorCode); 244 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 245 runWithExecutor(() -> errorCallback.accept(mErrorCode)); 246 return; 247 } 248 249 SatelliteCapabilities capabilities = new SatelliteCapabilities(); 250 capabilities.supportedRadioTechnologies = SUPPORTED_RADIO_TECHNOLOGIES; 251 capabilities.isPointingRequired = POINTING_TO_SATELLITE_REQUIRED; 252 capabilities.maxBytesPerOutgoingDatagram = MAX_BYTES_PER_DATAGRAM; 253 capabilities.antennaPositionKeys = ANTENNA_POSITION_KEYS; 254 capabilities.antennaPositionValues = ANTENNA_POSITION_VALUES; 255 runWithExecutor(() -> callback.accept(capabilities)); 256 } 257 258 @Override startSendingSatellitePointingInfo(@onNull IIntegerConsumer errorCallback)259 public void startSendingSatellitePointingInfo(@NonNull IIntegerConsumer errorCallback) { 260 logd("startSendingSatellitePointingInfo: mErrorCode=" + mErrorCode); 261 if (!verifySatelliteModemState(errorCallback)) { 262 if (mLocalListener != null) { 263 runWithExecutor(() -> mLocalListener.onStartSendingSatellitePointingInfo()); 264 } else { 265 loge("startSendingSatellitePointingInfo: mLocalListener is null"); 266 } 267 return; 268 } 269 270 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 271 runWithExecutor(() -> errorCallback.accept(mErrorCode)); 272 } else { 273 runWithExecutor(() -> errorCallback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS)); 274 } 275 276 if (mLocalListener != null) { 277 runWithExecutor(() -> mLocalListener.onStartSendingSatellitePointingInfo()); 278 } else { 279 loge("startSendingSatellitePointingInfo: mLocalListener is null"); 280 } 281 } 282 283 @Override stopSendingSatellitePointingInfo(@onNull IIntegerConsumer errorCallback)284 public void stopSendingSatellitePointingInfo(@NonNull IIntegerConsumer errorCallback) { 285 logd("stopSendingSatellitePointingInfo: mErrorCode=" + mErrorCode); 286 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 287 runWithExecutor(() -> errorCallback.accept(mErrorCode)); 288 } else { 289 runWithExecutor(() -> errorCallback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS)); 290 } 291 292 if (mLocalListener != null) { 293 runWithExecutor(() -> mLocalListener.onStopSendingSatellitePointingInfo()); 294 } else { 295 loge("stopSendingSatellitePointingInfo: mLocalListener is null"); 296 } 297 } 298 299 @Override provisionSatelliteService(@onNull String token, @NonNull byte[] provisionData, @NonNull IIntegerConsumer errorCallback)300 public void provisionSatelliteService(@NonNull String token, @NonNull byte[] provisionData, 301 @NonNull IIntegerConsumer errorCallback) { 302 logd("provisionSatelliteService: mErrorCode=" + mErrorCode); 303 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 304 runWithExecutor(() -> errorCallback.accept(mErrorCode)); 305 return; 306 } 307 runWithExecutor(() -> errorCallback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS)); 308 updateSatelliteProvisionState(true); 309 } 310 311 @Override deprovisionSatelliteService(@onNull String token, @NonNull IIntegerConsumer errorCallback)312 public void deprovisionSatelliteService(@NonNull String token, 313 @NonNull IIntegerConsumer errorCallback) { 314 logd("deprovisionSatelliteService: mErrorCode=" + mErrorCode); 315 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 316 runWithExecutor(() -> errorCallback.accept(mErrorCode)); 317 return; 318 } 319 runWithExecutor(() -> errorCallback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS)); 320 updateSatelliteProvisionState(false); 321 } 322 323 @Override requestIsSatelliteProvisioned(@onNull IIntegerConsumer errorCallback, @NonNull IBooleanConsumer callback)324 public void requestIsSatelliteProvisioned(@NonNull IIntegerConsumer errorCallback, 325 @NonNull IBooleanConsumer callback) { 326 logd("requestIsSatelliteProvisioned: mErrorCode=" + mErrorCode); 327 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 328 runWithExecutor(() -> errorCallback.accept(mErrorCode)); 329 return; 330 } 331 runWithExecutor(() -> callback.accept(mIsProvisioned)); 332 } 333 334 @Override pollPendingSatelliteDatagrams(@onNull IIntegerConsumer errorCallback)335 public void pollPendingSatelliteDatagrams(@NonNull IIntegerConsumer errorCallback) { 336 logd("pollPendingSatelliteDatagrams: mErrorCode=" + mErrorCode); 337 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 338 runWithExecutor(() -> errorCallback.accept(mErrorCode)); 339 } else { 340 runWithExecutor(() -> errorCallback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS)); 341 } 342 343 if (mLocalListener != null) { 344 runWithExecutor(() -> mLocalListener.onPollPendingSatelliteDatagrams()); 345 } else { 346 loge("pollPendingDatagrams: mLocalListener is null"); 347 } 348 } 349 350 @Override sendSatelliteDatagram(@onNull SatelliteDatagram datagram, boolean isEmergency, @NonNull IIntegerConsumer errorCallback)351 public void sendSatelliteDatagram(@NonNull SatelliteDatagram datagram, boolean isEmergency, 352 @NonNull IIntegerConsumer errorCallback) { 353 logd("sendDatagram: mErrorCode=" + mErrorCode); 354 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 355 runWithExecutor(() -> errorCallback.accept(mErrorCode)); 356 } else { 357 runWithExecutor(() -> errorCallback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS)); 358 } 359 360 if (mLocalListener != null) { 361 runWithExecutor(() -> mLocalListener.onSendSatelliteDatagram(datagram, isEmergency)); 362 } else { 363 loge("sendDatagram: mLocalListener is null"); 364 } 365 } 366 367 @Override requestSatelliteModemState(@onNull IIntegerConsumer errorCallback, @NonNull IIntegerConsumer callback)368 public void requestSatelliteModemState(@NonNull IIntegerConsumer errorCallback, 369 @NonNull IIntegerConsumer callback) { 370 logd("requestSatelliteModemState: mErrorCode=" + mErrorCode); 371 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 372 runWithExecutor(() -> errorCallback.accept(mErrorCode)); 373 return; 374 } 375 runWithExecutor(() -> callback.accept(mModemState)); 376 } 377 378 @Override requestTimeForNextSatelliteVisibility(@onNull IIntegerConsumer errorCallback, @NonNull IIntegerConsumer callback)379 public void requestTimeForNextSatelliteVisibility(@NonNull IIntegerConsumer errorCallback, 380 @NonNull IIntegerConsumer callback) { 381 logd("requestTimeForNextSatelliteVisibility: mErrorCode=" + mErrorCode); 382 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 383 runWithExecutor(() -> errorCallback.accept(mErrorCode)); 384 return; 385 } 386 runWithExecutor(() -> callback.accept(SATELLITE_ALWAYS_VISIBLE)); 387 } 388 389 @Override setSatellitePlmn(int simLogicalSlotIndex, List<String> carrierPlmnList, List<String> allSatellitePlmnList, IIntegerConsumer resultCallback)390 public void setSatellitePlmn(int simLogicalSlotIndex, List<String> carrierPlmnList, 391 List<String> allSatellitePlmnList, IIntegerConsumer resultCallback) { 392 logd("setSatellitePlmn: simLogicalSlotIndex=" + simLogicalSlotIndex + " , carrierPlmnList=" 393 + carrierPlmnList + " , allSatellitePlmnList=" + allSatellitePlmnList); 394 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 395 runWithExecutor(() -> resultCallback.accept(mErrorCode)); 396 return; 397 } 398 runWithExecutor(() -> resultCallback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS)); 399 400 mCarrierPlmnList = carrierPlmnList; 401 mAllPlmnList = allSatellitePlmnList; 402 403 if (mLocalListener != null) { 404 runWithExecutor(() -> mLocalListener.onSetSatellitePlmn()); 405 } else { 406 loge("setSatellitePlmn: mLocalListener is null"); 407 } 408 } 409 410 @Override setSatelliteEnabledForCarrier(int simLogicalSlotIndex, boolean satelliteEnabled, IIntegerConsumer callback)411 public void setSatelliteEnabledForCarrier(int simLogicalSlotIndex, boolean satelliteEnabled, 412 IIntegerConsumer callback) { 413 logd("setSatelliteEnabledForCarrier: simLogicalSlotIndex=" + simLogicalSlotIndex 414 + ", satelliteEnabled=" + satelliteEnabled); 415 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 416 runWithExecutor(() -> callback.accept(mErrorCode)); 417 return; 418 } 419 420 mIsSatelliteEnabledForCarrier = satelliteEnabled; 421 runWithExecutor(() -> callback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS)); 422 } 423 424 @Override requestIsSatelliteEnabledForCarrier(int simLogicalSlotIndex, IIntegerConsumer resultCallback, IBooleanConsumer callback)425 public void requestIsSatelliteEnabledForCarrier(int simLogicalSlotIndex, 426 IIntegerConsumer resultCallback, IBooleanConsumer callback) { 427 logd("requestIsSatelliteEnabledForCarrier: simLogicalSlotIndex=" + simLogicalSlotIndex); 428 if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) { 429 runWithExecutor(() -> resultCallback.accept(mErrorCode)); 430 mIsRequestIsSatelliteEnabledForCarrier = false; 431 return; 432 } 433 434 runWithExecutor(() -> callback.accept(mIsSatelliteEnabledForCarrier)); 435 mIsRequestIsSatelliteEnabledForCarrier = true; 436 } 437 438 @Override updateSatelliteSubscription(@onNull String iccId, @NonNull IIntegerConsumer resultCallback)439 public void updateSatelliteSubscription(@NonNull String iccId, 440 @NonNull IIntegerConsumer resultCallback) { 441 logd("updateSatelliteSubscription: iccId=" + iccId + " mErrorCode=" + mErrorCode); 442 runWithExecutor(() -> resultCallback.accept(mErrorCode)); 443 } 444 445 @Override updateSystemSelectionChannels( @onNull List<SystemSelectionSpecifier> systemSelectionSpecifiers, @NonNull IIntegerConsumer resultCallback)446 public void updateSystemSelectionChannels( 447 @NonNull List<SystemSelectionSpecifier> systemSelectionSpecifiers, 448 @NonNull IIntegerConsumer resultCallback) { 449 logd(" updateSystemSelectionChannels: " 450 + "systemSelectionSpecifiers=" + systemSelectionSpecifiers 451 + " mErrorCode=" + mErrorCode); 452 runWithExecutor(() -> resultCallback.accept(mErrorCode)); 453 } 454 setLocalSatelliteListener(@onNull ILocalSatelliteListener listener)455 public void setLocalSatelliteListener(@NonNull ILocalSatelliteListener listener) { 456 logd("setLocalSatelliteListener: listener=" + listener); 457 mLocalListener = listener; 458 if (mShouldNotifyRemoteServiceConnected.get()) { 459 notifyRemoteServiceConnected(); 460 } 461 } 462 setErrorCode(@atelliteResult int errorCode)463 public void setErrorCode(@SatelliteResult int errorCode) { 464 logd("setErrorCode: errorCode=" + errorCode); 465 mErrorCode = errorCode; 466 } 467 setSatelliteSupport(boolean supported)468 public void setSatelliteSupport(boolean supported) { 469 logd("setSatelliteSupport: supported=" + supported); 470 mIsSupported = supported; 471 } 472 sendOnSatelliteDatagramReceived(SatelliteDatagram datagram, int pendingCount)473 public void sendOnSatelliteDatagramReceived(SatelliteDatagram datagram, int pendingCount) { 474 logd("sendOnSatelliteDatagramReceived"); 475 mRemoteListeners.values().forEach(listener -> runWithExecutor(() -> 476 listener.onSatelliteDatagramReceived(datagram, pendingCount))); 477 } 478 sendOnPendingDatagrams()479 public void sendOnPendingDatagrams() { 480 logd("sendOnPendingDatagrams"); 481 mRemoteListeners.values().forEach(listener -> runWithExecutor(() -> 482 listener.onPendingDatagrams())); 483 } 484 sendOnSatellitePositionChanged(PointingInfo pointingInfo)485 public void sendOnSatellitePositionChanged(PointingInfo pointingInfo) { 486 logd("sendOnSatellitePositionChanged"); 487 mRemoteListeners.values().forEach(listener -> runWithExecutor(() -> 488 listener.onSatellitePositionChanged(pointingInfo))); 489 } 490 491 /** 492 * Helper method to report satellite supported from modem side for testing purpose. 493 * @param supported whether satellite is supported from modem or not. 494 */ sendOnSatelliteSupportedStateChanged(boolean supported)495 public void sendOnSatelliteSupportedStateChanged(boolean supported) { 496 logd("sendOnSatelliteSupportedStateChanged: supported=" + supported); 497 mRemoteListeners.values().forEach(listener -> runWithExecutor(() -> 498 listener.onSatelliteSupportedStateChanged(supported))); 499 } 500 501 /** 502 * Helper method to verify that the satellite modem is properly configured to receive 503 * requests. 504 * 505 * @param errorCallback The callback to notify of any errors preventing satellite requests. 506 * @return {@code true} if the satellite modem is configured to receive requests and 507 * {@code false} if it is not. 508 */ verifySatelliteModemState(@onNull IIntegerConsumer errorCallback)509 private boolean verifySatelliteModemState(@NonNull IIntegerConsumer errorCallback) { 510 if (!mIsSupported) { 511 runWithExecutor(() -> errorCallback.accept( 512 SatelliteResult.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)); 513 return false; 514 } 515 if (!mIsProvisioned) { 516 runWithExecutor(() -> errorCallback.accept( 517 SatelliteResult.SATELLITE_RESULT_SERVICE_NOT_PROVISIONED)); 518 return false; 519 } 520 if (!mIsEnabled) { 521 runWithExecutor(() -> errorCallback.accept( 522 SatelliteResult.SATELLITE_RESULT_INVALID_MODEM_STATE)); 523 return false; 524 } 525 return true; 526 } 527 528 /** 529 * Update the satellite modem state and notify listeners if it changed. 530 * 531 * @param modemState The {@link SatelliteModemState} to update. 532 */ updateSatelliteModemState(int modemState)533 private void updateSatelliteModemState(int modemState) { 534 if (modemState == mModemState) { 535 return; 536 } 537 if (mIsCellularModemEnabledMode 538 && modemState == SatelliteModemState.SATELLITE_MODEM_STATE_OFF) { 539 logd("Not updating the Modem state to Off as it is in CellularModemEnabledMode"); 540 return; 541 } 542 mRemoteListeners.values().forEach(listener -> runWithExecutor(() -> 543 listener.onSatelliteModemStateChanged(modemState))); 544 mModemState = modemState; 545 } 546 547 /** 548 * Update the satellite provision state and notify listeners if it changed. 549 * 550 * @param isProvisioned {@code true} if the satellite is currently provisioned and 551 * {@code false} if it is not. 552 */ updateSatelliteProvisionState(boolean isProvisioned)553 private void updateSatelliteProvisionState(boolean isProvisioned) { 554 logd("updateSatelliteProvisionState: isProvisioned=" + isProvisioned 555 + ", mIsProvisioned=" + mIsProvisioned); 556 if (isProvisioned == mIsProvisioned) { 557 return; 558 } 559 mIsProvisioned = isProvisioned; 560 logd("updateSatelliteProvisionState: mRemoteListeners.size=" + mRemoteListeners.size()); 561 mRemoteListeners.values().forEach(listener -> runWithExecutor(() -> 562 listener.onSatelliteProvisionStateChanged(mIsProvisioned))); 563 } 564 565 /** 566 * Execute the given runnable using the executor that this service was created with. 567 * 568 * @param r A runnable that can throw an exception. 569 */ runWithExecutor(@onNull FunctionalUtils.ThrowingRunnable r)570 private void runWithExecutor(@NonNull FunctionalUtils.ThrowingRunnable r) { 571 mExecutor.execute(() -> Binder.withCleanCallingIdentity(r)); 572 } 573 notifyRemoteServiceConnected()574 private void notifyRemoteServiceConnected() { 575 logd("notifyRemoteServiceConnected"); 576 if (mLocalListener != null) { 577 runWithExecutor(() -> mLocalListener.onRemoteServiceConnected()); 578 mShouldNotifyRemoteServiceConnected.set(false); 579 } else { 580 mShouldNotifyRemoteServiceConnected.set(true); 581 } 582 } 583 getCarrierPlmnList()584 public List<String> getCarrierPlmnList() { 585 return mCarrierPlmnList; 586 } 587 getAllSatellitePlmnList()588 public List<String> getAllSatellitePlmnList() { 589 return mAllPlmnList; 590 } 591 isSatelliteEnabledForCarrier()592 public boolean isSatelliteEnabledForCarrier() { 593 return mIsSatelliteEnabledForCarrier; 594 } 595 isRequestIsSatelliteEnabledForCarrier()596 public boolean isRequestIsSatelliteEnabledForCarrier() { 597 return mIsRequestIsSatelliteEnabledForCarrier; 598 } 599 getIsEmergency()600 public boolean getIsEmergency() { 601 return mIsEmergnecy; 602 } 603 604 /** 605 * Helper methoid to provide a way to set supported state from test application to mock modem. 606 * @param supported whether satellite is supported by modem or not. 607 */ updateSatelliteSupportedState(boolean supported)608 public void updateSatelliteSupportedState(boolean supported) { 609 logd("updateSatelliteSupportedState: supported=" + supported); 610 mIsSupported = supported; 611 mRemoteListeners.values().forEach(listener -> runWithExecutor( 612 () -> listener.onSatelliteSupportedStateChanged(mIsSupported))); 613 614 } 615 getSatelliteSupportedState()616 public boolean getSatelliteSupportedState() { 617 return mIsSupported; 618 } 619 620 /** 621 * Log the message to the radio buffer with {@code DEBUG} priority. 622 * 623 * @param log The message to log. 624 */ logd(@onNull String log)625 private static void logd(@NonNull String log) { 626 Rlog.d(TAG, log); 627 } 628 629 /** 630 * Log with error attribute 631 * 632 * @param s is string log 633 */ loge(@onNull String s)634 protected void loge(@NonNull String s) { 635 Log.e(TAG, s); 636 } 637 } 638