Snap for 12134224 from 4ee1c609cc1c294a9e194885a79b88e5625bd31f to simpleperf-release Change-Id: Ia4daeb35a738912531e23514d02cf04f2753d340
diff --git a/satellite_client/Android.bp b/satellite_client/Android.bp index 1661dcf..89c5c4b 100644 --- a/satellite_client/Android.bp +++ b/satellite_client/Android.bp
@@ -17,6 +17,10 @@ "app-compat-annotations", "unsupportedappusage", ], + required: [ + "android.telephony.satellite.xml", + ], + provides_uses_lib: "android.telephony.satellite", optimize: { ignore_warnings: false, proguard_flags_files: ["proguard.flags"], @@ -28,5 +32,4 @@ sub_dir: "sysconfig", system_ext_specific: true, src: "android.telephony.satellite.xml", -} - +} \ No newline at end of file
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/NtnSignalStrengthCallbackWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/NtnSignalStrengthCallbackWrapper.java new file mode 100644 index 0000000..46aef62 --- /dev/null +++ b/satellite_client/src/android/telephony/satellite/wrapper/NtnSignalStrengthCallbackWrapper.java
@@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.satellite.wrapper; + +import android.annotation.FlaggedApi; +import android.annotation.NonNull; +import com.android.internal.telephony.flags.Flags; + +/** + * Encapsulates the callback class for notifying satellite signal strength change. + */ +@FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) +public interface NtnSignalStrengthCallbackWrapper { + /** + * Called when non-terrestrial network signal strength changes. + * @param ntnSignalStrength The new non-terrestrial network signal strength. + */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + void onNtnSignalStrengthChanged(@NonNull NtnSignalStrengthWrapper ntnSignalStrength); +}
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/NtnSignalStrengthWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/NtnSignalStrengthWrapper.java new file mode 100644 index 0000000..5198457 --- /dev/null +++ b/satellite_client/src/android/telephony/satellite/wrapper/NtnSignalStrengthWrapper.java
@@ -0,0 +1,67 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.satellite.wrapper; + +import android.annotation.FlaggedApi; +import android.annotation.IntDef; +import android.annotation.NonNull; +import com.android.internal.telephony.flags.Flags; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** Encapsulates the non-terrestrial network signal strength related information. */ +@FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) +public final class NtnSignalStrengthWrapper { + + /** Non-terrestrial network signal strength is not available. */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + public static final int NTN_SIGNAL_STRENGTH_NONE = 0; + /** Non-terrestrial network signal strength is poor. */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + public static final int NTN_SIGNAL_STRENGTH_POOR = 1; + /** Non-terrestrial network signal strength is moderate. */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + public static final int NTN_SIGNAL_STRENGTH_MODERATE = 2; + /** Non-terrestrial network signal strength is good. */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + public static final int NTN_SIGNAL_STRENGTH_GOOD = 3; + /** Non-terrestrial network signal strength is great. */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + public static final int NTN_SIGNAL_STRENGTH_GREAT = 4; + @NtnSignalStrengthLevel private final int mLevel; + + /** @hide */ + @IntDef(prefix = "NTN_SIGNAL_STRENGTH_", value = { + NTN_SIGNAL_STRENGTH_NONE, + NTN_SIGNAL_STRENGTH_POOR, + NTN_SIGNAL_STRENGTH_MODERATE, + NTN_SIGNAL_STRENGTH_GOOD, + NTN_SIGNAL_STRENGTH_GREAT + }) + @Retention(RetentionPolicy.SOURCE) + public @interface NtnSignalStrengthLevel {} + + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + public NtnSignalStrengthWrapper(@NonNull @NtnSignalStrengthLevel int level) { + this.mLevel = level; + } + + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + @NtnSignalStrengthLevel public int getLevel() { + return mLevel; + } +}
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteCapabilitiesCallbackWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteCapabilitiesCallbackWrapper.java new file mode 100644 index 0000000..c538608 --- /dev/null +++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteCapabilitiesCallbackWrapper.java
@@ -0,0 +1,35 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.satellite.wrapper; + +import android.annotation.FlaggedApi; +import android.annotation.NonNull; + +import com.android.internal.telephony.flags.Flags; + +/** + * A callback class for satellite capabilities change events. + */ +@FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) +public interface SatelliteCapabilitiesCallbackWrapper { + /** + * Called when satellite capability has changed. + * @param capabilities The new satellite capabilities. + */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + void onSatelliteCapabilitiesChanged(@NonNull SatelliteCapabilitiesWrapper capabilities); +}
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java index b13a0fc..d230e8f 100644 --- a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java +++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java
@@ -16,32 +16,52 @@ package android.telephony.satellite.wrapper; +import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN; +import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS; import static android.telephony.satellite.SatelliteManager.SatelliteException; import android.annotation.CallbackExecutor; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.os.CancellationSignal; import android.os.OutcomeReceiver; +import android.telephony.NetworkRegistrationInfo; +import android.telephony.ServiceState; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; import android.telephony.satellite.AntennaPosition; +import android.telephony.satellite.EnableRequestAttributes; +import android.telephony.satellite.NtnSignalStrength; +import android.telephony.satellite.NtnSignalStrengthCallback; import android.telephony.satellite.PointingInfo; import android.telephony.satellite.SatelliteCapabilities; +import android.telephony.satellite.SatelliteCapabilitiesCallback; import android.telephony.satellite.SatelliteDatagram; import android.telephony.satellite.SatelliteDatagramCallback; import android.telephony.satellite.SatelliteManager; +import android.telephony.satellite.SatelliteModemStateCallback; import android.telephony.satellite.SatelliteProvisionStateCallback; -import android.telephony.satellite.SatelliteStateCallback; import android.telephony.satellite.SatelliteTransmissionUpdateCallback; + +import com.android.internal.telephony.flags.Flags; +import com.android.telephony.Rlog; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.time.Duration; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.function.Consumer; +import java.util.stream.Collectors; /** * Wrapper for satellite operations such as provisioning, pointing, messaging, location sharing, @@ -51,24 +71,37 @@ private static final String TAG = "SatelliteManagerWrapper"; private static final ConcurrentHashMap< + SatelliteDatagramCallbackWrapper, SatelliteDatagramCallback> + sSatelliteDatagramCallbackWrapperMap = new ConcurrentHashMap<>(); + + private static final ConcurrentHashMap< SatelliteProvisionStateCallbackWrapper, SatelliteProvisionStateCallback> sSatelliteProvisionStateCallbackWrapperMap = new ConcurrentHashMap<>(); - private static final ConcurrentHashMap<SatelliteStateCallbackWrapper, SatelliteStateCallback> - sSatelliteStateCallbackWrapperMap = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap<SatelliteModemStateCallbackWrapper, + SatelliteModemStateCallback> sSatelliteModemStateCallbackWrapperMap = + new ConcurrentHashMap<>(); private static final ConcurrentHashMap< SatelliteTransmissionUpdateCallbackWrapper, SatelliteTransmissionUpdateCallback> sSatelliteTransmissionUpdateCallbackWrapperMap = new ConcurrentHashMap<>(); private static final ConcurrentHashMap< - SatelliteDatagramCallbackWrapper, SatelliteDatagramCallback> - sSatelliteDatagramCallbackWrapperMap = new ConcurrentHashMap<>(); + NtnSignalStrengthCallbackWrapper, NtnSignalStrengthCallback> + sNtnSignalStrengthCallbackWrapperMap = new ConcurrentHashMap<>(); + + private static final ConcurrentHashMap< + SatelliteCapabilitiesCallbackWrapper, SatelliteCapabilitiesCallback> + sSatelliteCapabilitiesCallbackWrapperMap = new ConcurrentHashMap<>(); private final SatelliteManager mSatelliteManager; + private final SubscriptionManager mSubscriptionManager; + private final TelephonyManager mTelephonyManager; SatelliteManagerWrapper(Context context) { - mSatelliteManager = (SatelliteManager) context.getSystemService("satellite"); + mSatelliteManager = context.getSystemService(SatelliteManager.class); + mSubscriptionManager = context.getSystemService(SubscriptionManager.class); + mTelephonyManager = context.getSystemService(TelephonyManager.class); } /** @@ -224,104 +257,107 @@ public @interface SatelliteDatagramTransferState {} /** The request was successfully processed. */ - public static final int SATELLITE_ERROR_NONE = 0; + public static final int SATELLITE_RESULT_SUCCESS = 0; /** A generic error which should be used only when other specific errors cannot be used. */ - public static final int SATELLITE_ERROR = 1; + public static final int SATELLITE_RESULT_ERROR = 1; /** Error received from the satellite server. */ - public static final int SATELLITE_SERVER_ERROR = 2; + public static final int SATELLITE_RESULT_SERVER_ERROR = 2; /** * Error received from the vendor service. This generic error code should be used only when the * error cannot be mapped to other specific service error codes. */ - public static final int SATELLITE_SERVICE_ERROR = 3; + public static final int SATELLITE_RESULT_SERVICE_ERROR = 3; /** * Error received from satellite modem. This generic error code should be used only when the error * cannot be mapped to other specific modem error codes. */ - public static final int SATELLITE_MODEM_ERROR = 4; + public static final int SATELLITE_RESULT_MODEM_ERROR = 4; /** * Error received from the satellite network. This generic error code should be used only when the * error cannot be mapped to other specific network error codes. */ - public static final int SATELLITE_NETWORK_ERROR = 5; + public static final int SATELLITE_RESULT_NETWORK_ERROR = 5; /** Telephony is not in a valid state to receive requests from clients. */ - public static final int SATELLITE_INVALID_TELEPHONY_STATE = 6; + public static final int SATELLITE_RESULT_INVALID_TELEPHONY_STATE = 6; /** Satellite modem is not in a valid state to receive requests from clients. */ - public static final int SATELLITE_INVALID_MODEM_STATE = 7; + public static final int SATELLITE_RESULT_INVALID_MODEM_STATE = 7; /** * Either vendor service, or modem, or Telephony framework has received a request with invalid * arguments from its clients. */ - public static final int SATELLITE_INVALID_ARGUMENTS = 8; + public static final int SATELLITE_RESULT_INVALID_ARGUMENTS = 8; /** * Telephony framework failed to send a request or receive a response from the vendor service or * satellite modem due to internal error. */ - public static final int SATELLITE_REQUEST_FAILED = 9; + public static final int SATELLITE_RESULT_REQUEST_FAILED = 9; /** Radio did not start or is resetting. */ - public static final int SATELLITE_RADIO_NOT_AVAILABLE = 10; + public static final int SATELLITE_RESULT_RADIO_NOT_AVAILABLE = 10; /** The request is not supported by either the satellite modem or the network. */ - public static final int SATELLITE_REQUEST_NOT_SUPPORTED = 11; + public static final int SATELLITE_RESULT_REQUEST_NOT_SUPPORTED = 11; /** Satellite modem or network has no resources available to handle requests from clients. */ - public static final int SATELLITE_NO_RESOURCES = 12; + public static final int SATELLITE_RESULT_NO_RESOURCES = 12; /** Satellite service is not provisioned yet. */ - public static final int SATELLITE_SERVICE_NOT_PROVISIONED = 13; + public static final int SATELLITE_RESULT_SERVICE_NOT_PROVISIONED = 13; /** Satellite service provision is already in progress. */ - public static final int SATELLITE_SERVICE_PROVISION_IN_PROGRESS = 14; + public static final int SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS = 14; /** * The ongoing request was aborted by either the satellite modem or the network. This error is * also returned when framework decides to abort current send request as one of the previous send * request failed. */ - public static final int SATELLITE_REQUEST_ABORTED = 15; + public static final int SATELLITE_RESULT_REQUEST_ABORTED = 15; /** The device/subscriber is barred from accessing the satellite service. */ - public static final int SATELLITE_ACCESS_BARRED = 16; + public static final int SATELLITE_RESULT_ACCESS_BARRED = 16; /** * Satellite modem timeout to receive ACK or response from the satellite network after sending a * request to the network. */ - public static final int SATELLITE_NETWORK_TIMEOUT = 17; + public static final int SATELLITE_RESULT_NETWORK_TIMEOUT = 17; /** Satellite network is not reachable from the modem. */ - public static final int SATELLITE_NOT_REACHABLE = 18; + public static final int SATELLITE_RESULT_NOT_REACHABLE = 18; /** The device/subscriber is not authorized to register with the satellite service provider. */ - public static final int SATELLITE_NOT_AUTHORIZED = 19; + public static final int SATELLITE_RESULT_NOT_AUTHORIZED = 19; /** The device does not support satellite. */ - public static final int SATELLITE_NOT_SUPPORTED = 20; + public static final int SATELLITE_RESULT_NOT_SUPPORTED = 20; /** The current request is already in-progress. */ - public static final int SATELLITE_REQUEST_IN_PROGRESS = 21; + public static final int SATELLITE_RESULT_REQUEST_IN_PROGRESS = 21; /** Satellite modem is currently busy due to which current request cannot be processed. */ - public static final int SATELLITE_MODEM_BUSY = 22; + public static final int SATELLITE_RESULT_MODEM_BUSY = 22; + /** Telephony process is not currently available or satellite is not supported. */ + public static final int SATELLITE_RESULT_ILLEGAL_STATE = 23; /** @hide */ @IntDef( - prefix = {"SATELLITE_"}, + prefix = {"SATELLITE_RESULT_"}, value = { - SATELLITE_ERROR_NONE, - SATELLITE_ERROR, - SATELLITE_SERVER_ERROR, - SATELLITE_SERVICE_ERROR, - SATELLITE_MODEM_ERROR, - SATELLITE_NETWORK_ERROR, - SATELLITE_INVALID_TELEPHONY_STATE, - SATELLITE_INVALID_MODEM_STATE, - SATELLITE_INVALID_ARGUMENTS, - SATELLITE_REQUEST_FAILED, - SATELLITE_RADIO_NOT_AVAILABLE, - SATELLITE_REQUEST_NOT_SUPPORTED, - SATELLITE_NO_RESOURCES, - SATELLITE_SERVICE_NOT_PROVISIONED, - SATELLITE_SERVICE_PROVISION_IN_PROGRESS, - SATELLITE_REQUEST_ABORTED, - SATELLITE_ACCESS_BARRED, - SATELLITE_NETWORK_TIMEOUT, - SATELLITE_NOT_REACHABLE, - SATELLITE_NOT_AUTHORIZED, - SATELLITE_NOT_SUPPORTED, - SATELLITE_REQUEST_IN_PROGRESS, - SATELLITE_MODEM_BUSY + SATELLITE_RESULT_SUCCESS, + SATELLITE_RESULT_ERROR, + SATELLITE_RESULT_SERVER_ERROR, + SATELLITE_RESULT_SERVICE_ERROR, + SATELLITE_RESULT_MODEM_ERROR, + SATELLITE_RESULT_NETWORK_ERROR, + SATELLITE_RESULT_INVALID_TELEPHONY_STATE, + SATELLITE_RESULT_INVALID_MODEM_STATE, + SATELLITE_RESULT_INVALID_ARGUMENTS, + SATELLITE_RESULT_REQUEST_FAILED, + SATELLITE_RESULT_RADIO_NOT_AVAILABLE, + SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, + SATELLITE_RESULT_NO_RESOURCES, + SATELLITE_RESULT_SERVICE_NOT_PROVISIONED, + SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS, + SATELLITE_RESULT_REQUEST_ABORTED, + SATELLITE_RESULT_ACCESS_BARRED, + SATELLITE_RESULT_NETWORK_TIMEOUT, + SATELLITE_RESULT_NOT_REACHABLE, + SATELLITE_RESULT_NOT_AUTHORIZED, + SATELLITE_RESULT_NOT_SUPPORTED, + SATELLITE_RESULT_REQUEST_IN_PROGRESS, + SATELLITE_RESULT_MODEM_BUSY, + SATELLITE_RESULT_ILLEGAL_STATE }) @Retention(RetentionPolicy.SOURCE) - public @interface SatelliteError {} + public @interface SatelliteResult {} /** Suggested device hold position is unknown. */ public static final int DEVICE_HOLD_POSITION_UNKNOWN = 0; @@ -344,7 +380,35 @@ @Retention(RetentionPolicy.SOURCE) public @interface DeviceHoldPosition {} - /** Exception from the satellite service containing the {@link SatelliteError} error code. */ + /** + * Satellite communication restricted by user. + * @hide + */ + public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER = 0; + + /** + * Satellite communication restricted by geolocation. This can be + * triggered based upon geofence input provided by carrier to enable or disable satellite. + */ + public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_GEOLOCATION = 1; + + /** + * Satellite communication restricted by entitlement server. This can be triggered based on + * the EntitlementStatus value received from the entitlement server to enable or disable + * satellite. + */ + public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT = 2; + + /** @hide */ + @IntDef(prefix = "SATELLITE_COMMUNICATION_RESTRICTION_REASON_", value = { + SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER, + SATELLITE_COMMUNICATION_RESTRICTION_REASON_GEOLOCATION, + SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SatelliteCommunicationRestrictionReason {} + + /** Exception from the satellite service containing the {@link SatelliteResult} error code. */ public static class SatelliteExceptionWrapper extends Exception { private final int mErrorCode; @@ -364,17 +428,20 @@ * enabled, this may also disable the cellular modem, and if the satellite modem is disabled, this * may also re-enable the cellular modem. */ - public void requestSatelliteEnabled( + public void requestEnabled( boolean enableSatellite, boolean enableDemoMode, + boolean isEmergency, @NonNull @CallbackExecutor Executor executor, - @SatelliteError @NonNull Consumer<Integer> resultListener) { - mSatelliteManager.requestSatelliteEnabled( - enableSatellite, enableDemoMode, executor, resultListener); + @SatelliteResult @NonNull Consumer<Integer> resultListener) { + mSatelliteManager.requestEnabled(new EnableRequestAttributes.Builder(enableSatellite) + .setDemoMode(enableDemoMode) + .setEmergencyMode(isEmergency) + .build(), executor, resultListener); } /** Request to get whether the satellite modem is enabled. */ - public void requestIsSatelliteEnabled( + public void requestIsEnabled( @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { OutcomeReceiver internalCallback = @@ -389,7 +456,7 @@ callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode())); } }; - mSatelliteManager.requestIsSatelliteEnabled(executor, internalCallback); + mSatelliteManager.requestIsEnabled(executor, internalCallback); } /** Request to get whether the satellite service demo mode is enabled. */ @@ -411,8 +478,27 @@ mSatelliteManager.requestIsDemoModeEnabled(executor, internalCallback); } + /** Request to get whether the satellite service is enabled for emergency mode */ + public void requestIsEmergencyModeEnabled( + @NonNull @CallbackExecutor Executor executor, + @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { + OutcomeReceiver internalCallback = + new OutcomeReceiver<Boolean, SatelliteException>() { + @Override + public void onResult(Boolean result) { + callback.onResult(result); + } + + @Override + public void onError(SatelliteException exception) { + callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode())); + } + }; + mSatelliteManager.requestIsEmergencyModeEnabled(executor, internalCallback); + } + /** Request to get whether the satellite service is supported on the device. */ - public void requestIsSatelliteSupported( + public void requestIsSupported( @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { OutcomeReceiver internalCallback = @@ -427,11 +513,11 @@ callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode())); } }; - mSatelliteManager.requestIsSatelliteSupported(executor, internalCallback); + mSatelliteManager.requestIsSupported(executor, internalCallback); } /** Request to get the {@link SatelliteCapabilities} of the satellite service. */ - public void requestSatelliteCapabilities( + public void requestCapabilities( @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<SatelliteCapabilitiesWrapper, SatelliteExceptionWrapper> callback) { OutcomeReceiver internalCallback = @@ -451,20 +537,20 @@ callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode())); } }; - mSatelliteManager.requestSatelliteCapabilities(executor, internalCallback); + mSatelliteManager.requestCapabilities(executor, internalCallback); } /** * Start receiving satellite transmission updates. This can be called by the pointing UI when the * user starts pointing to the satellite. Modem should continue to report the pointing input as * the device or satellite moves. Satellite transmission updates are started only on {@link - * #SATELLITE_ERROR_NONE}. All other results indicate that this operation failed. Once satellite - * transmission updates begin, position and datagram transfer state updates will be sent through - * {@link SatelliteTransmissionUpdateCallback}. + * #SATELLITE_RESULT_SUCCESS}. All other results indicate that this operation failed. + * Once satellite transmission updates begin, position and datagram transfer state updates + * will be sent through {@link SatelliteTransmissionUpdateCallback}. */ - public void startSatelliteTransmissionUpdates( + public void startTransmissionUpdates( @NonNull @CallbackExecutor Executor executor, - @SatelliteError @NonNull Consumer<Integer> resultListener, + @SatelliteResult @NonNull Consumer<Integer> resultListener, @NonNull SatelliteTransmissionUpdateCallbackWrapper callback) { SatelliteTransmissionUpdateCallback internalCallback = @@ -474,7 +560,7 @@ public void onSendDatagramStateChanged( @SatelliteDatagramTransferState int state, int sendPendingCount, - @SatelliteError int errorCode) { + @SatelliteResult int errorCode) { callback.onSendDatagramStateChanged(state, sendPendingCount, errorCode); } @@ -482,7 +568,7 @@ public void onReceiveDatagramStateChanged( @SatelliteDatagramTransferState int state, int receivePendingCount, - @SatelliteError int errorCode) { + @SatelliteResult int errorCode) { callback.onReceiveDatagramStateChanged(state, receivePendingCount, errorCode); } @@ -496,23 +582,23 @@ }; sSatelliteTransmissionUpdateCallbackWrapperMap.put(callback, internalCallback); - mSatelliteManager.startSatelliteTransmissionUpdates(executor, resultListener, internalCallback); + mSatelliteManager.startTransmissionUpdates(executor, resultListener, internalCallback); } /** * Stop receiving satellite transmission updates. This can be called by the pointing UI when the * user stops pointing to the satellite. Satellite transmission updates are stopped and the - * callback is unregistered only on {@link #SATELLITE_ERROR_NONE}. All other results that this + * callback is unregistered only on {@link #SATELLITE_RESULT_SUCCESS}. All other results that this * operation failed. */ - public void stopSatelliteTransmissionUpdates( + public void stopTransmissionUpdates( @NonNull SatelliteTransmissionUpdateCallbackWrapper callback, @NonNull @CallbackExecutor Executor executor, - @SatelliteError @NonNull Consumer<Integer> resultListener) { + @SatelliteResult @NonNull Consumer<Integer> resultListener) { SatelliteTransmissionUpdateCallback internalCallback = sSatelliteTransmissionUpdateCallbackWrapperMap.get(callback); if (internalCallback != null) { - mSatelliteManager.stopSatelliteTransmissionUpdates( + mSatelliteManager.stopTransmissionUpdates( internalCallback, executor, resultListener); } } @@ -521,13 +607,13 @@ * Provision the device with a satellite provider. This is needed if the provider allows dynamic * registration. */ - public void provisionSatelliteService( + public void provisionService( @NonNull String token, @NonNull byte[] provisionData, @Nullable CancellationSignal cancellationSignal, @NonNull @CallbackExecutor Executor executor, - @SatelliteError @NonNull Consumer<Integer> resultListener) { - mSatelliteManager.provisionSatelliteService( + @SatelliteResult @NonNull Consumer<Integer> resultListener) { + mSatelliteManager.provisionService( token, provisionData, cancellationSignal, executor, resultListener); } @@ -537,16 +623,16 @@ * SatelliteProvisionStateCallback#onSatelliteProvisionStateChanged(boolean)} should report as * deprovisioned. */ - public void deprovisionSatelliteService( + public void deprovisionService( @NonNull String token, @NonNull @CallbackExecutor Executor executor, - @SatelliteError @NonNull Consumer<Integer> resultListener) { - mSatelliteManager.deprovisionSatelliteService(token, executor, resultListener); + @SatelliteResult @NonNull Consumer<Integer> resultListener) { + mSatelliteManager.deprovisionService(token, executor, resultListener); } /** Registers for the satellite provision state changed. */ - @SatelliteError - public int registerForSatelliteProvisionStateChanged( + @SatelliteResult + public int registerForProvisionStateChanged( @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteProvisionStateCallbackWrapper callback) { SatelliteProvisionStateCallback internalCallback = @@ -558,7 +644,7 @@ }; sSatelliteProvisionStateCallbackWrapperMap.put(callback, internalCallback); int result = - mSatelliteManager.registerForSatelliteProvisionStateChanged(executor, internalCallback); + mSatelliteManager.registerForProvisionStateChanged(executor, internalCallback); return result; } @@ -566,17 +652,17 @@ * Unregisters for the satellite provision state changed. If callback was not registered before, * the request will be ignored. */ - public void unregisterForSatelliteProvisionStateChanged( + public void unregisterForProvisionStateChanged( @NonNull SatelliteProvisionStateCallbackWrapper callback) { SatelliteProvisionStateCallback internalCallback = sSatelliteProvisionStateCallbackWrapperMap.get(callback); if (internalCallback != null) { - mSatelliteManager.unregisterForSatelliteProvisionStateChanged(internalCallback); + mSatelliteManager.unregisterForProvisionStateChanged(internalCallback); } } /** Request to get whether this device is provisioned with a satellite provider. */ - public void requestIsSatelliteProvisioned( + public void requestIsProvisioned( @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { OutcomeReceiver internalCallback = @@ -591,24 +677,24 @@ callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode())); } }; - mSatelliteManager.requestIsSatelliteProvisioned(executor, internalCallback); + mSatelliteManager.requestIsProvisioned(executor, internalCallback); } /** Registers for modem state changed from satellite modem. */ - @SatelliteError - public int registerForSatelliteModemStateChanged( + @SatelliteResult + public int registerForModemStateChanged( @NonNull @CallbackExecutor Executor executor, - @NonNull SatelliteStateCallbackWrapper callback) { - SatelliteStateCallback internalCallback = - new SatelliteStateCallback() { + @NonNull SatelliteModemStateCallbackWrapper callback) { + SatelliteModemStateCallback internalCallback = + new SatelliteModemStateCallback() { public void onSatelliteModemStateChanged(@SatelliteModemState int state) { callback.onSatelliteModemStateChanged(state); } }; - sSatelliteStateCallbackWrapperMap.put(callback, internalCallback); + sSatelliteModemStateCallbackWrapperMap.put(callback, internalCallback); int result = - mSatelliteManager.registerForSatelliteModemStateChanged(executor, internalCallback); + mSatelliteManager.registerForModemStateChanged(executor, internalCallback); return result; } @@ -616,17 +702,18 @@ * Unregisters for modem state changed from satellite modem. If callback was not registered * before, the request will be ignored. */ - public void unregisterForSatelliteModemStateChanged( - @NonNull SatelliteStateCallbackWrapper callback) { - SatelliteStateCallback internalCallback = sSatelliteStateCallbackWrapperMap.get(callback); + public void unregisterForModemStateChanged( + @NonNull SatelliteModemStateCallbackWrapper callback) { + SatelliteModemStateCallback internalCallback = sSatelliteModemStateCallbackWrapperMap.get( + callback); if (internalCallback != null) { - mSatelliteManager.unregisterForSatelliteModemStateChanged(internalCallback); + mSatelliteManager.unregisterForModemStateChanged(internalCallback); } } /** Register to receive incoming datagrams over satellite. */ - @SatelliteError - public int registerForSatelliteDatagram( + @SatelliteResult + public int registerForIncomingDatagram( @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteDatagramCallbackWrapper callback) { SatelliteDatagramCallback internalCallback = @@ -645,7 +732,7 @@ } }; sSatelliteDatagramCallbackWrapperMap.put(callback, internalCallback); - int result = mSatelliteManager.registerForSatelliteDatagram(executor, internalCallback); + int result = mSatelliteManager.registerForIncomingDatagram(executor, internalCallback); return result; } @@ -653,18 +740,18 @@ * Unregister to stop receiving incoming datagrams over satellite. If callback was not registered * before, the request will be ignored. */ - public void unregisterForSatelliteDatagram(@NonNull SatelliteDatagramCallbackWrapper callback) { + public void unregisterForIncomingDatagram(@NonNull SatelliteDatagramCallbackWrapper callback) { SatelliteDatagramCallback internalCallback = sSatelliteDatagramCallbackWrapperMap.get(callback); if (internalCallback != null) { - mSatelliteManager.unregisterForSatelliteDatagram(internalCallback); + mSatelliteManager.unregisterForIncomingDatagram(internalCallback); } } /** Poll pending satellite datagrams over satellite. */ - public void pollPendingSatelliteDatagrams( + public void pollPendingDatagrams( @NonNull @CallbackExecutor Executor executor, - @SatelliteError @NonNull Consumer<Integer> resultListener) { - mSatelliteManager.pollPendingSatelliteDatagrams(executor, resultListener); + @SatelliteResult @NonNull Consumer<Integer> resultListener) { + mSatelliteManager.pollPendingDatagrams(executor, resultListener); } /** @@ -674,19 +761,19 @@ * input to this method. Datagram received here will be passed down to modem without any encoding * or encryption. */ - public void sendSatelliteDatagram( + public void sendDatagram( @DatagramType int datagramType, @NonNull SatelliteDatagramWrapper datagram, boolean needFullScreenPointingUI, @NonNull @CallbackExecutor Executor executor, - @SatelliteError @NonNull Consumer<Integer> resultListener) { + @SatelliteResult @NonNull Consumer<Integer> resultListener) { SatelliteDatagram datagramInternal = new SatelliteDatagram(datagram.getSatelliteDatagram()); - mSatelliteManager.sendSatelliteDatagram( + mSatelliteManager.sendDatagram( datagramType, datagramInternal, needFullScreenPointingUI, executor, resultListener); } /** Request to get whether satellite communication is allowed for the current location. */ - public void requestIsSatelliteCommunicationAllowedForCurrentLocation( + public void requestIsCommunicationAllowedForCurrentLocation( @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { OutcomeReceiver internalCallback = @@ -701,7 +788,7 @@ callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode())); } }; - mSatelliteManager.requestIsSatelliteCommunicationAllowedForCurrentLocation( + mSatelliteManager.requestIsCommunicationAllowedForCurrentLocation( executor, internalCallback); } @@ -730,8 +817,8 @@ /** * Inform whether the device is aligned with the satellite for demo mode. */ - public void onDeviceAlignedWithSatellite(boolean isAligned) { - mSatelliteManager.onDeviceAlignedWithSatellite(isAligned); + public void setDeviceAlignedWithSatellite(boolean isAligned) { + mSatelliteManager.setDeviceAlignedWithSatellite(isAligned); } private Map<Integer, AntennaPositionWrapper> transformToAntennaPositionWrapperMap( @@ -752,4 +839,348 @@ return output; } + + /** Request to get the signal strength of the satellite connection. */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + @NonNull + public void requestNtnSignalStrength( + @NonNull @CallbackExecutor Executor executor, + @NonNull OutcomeReceiver<NtnSignalStrengthWrapper, SatelliteExceptionWrapper> callback) { + OutcomeReceiver internalCallback = + new OutcomeReceiver<NtnSignalStrength, SatelliteException>() { + @Override + public void onResult(NtnSignalStrength result) { + callback.onResult(new NtnSignalStrengthWrapper(result.getLevel())); + } + + @Override + public void onError(SatelliteException exception) { + callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode())); + } + }; + mSatelliteManager.requestNtnSignalStrength(executor, internalCallback); + } + + /** Registers for NTN signal strength changed from satellite modem. */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + public void registerForNtnSignalStrengthChanged( + @NonNull @CallbackExecutor Executor executor, + @NonNull NtnSignalStrengthCallbackWrapper callback) { + NtnSignalStrengthCallback internalCallback = + new NtnSignalStrengthCallback() { + @Override + public void onNtnSignalStrengthChanged(@NonNull NtnSignalStrength ntnSignalStrength) { + callback.onNtnSignalStrengthChanged( + new NtnSignalStrengthWrapper(ntnSignalStrength.getLevel())); + } + }; + sNtnSignalStrengthCallbackWrapperMap.put(callback, internalCallback); + mSatelliteManager.registerForNtnSignalStrengthChanged(executor, internalCallback); + } + + /** + * Unregisters for NTN signal strength changed from satellite modem. + * If callback was not registered before, the request will be ignored. + */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + public void unregisterForNtnSignalStrengthChanged( + @NonNull NtnSignalStrengthCallbackWrapper callback) { + NtnSignalStrengthCallback internalCallback = sNtnSignalStrengthCallbackWrapperMap.get(callback); + if (internalCallback != null) { + try { + mSatelliteManager.unregisterForNtnSignalStrengthChanged(internalCallback); + } catch (Exception ex) { + throw ex; + } + } + } + + /** + * Wrapper API to provide a way to check if the subscription is exclusively for non-terrestrial + * networks. + * + * @param subId The unique SubscriptionInfo key in database. + * @return {@code true} if it is a non-terrestrial network subscription, {@code false} + * otherwise. + * Note: The method returns {@code false} if the parameter is invalid or any other error occurs. + */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + public boolean isOnlyNonTerrestrialNetworkSubscription(int subId) { + List<SubscriptionInfo> subInfoList = mSubscriptionManager.getAvailableSubscriptionInfoList(); + + for (SubscriptionInfo subInfo : subInfoList) { + if (subInfo.getSubscriptionId() == subId) { + logd("found matched subscription info"); + return subInfo.isOnlyNonTerrestrialNetwork(); + } + } + logd("failed to found matched subscription info"); + return false; + } + + /** + * Wrapper API to register for satellite capabilities change event from the satellite service. + * + * @param executor The executor on which the callback will be called. + * @param callback The callback to handle the satellite capabilities changed event. + */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + public int registerForCapabilitiesChanged( + @NonNull @CallbackExecutor Executor executor, + @NonNull SatelliteCapabilitiesCallbackWrapper callback) { + SatelliteCapabilitiesCallback internalCallback = + capabilities -> callback.onSatelliteCapabilitiesChanged( + new SatelliteCapabilitiesWrapper( + capabilities.getSupportedRadioTechnologies(), + capabilities.isPointingRequired(), + capabilities.getMaxBytesPerOutgoingDatagram(), + transformToAntennaPositionWrapperMap( + capabilities.getAntennaPositionMap()))); + sSatelliteCapabilitiesCallbackWrapperMap.put(callback, internalCallback); + return mSatelliteManager.registerForCapabilitiesChanged(executor, internalCallback); + } + + /** + * Wrapper API to unregisters for satellite capabilities change event from the satellite service. + * If callback was not registered before, the request will be ignored. + * + * @param callback The callback that was passed to. + */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + public void unregisterForCapabilitiesChanged( + @NonNull SatelliteCapabilitiesCallbackWrapper callback) { + SatelliteCapabilitiesCallback internalCallback = + sSatelliteCapabilitiesCallbackWrapperMap.get(callback); + if (internalCallback != null) { + mSatelliteManager.unregisterForCapabilitiesChanged(internalCallback); + } + } + + /** + * Wrapper API to provide whether current network is non-terrestrial network or not. + * + * @param subId Subscription ID. + * + * @return {@code true} if current network is a non-terrestrial network, {@code false} otherwise. + * Note: The method returns {@code false} if the no available network info or any other error + * occurs. + */ + public boolean isNonTerrestrialNetwork(int subId) { + ServiceState ss = getServiceStateForSubscriptionId(subId); + + if (ss == null) { + logd("isNonTerrestrialNetwork(): ServiceState is null, return"); + return false; + } + + NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN); + if (nri == null) { + logd("isNonTerrestrialNetwork(): NetworkRegistrationInfo is null, return"); + return false; + } + + boolean isNonTerrestrialNetwork = nri.isNonTerrestrialNetwork(); + logd("isNonTerrestrialNetwork = " + isNonTerrestrialNetwork); + return isNonTerrestrialNetwork; + } + + /** + * Wrapper API to provide the list of available services. + * + * @param subId Subscription ID. + * + * @return the list of available service types for given subscription ID. + * Note: The method returns empty list if no service is available or any other error occurs. + */ + @NonNull + public List<Integer> getAvailableServices(int subId) { + ServiceState ss = getServiceStateForSubscriptionId(subId); + if (ss == null) { + logd("getAvailableServices(): ServiceState is null, return"); + return new ArrayList<>(); + } + + NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN); + if (nri == null) { + logd("getAvailableServices(): NetworkRegistrationInfo is null, return empty list"); + return new ArrayList<>(); + } + + List<Integer> serviceType = nri.getAvailableServices(); + logd("getAvailableServices() : serviceType=" + serviceType.stream().map( + Object::toString).collect(Collectors.joining(", "))); + return serviceType; + } + + /** + * Wrapper API to get whether device is connected to a non-terrestrial network. + * + * @param subId Subscription ID. + * + * @return {@code true} if device is connected to a non-terrestrial network, {@code false} + * otherwise. + * Note: The method returns {@code false} if the no available network info or any other error + * occurs. + */ + public boolean isUsingNonTerrestrialNetwork(int subId) { + ServiceState ss = getServiceStateForSubscriptionId(subId); + + if (ss == null) { + logd("isUsingNonTerrestrialNetwork(): ServiceState is null, return"); + return false; + } + + boolean isUsingNonTerrestrialNetwork = ss.isUsingNonTerrestrialNetwork(); + logd("isUsingNonTerrestrialNetwork() returns " + isUsingNonTerrestrialNetwork); + return isUsingNonTerrestrialNetwork; + } + + /** + * User request to enable or disable carrier supported satellite plmn scan and attach by modem. + * <p> + * This API should be called by only settings app to pass down the user input for + * enabling/disabling satellite. This user input will be persisted across device reboots. + * <p> + * Satellite will be enabled only when the following conditions are met: + * <ul> + * <li>Users want to enable it.</li> + * <li>There is no satellite communication restriction, which is added by + * {@link #addAttachRestrictionForCarrier(int, int, Executor, Consumer)}</li> + * <li>The carrier config {@link + * android.telephony.CarrierConfigManager#KEY_SATELLITE_ATTACH_SUPPORTED_BOOL} is set to + * {@code true}.</li> + * </ul> + * + * @param subId The subscription ID of the carrier. + * @param enableSatellite {@code true} to enable the satellite and {@code false} to disable. + * @param executor The executor on which the error code listener will be called. + * @param resultListener Listener for the {@link SatelliteResult} result of the operation. + * + * @throws SecurityException if the caller doesn't have required permission. + * @throws IllegalArgumentException if the subscription is invalid. + */ + public void requestAttachEnabledForCarrier(int subId, boolean enableSatellite, + @NonNull @CallbackExecutor Executor executor, + @SatelliteResult @NonNull Consumer<Integer> resultListener) { + mSatelliteManager.requestAttachEnabledForCarrier(subId, enableSatellite, executor, + resultListener); + } + + /** + * Request to get whether the carrier supported satellite plmn scan and attach by modem is + * enabled by user. + * + * @param subId The subscription ID of the carrier. + * @param executor The executor on which the callback will be called. + * @param callback The callback object to which the result will be delivered. + * If the request is successful, {@link OutcomeReceiver#onResult(Object)} + * will return a {@code boolean} with value {@code true} if the satellite + * is enabled and {@code false} otherwise. + * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)} + * will return a {@link SatelliteExceptionWrapper} with the + * {@link SatelliteResult}. + * + * @throws SecurityException if the caller doesn't have required permission. + * @throws IllegalStateException if the Telephony process is not currently available. + * @throws IllegalArgumentException if the subscription is invalid. + */ + public void requestIsAttachEnabledForCarrier(int subId, + @NonNull @CallbackExecutor Executor executor, + @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { + OutcomeReceiver internalCallback = + new OutcomeReceiver<Boolean, SatelliteException>() { + @Override + public void onResult(Boolean result) { + callback.onResult(result); + } + + @Override + public void onError(SatelliteException exception) { + callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode())); + } + }; + mSatelliteManager.requestIsAttachEnabledForCarrier(subId, executor, internalCallback); + } + + /** + * Add a restriction reason for disallowing carrier supported satellite plmn scan and attach + * by modem. + * + * @param subId The subscription ID of the carrier. + * @param reason Reason for disallowing satellite communication. + * @param executor The executor on which the error code listener will be called. + * @param resultListener Listener for the {@link SatelliteResult} result of the + * operation. + * + * @throws SecurityException if the caller doesn't have required permission. + * @throws IllegalArgumentException if the subscription is invalid. + */ + public void addAttachRestrictionForCarrier(int subId, + @SatelliteCommunicationRestrictionReason int reason, + @NonNull @CallbackExecutor Executor executor, + @SatelliteResult @NonNull Consumer<Integer> resultListener) { + mSatelliteManager.addAttachRestrictionForCarrier(subId, reason, executor, resultListener); + } + + /** + * Remove a restriction reason for disallowing carrier supported satellite plmn scan and attach + * by modem. + * + * @param subId The subscription ID of the carrier. + * @param reason Reason for disallowing satellite communication. + * @param executor The executor on which the error code listener will be called. + * @param resultListener Listener for the {@link SatelliteResult} result of the + * operation. + * + * @throws SecurityException if the caller doesn't have required permission. + * @throws IllegalArgumentException if the subscription is invalid. + */ + public void removeAttachRestrictionForCarrier(int subId, + @SatelliteCommunicationRestrictionReason int reason, + @NonNull @CallbackExecutor Executor executor, + @SatelliteResult @NonNull Consumer<Integer> resultListener) { + mSatelliteManager.removeAttachRestrictionForCarrier(subId, reason, executor, resultListener); + } + + /** + * Get reasons for disallowing satellite attach, as requested by + * {@link #addAttachRestrictionForCarrier(int, int, Executor, Consumer)} + * + * @param subId The subscription ID of the carrier. + * @return Set of reasons for disallowing satellite communication. + * + * @throws SecurityException if the caller doesn't have required permission. + * @throws IllegalStateException if the Telephony process is not currently available. + * @throws IllegalArgumentException if the subscription is invalid. + */ + @SatelliteCommunicationRestrictionReason + @NonNull public Set<Integer> getAttachRestrictionReasonsForCarrier(int subId) { + return mSatelliteManager.getAttachRestrictionReasonsForCarrier(subId); + } + + /** + * Get all satellite PLMNs for which attach is enable for carrier. + * + * @param subId subId The subscription ID of the carrier. + * + * @return List of plmn for carrier satellite service. If no plmn is available, empty list will + * be returned. + */ + @NonNull public List<String> getSatellitePlmnsForCarrier(int subId) { + return mSatelliteManager.getSatellitePlmnsForCarrier(subId); + } + + @Nullable + private ServiceState getServiceStateForSubscriptionId(int subId) { + if (!mSubscriptionManager.isValidSubscriptionId(subId)) { + return null; + } + + TelephonyManager tm = mTelephonyManager.createForSubscriptionId(subId); + return tm.getServiceState(); + } + + private void logd(String message) { + Rlog.d(TAG, message); + } }
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteStateCallbackWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteModemStateCallbackWrapper.java similarity index 94% rename from satellite_client/src/android/telephony/satellite/wrapper/SatelliteStateCallbackWrapper.java rename to satellite_client/src/android/telephony/satellite/wrapper/SatelliteModemStateCallbackWrapper.java index 3d57fa0..450e48a 100644 --- a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteStateCallbackWrapper.java +++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteModemStateCallbackWrapper.java
@@ -17,7 +17,7 @@ package android.telephony.satellite.wrapper; /** A callback class for monitoring satellite modem state change events. */ -public interface SatelliteStateCallbackWrapper { +public interface SatelliteModemStateCallbackWrapper { /** * Called when satellite modem state changes.
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteTransmissionUpdateCallbackWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteTransmissionUpdateCallbackWrapper.java index c65f4f6..381b397 100644 --- a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteTransmissionUpdateCallbackWrapper.java +++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteTransmissionUpdateCallbackWrapper.java
@@ -40,7 +40,7 @@ void onSendDatagramStateChanged( @SatelliteManagerWrapper.SatelliteDatagramTransferState int state, int sendPendingCount, - @SatelliteManagerWrapper.SatelliteError int errorCode); + @SatelliteManagerWrapper.SatelliteResult int errorCode); /** * Called when satellite datagram receive state changed. @@ -52,5 +52,5 @@ void onReceiveDatagramStateChanged( @SatelliteManagerWrapper.SatelliteDatagramTransferState int state, int receivePendingCount, - @SatelliteManagerWrapper.SatelliteError int errorCode); + @SatelliteManagerWrapper.SatelliteResult int errorCode); }
diff --git a/ts43authentication/src/com/android/libraries/ts43authentication/AuthenticationOutcomeReceiver.java b/ts43authentication/src/com/android/libraries/ts43authentication/AuthenticationOutcomeReceiver.java new file mode 100644 index 0000000..37ad354 --- /dev/null +++ b/ts43authentication/src/com/android/libraries/ts43authentication/AuthenticationOutcomeReceiver.java
@@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.libraries.ts43authentication; + +/** + * Callback interface intended for use when an TS.43 authentication request may result in a failure. + * This interface may be used in cases where an asynchronous API may complete either with a value + * or with a {@link Throwable} that indicates an error. + * Functionally the same as an OutcomeReceiver, but creating a new class for backwards compatibility + * on devices with SDK < 31. + * + * @param <R> The type of the result that's being sent. + * @param <E> The type of the {@link Throwable} that contains more information about the error. + */ +public interface AuthenticationOutcomeReceiver <R, E extends Throwable> { + /** + * Called when the asynchronous operation succeeds and delivers a result value. + * + * @param result The value delivered by the asynchronous operation. + */ + void onResult(R result); + + /** + * Called when the asynchronous operation fails. The mode of failure is indicated by the + * {@link Throwable} passed as an argument to this method. + * + * @param error A subclass of {@link Throwable} with more details about the error that occurred. + */ + default void onError(E error) {} +}
diff --git a/ts43authentication/src/com/android/libraries/ts43authentication/Ts43AuthenticationLibrary.java b/ts43authentication/src/com/android/libraries/ts43authentication/Ts43AuthenticationLibrary.java index be3931d..da45671 100644 --- a/ts43authentication/src/com/android/libraries/ts43authentication/Ts43AuthenticationLibrary.java +++ b/ts43authentication/src/com/android/libraries/ts43authentication/Ts43AuthenticationLibrary.java
@@ -22,10 +22,10 @@ import android.content.pm.Signature; import android.content.pm.SigningInfo; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.os.OutcomeReceiver; import android.os.PersistableBundle; import android.telephony.SubscriptionInfo; import android.util.Log; @@ -43,7 +43,6 @@ import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.ArrayList; -import java.util.HexFormat; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.locks.ReentrantLock; @@ -131,12 +130,12 @@ @Nullable private final String mEntitlementVersion; private final String mAppId; private final Executor mExecutor; - private final OutcomeReceiver< + private final AuthenticationOutcomeReceiver< Ts43Authentication.Ts43AuthToken, AuthenticationException> mCallback; private EapAkaAuthenticationRequest(String appName, @Nullable String appVersion, int slotIndex, URL entitlementServerAddress, @Nullable String entitlementVersion, - String appId, Executor executor, OutcomeReceiver< + String appId, Executor executor, AuthenticationOutcomeReceiver< Ts43Authentication.Ts43AuthToken, AuthenticationException> callback) { mAppName = appName; mAppVersion = appVersion; @@ -157,12 +156,12 @@ @Nullable private final String mEntitlementVersion; private final String mAppId; private final Executor mExecutor; - private final OutcomeReceiver<URL, AuthenticationException> mCallback; + private final AuthenticationOutcomeReceiver<URL, AuthenticationException> mCallback; private OidcAuthenticationServerRequest(String appName, @Nullable String appVersion, int slotIndex, URL entitlementServerAddress, @Nullable String entitlementVersion, String appId, Executor executor, - OutcomeReceiver<URL, AuthenticationException> callback) { + AuthenticationOutcomeReceiver<URL, AuthenticationException> callback) { mAppName = appName; mAppVersion = appVersion; mSlotIndex = slotIndex; @@ -179,11 +178,12 @@ @Nullable private final String mEntitlementVersion; private final URL mAesUrl; private final Executor mExecutor; - private final OutcomeReceiver< + private final AuthenticationOutcomeReceiver< Ts43Authentication.Ts43AuthToken, AuthenticationException> mCallback; private OidcAuthenticationRequest(URL entitlementServerAddress, - @Nullable String entitlementVersion, URL aesUrl, Executor executor, OutcomeReceiver< + @Nullable String entitlementVersion, URL aesUrl, Executor executor, + AuthenticationOutcomeReceiver< Ts43Authentication.Ts43AuthToken, AuthenticationException> callback) { mEntitlementServerAddress = entitlementServerAddress; mEntitlementVersion = entitlementVersion; @@ -216,14 +216,17 @@ * Refer to GSMA Service Entitlement Configuration section 2.3. * @param executor The executor on which the callback will be called. * @param callback The callback to receive the results of the authentication request. - * If authentication is successful, {@link OutcomeReceiver#onResult(Object)} will return - * a {@link Ts43Authentication.Ts43AuthToken} with the token and validity. - * If the authentication fails, {@link OutcomeReceiver#onError(Throwable)} will return an + * If authentication is successful, + * {@link AuthenticationOutcomeReceiver#onResult(Object)} will return a + * {@link Ts43Authentication.Ts43AuthToken} with the token and validity. + * If the authentication fails, + * {@link AuthenticationOutcomeReceiver#onError(Throwable)} will return an * {@link AuthenticationException} with the failure details. */ public void requestEapAkaAuthentication(PersistableBundle configs, String packageName, @Nullable String appVersion, int slotIndex, URL entitlementServerAddress, - @Nullable String entitlementVersion, String appId, Executor executor, OutcomeReceiver< + @Nullable String entitlementVersion, String appId, Executor executor, + AuthenticationOutcomeReceiver< Ts43Authentication.Ts43AuthToken, AuthenticationException> callback) { String[] allowedPackageInfo = configs.getStringArray(KEY_ALLOWED_CERTIFICATES_STRING_ARRAY); String certificate = getMatchingCertificate(allowedPackageInfo, packageName); @@ -245,8 +248,8 @@ * The client should present the content of the URL to the user to continue the authentication * process. After receiving a response from the authentication server, the client can call * {@link #requestOidcAuthentication( - * PersistableBundle, String, URL, String, URL, Executor, OutcomeReceiver)} to get the - * authentication token. + * PersistableBundle, String, URL, String, URL, Executor, AuthenticationOutcomeReceiver)} to get + * the authentication token. * * @param configs The configurations that should be applied to this authentication request. * The keys of the bundle must be in {@link ConfigurationKey}. @@ -267,18 +270,18 @@ * Refer to GSMA Service Entitlement Configuration section 2.3. * @param executor The executor on which the callback will be called. * @param callback The callback to receive the results of the authentication server request. - * If the request is successful, {@link OutcomeReceiver#onResult(Object)} will return a - * {@link URL} with all the required parameters for the client to launch a user interface - * for users to complete the authentication process. The parameters in URL include - * {@code client_id}, {@code redirect_uri}, {@code state}, and {@code nonce}. - * If the authentication fails, {@link OutcomeReceiver#onError(Throwable)} will return an - * {@link AuthenticationException} with the failure details. + * If the request is successful, {@link AuthenticationOutcomeReceiver#onResult(Object)} + * will return a {@link URL} with all the required parameters for the client to launch a + * user interface for users to complete the authentication process. The parameters in URL + * include {@code client_id}, {@code redirect_uri}, {@code state}, and {@code nonce}. + * If the authentication fails, {@link AuthenticationOutcomeReceiver#onError(Throwable)} + * will return an {@link AuthenticationException} with the failure details. */ public void requestOidcAuthenticationServer(PersistableBundle configs, String packageName, @Nullable String appVersion, int slotIndex, URL entitlementServerAddress, @Nullable String entitlementVersion, String appId, Executor executor, - OutcomeReceiver<URL, AuthenticationException> callback) { + AuthenticationOutcomeReceiver<URL, AuthenticationException> callback) { String[] allowedPackageInfo = configs.getStringArray(KEY_ALLOWED_CERTIFICATES_STRING_ARRAY); String certificate = getMatchingCertificate(allowedPackageInfo, packageName); if (isCallingPackageAllowed(allowedPackageInfo, packageName, certificate)) { @@ -309,15 +312,16 @@ * URL include the OIDC authentication code {@code code} and {@code state}. * @param executor The executor on which the callback will be called. * @param callback The callback to receive the results of the authentication request. - * If authentication is successful, {@link OutcomeReceiver#onResult(Object)} will return - * a {@link Ts43Authentication.Ts43AuthToken} with the token and validity. - * If the authentication fails, {@link OutcomeReceiver#onError(Throwable)} will return an - * {@link AuthenticationException} with the failure details. + * If authentication is successful, + * {@link AuthenticationOutcomeReceiver#onResult(Object)} will return a + * {@link Ts43Authentication.Ts43AuthToken} with the token and validity. + * If the authentication fails, {@link AuthenticationOutcomeReceiver#onError(Throwable)} + * will return an {@link AuthenticationException} with the failure details. */ public void requestOidcAuthentication(PersistableBundle configs, String packageName, URL entitlementServerAddress, @Nullable String entitlementVersion, URL aesUrl, Executor executor, - OutcomeReceiver< + AuthenticationOutcomeReceiver< Ts43Authentication.Ts43AuthToken, AuthenticationException> callback) { String[] allowedPackageInfo = configs.getStringArray(KEY_ALLOWED_CERTIFICATES_STRING_ARRAY); String certificate = getMatchingCertificate(allowedPackageInfo, packageName); @@ -372,7 +376,7 @@ for (Signature signature : signatures) { byte[] signatureHash = md.digest(signature.toByteArray()); for (String certificate : allowedCertificates) { - byte[] certificateHash = HexFormat.of().parseHex(certificate); + byte[] certificateHash = hexStringToBytes(certificate); if (Arrays.equals(signatureHash, certificateHash)) { Log.d(TAG, "Found matching certificate for package " + packageName + ": " + certificate); @@ -412,8 +416,14 @@ @Nullable private Signature[] getMainPackageSignatures(String packageName) { PackageInfo packageInfo; try { - packageInfo = mPackageManager.getPackageInfo(packageName, - PackageManager.PackageInfoFlags.of(PackageManager.GET_SIGNING_CERTIFICATES)); + if (Build.VERSION.SDK_INT < 33) { + packageInfo = mPackageManager.getPackageInfo(packageName, + PackageManager.GET_SIGNING_CERTIFICATES); + } else { + packageInfo = mPackageManager.getPackageInfo(packageName, + PackageManager.PackageInfoFlags.of( + PackageManager.GET_SIGNING_CERTIFICATES)); + } } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "Unable to find package name: " + packageName); return null; @@ -439,6 +449,25 @@ return signatures; } + @Nullable private byte[] hexStringToBytes(@Nullable String hex) { + if (hex == null) { + return null; + } + + int length = hex.length(); + byte[] ret = new byte[length / 2]; + + for (int i = 0; i < length; i += 2) { + ret[i / 2] = + (byte) ((hexCharToInt(hex.charAt(i)) << 4) | hexCharToInt(hex.charAt(i + 1))); + } + return ret; + } + + private int hexCharToInt(char hex) { + return Integer.parseInt(String.valueOf(hex), 16); + } + private boolean isCallingPackageAllowed(@Nullable String[] allowedPackageInfo, String packageName, @Nullable String certificate) { // Check that the package name matches that of the calling package.