Snap for 11426397 from 9acb227ffe595e9f9b5cb678310f84cbba669582 to 24Q2-release Change-Id: I54c1be073307a176444ff8bc3fb81cf6cf5adad7
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java index 4310378..d230e8f 100644 --- a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java +++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java
@@ -16,6 +16,8 @@ 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; @@ -26,8 +28,11 @@ 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; @@ -48,12 +53,15 @@ 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, @@ -88,10 +96,12 @@ private final SatelliteManager mSatelliteManager; private final SubscriptionManager mSubscriptionManager; + private final TelephonyManager mTelephonyManager; SatelliteManagerWrapper(Context context) { mSatelliteManager = context.getSystemService(SatelliteManager.class); mSubscriptionManager = context.getSystemService(SubscriptionManager.class); + mTelephonyManager = context.getSystemService(TelephonyManager.class); } /** @@ -370,6 +380,34 @@ @Retention(RetentionPolicy.SOURCE) public @interface DeviceHoldPosition {} + /** + * 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; @@ -918,6 +956,230 @@ } } + /** + * 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); }