Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 43897838 authored by Hakjun Choi's avatar Hakjun Choi
Browse files

Add new satellite APIs for cellular modems

Add new APIs to add/remove a restriction reason for carrier supported satellite.
Add new APIs user request to enable or disable satellite for carrier, and get status whether satellite for carrier is enabled or disabled.
Add a new API to provide restriction reasons for carrier supported satellite.

Bug: 291302444
Test: CTS/SatelliteManagerTest, SatelliteManagerTestOnMockService
Test: Live network test include call / sms / mms

Change-Id: I81048c29f577c4cc375eeff1c7bcd02f7b6832c9
parent 204ea9a7
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -9455,6 +9455,19 @@ public class CarrierConfigManager {
    public static final String KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE =
            "carrier_supported_satellite_services_per_provider_bundle";

    /**
     * This config enables modem to scan satellite PLMNs specified as per
     * {@link #KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE} and attach to same
     * in case cellular networks are not enabled. This will need specific agreement between
     * satellite provider and the carrier before enabling this flag.
     *
     * The default value is false.
     *
     * @hide
     */
    public static final String KEY_SATELLITE_ATTACH_SUPPORTED_BOOL =
            "satellite_attach_supported_bool";

    /**
     * Indicating whether DUN APN should be disabled when the device is roaming. In that case,
     * the default APN (i.e. internet) will be used for tethering.
@@ -10465,6 +10478,7 @@ public class CarrierConfigManager {
        sDefaults.putPersistableBundle(
                KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE,
                PersistableBundle.EMPTY);
        sDefaults.putBoolean(KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, false);
        sDefaults.putBoolean(KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL, false);
        sDefaults.putString(KEY_DEFAULT_PREFERRED_APN_NAME_STRING, "");
        sDefaults.putBoolean(KEY_SUPPORTS_CALL_COMPOSER_BOOL, false);
+218 −0
Original line number Diff line number Diff line
@@ -44,10 +44,14 @@ import com.android.telephony.Rlog;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.time.Duration;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * Manages satellite operations such as provisioning, pointing, messaging, location sharing, etc.
@@ -78,6 +82,23 @@ public final class SatelliteManager {
     */
    @Nullable private final Context mContext;

    /**
     * Create a new SatelliteManager object pinned to the given subscription ID.
     * This is needed only to handle carrier specific satellite features.
     * For eg: requestSatelliteAttachEnabledForCarrier and
     *         requestIsSatelliteAttachEnabledForCarrier
     *
     * @return a SatelliteManager that uses the given subId for all satellite activities.
     * @throws IllegalArgumentException if the subscription is invalid.
     * @hide
     */
    public SatelliteManager createForSubscriptionId(int subId) {
        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
            throw new IllegalArgumentException("Invalid subscription ID");
        }
        return new SatelliteManager(mContext, subId);
    }

    /**
     * Create an instance of the SatelliteManager.
     *
@@ -790,6 +811,27 @@ public final class SatelliteManager {
    @Retention(RetentionPolicy.SOURCE)
    public @interface DatagramType {}

    /**
     * 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.
     * @hide
     */
    public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_GEOLOCATION = 1;

    /** @hide */
    @IntDef(prefix = "SATELLITE_COMMUNICATION_RESTRICTION_REASON_", value = {
            SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER,
            SATELLITE_COMMUNICATION_RESTRICTION_REASON_GEOLOCATION
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface SatelliteCommunicationRestrictionReason {}

    /**
     * Start receiving satellite transmission updates.
     * This can be called by the pointing UI when the user starts pointing to the satellite.
@@ -1559,6 +1601,182 @@ public final class SatelliteManager {
        }
    }

    /**
     * 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 #addSatelliteAttachRestrictionForCarrier(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 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 SatelliteError} result of the operation.
     *
     * @throws SecurityException if the caller doesn't have required permission.
     * @throws IllegalStateException if the Telephony process is not currently available.
     * @hide
     */
    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
    public void requestSatelliteAttachEnabledForCarrier(boolean enableSatellite,
            @NonNull @CallbackExecutor Executor executor,
            @SatelliteResult @NonNull Consumer<Integer> resultListener) {
        Objects.requireNonNull(executor);
        Objects.requireNonNull(resultListener);

        if (enableSatellite) {
            removeSatelliteAttachRestrictionForCarrier(
                    SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER, executor, resultListener);
        } else {
            addSatelliteAttachRestrictionForCarrier(
                    SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER, executor, resultListener);
        }
    }

    /**
     * Request to get whether the carrier supported satellite plmn scan and attach by modem is
     * enabled by user.
     *
     * @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 SatelliteException} with the {@link SatelliteError}.
     *
     * @throws SecurityException if the caller doesn't have required permission.
     * @throws IllegalStateException if the Telephony process is not currently available.
     * @hide
     */
    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
    public void requestIsSatelliteAttachEnabledForCarrier(
            @NonNull @CallbackExecutor Executor executor,
            @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
        Objects.requireNonNull(executor);
        Objects.requireNonNull(callback);

        Set<Integer> restrictionReason = getSatelliteAttachRestrictionReasonsForCarrier();
        executor.execute(() -> callback.onResult(
                !restrictionReason.contains(SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER)));
    }

    /**
     * Add a restriction reason for disallowing carrier supported satellite plmn scan and attach
     * by modem.
     *
     * @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 SatelliteError} result of the operation.
     *
     * @throws SecurityException if the caller doesn't have required permission.
     * @throws IllegalStateException if the Telephony process is not currently available.
     * @hide
     */
    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
    public void addSatelliteAttachRestrictionForCarrier(
            @SatelliteCommunicationRestrictionReason int reason,
            @NonNull @CallbackExecutor Executor executor,
            @SatelliteResult @NonNull Consumer<Integer> resultListener) {
        try {
            ITelephony telephony = getITelephony();
            if (telephony != null) {
                IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
                    @Override
                    public void accept(int result) {
                        executor.execute(() -> Binder.withCleanCallingIdentity(
                                () -> resultListener.accept(result)));
                    }
                };
                telephony.addSatelliteAttachRestrictionForCarrier(mSubId, reason, errorCallback);
            } else {
                throw new IllegalStateException("telephony service is null.");
            }
        } catch (RemoteException ex) {
            loge("addSatelliteAttachRestrictionForCarrier() RemoteException:" + ex);
            ex.rethrowFromSystemServer();
        }
    }

    /**
     * Remove a restriction reason for disallowing carrier supported satellite plmn scan and attach
     * by modem.
     *
     * @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 SatelliteError} result of the operation.
     *
     * @throws SecurityException if the caller doesn't have required permission.
     * @throws IllegalStateException if the Telephony process is not currently available.
     * @hide
     */
    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
    public void removeSatelliteAttachRestrictionForCarrier(
            @SatelliteCommunicationRestrictionReason int reason,
            @NonNull @CallbackExecutor Executor executor,
            @SatelliteResult @NonNull Consumer<Integer> resultListener) {
        try {
            ITelephony telephony = getITelephony();
            if (telephony != null) {
                IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
                    @Override
                    public void accept(int result) {
                        executor.execute(() -> Binder.withCleanCallingIdentity(
                                () -> resultListener.accept(result)));
                    }
                };
                telephony.removeSatelliteAttachRestrictionForCarrier(mSubId, reason, errorCallback);
            } else {
                throw new IllegalStateException("telephony service is null.");
            }
        } catch (RemoteException ex) {
            loge("removeSatelliteAttachRestrictionForCarrier() RemoteException:" + ex);
            ex.rethrowFromSystemServer();
        }
    }

    /**
     * Get reasons for disallowing satellite attach, as requested by
     * {@link #addSatelliteAttachRestrictionForCarrier(int, Executor, Consumer)}
     *
     * @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.
     * @hide
     */
    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
    @SatelliteCommunicationRestrictionReason
    public @NonNull Set<Integer> getSatelliteAttachRestrictionReasonsForCarrier() {
        try {
            ITelephony telephony = getITelephony();
            if (telephony != null) {
                int[] receivedArray =
                        telephony.getSatelliteAttachRestrictionReasonsForCarrier(mSubId);
                if (receivedArray.length == 0) {
                    logd("received set is empty, create empty set");
                    return new HashSet<>();
                } else {
                    return Arrays.stream(receivedArray).boxed().collect(Collectors.toSet());
                }
            } else {
                throw new IllegalStateException("telephony service is null.");
            }
        } catch (RemoteException ex) {
            loge("getSatelliteAttachRestrictionReasonsForCarrier() RemoteException: " + ex);
            ex.rethrowFromSystemServer();
        }
        return null;
    }

    private static ITelephony getITelephony() {
        ITelephony binder = ITelephony.Stub.asInterface(TelephonyFrameworkInitializer
                .getTelephonyServiceManager()
+60 −0
Original line number Diff line number Diff line
@@ -382,4 +382,64 @@ oneway interface ISatellite {
     */
    void requestTimeForNextSatelliteVisibility(in IIntegerConsumer resultCallback,
            in IIntegerConsumer callback);

    /**
     * Set the non-terrestrial PLMN with lower priority than terrestrial networks.
     * MCC/MNC broadcast by the non-terrestrial networks may not be included in OPLMNwACT file on
     * SIM profile. Acquisition of satellite based system is lower priority to terrestrial
     * networks. UE shall make all attempts to acquire terrestrial service prior to camping on
     * satellite LTE service.
     *
     * @param simSlot Indicates the SIM slot to which this API will be applied. The modem will use
     *                this information to determine the relevant carrier.
     * @param plmnList The list of roaming PLMN used for connecting to satellite networks.
     * @param resultCallback The callback to receive the error code result of the operation.
     *
     * Valid error codes returned:
     *   SatelliteError:NONE
     *   SatelliteError:INVALID_ARGUMENTS
     *   SatelliteError:INVALID_MODEM_STATE
     *   SatelliteError:MODEM_ERR
     *   SatelliteError:NO_RESOURCES
     *   SatelliteError:RADIO_NOT_AVAILABLE
     *   SatelliteError:REQUEST_NOT_SUPPORTED
     */
    void setSatellitePlmn(int simSlot, in List<String> plmnList,
            in IIntegerConsumer resultCallback);

    /**
     * Enable or disable satellite in the cellular modem associated with a carrier.
     * Refer setSatellitePlmn for the details of satellite PLMN scanning process.
     *
     * @param simSlot Indicates the SIM slot to which this API will be applied. The modem will use
     *                this information to determine the relevant carrier.
     * @param serial Serial number of request.
     * @param enable {@code true} to enable satellite, {@code false} to disable satellite.
     *
     * Valid errors returned:
     *   SatelliteError:NONE
     *   SatelliteError:INVALID_MODEM_STATE
     *   SatelliteError:MODEM_ERR
     *   SatelliteError:RADIO_NOT_AVAILABLE
     *   SatelliteError:REQUEST_NOT_SUPPORTED
     */
    void setSatelliteEnabledForCarrier(int simSlot, boolean satelliteEnabled,
         in IIntegerConsumer callback);

    /**
     * Check whether satellite is enabled in the cellular modem associated with a carrier.
     *
     * @param simSlot Indicates the SIM slot to which this API will be applied. The modem will use
     *                this information to determine the relevant carrier.
     * @param serial Serial number of request.
     *
     * Valid errors returned:
     *   SatelliteError:NONE
     *   SatelliteError:INVALID_MODEM_STATE
     *   SatelliteError:MODEM_ERR
     *   SatelliteError:RADIO_NOT_AVAILABLE
     *   SatelliteError:REQUEST_NOT_SUPPORTED
     */
    void requestIsSatelliteEnabledForCarrier(int simSlot, in IIntegerConsumer resultCallback,
            in IBooleanConsumer callback);
}
+100 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import com.android.internal.telephony.IBooleanConsumer;
import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.util.TelephonyUtils;

import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
@@ -212,6 +213,34 @@ public class SatelliteImplBase extends SatelliteService {
                    "requestTimeForNextSatelliteVisibility");
        }

        @Override
        public void setSatellitePlmn(int simSlot, List<String> plmnList,
                IIntegerConsumer errorCallback)
                throws RemoteException {
            executeMethodAsync(
                    () -> SatelliteImplBase.this
                            .setSatellitePlmn(simSlot, plmnList, errorCallback),
                    "setSatellitePlmn");
        }

        @Override
        public void setSatelliteEnabledForCarrier(int simSlot, boolean enableSatellite,
                IIntegerConsumer errorCallback) throws RemoteException {
            executeMethodAsync(
                    () -> SatelliteImplBase.this
                            .setSatelliteEnabledForCarrier(simSlot, enableSatellite, errorCallback),
                    "setSatelliteEnabledForCarrier");
        }

        @Override
        public void requestIsSatelliteEnabledForCarrier(int simSlot, IIntegerConsumer errorCallback,
                IBooleanConsumer callback) throws RemoteException {
            executeMethodAsync(
                    () -> SatelliteImplBase.this
                            .requestIsSatelliteEnabledForCarrier(simSlot, errorCallback, callback),
                    "requestIsSatelliteEnabledForCarrier");
        }

        // Call the methods with a clean calling identity on the executor and wait indefinitely for
        // the future to return.
        private void executeMethodAsync(Runnable r, String errorLogName) throws RemoteException {
@@ -618,4 +647,75 @@ public class SatelliteImplBase extends SatelliteService {
            @NonNull IIntegerConsumer callback) {
        // stub implementation
    }


    /**
     * Set the non-terrestrial PLMN with lower priority than terrestrial networks.
     * MCC/MNC broadcast by the non-terrestrial networks may not be included in OPLMNwACT file on
     * SIM profile. Acquisition of satellite based system is lower priority to terrestrial
     * networks. UE shall make all attempts to acquire terrestrial service prior to camping on
     * satellite LTE service.
     * This method must only take effect if {@link #setSatelliteEnabledForCarrier} is {@code true},
     * and return an error otherwise.
     *
     * @param simLogicalSlotIndex Indicates the SIM logical slot index to which this API will be
     * applied. The modem will use this information to determine the relevant carrier.
     * @param errorCallback The callback to receive the error code result of the operation.
     * @param plmnList The list of roaming PLMN used for connecting to satellite networks.
     *
     * Valid error codes returned:
     *   SatelliteError:NONE
     *   SatelliteError:INVALID_ARGUMENTS
     *   SatelliteError:INVALID_MODEM_STATE
     *   SatelliteError:MODEM_ERR
     *   SatelliteError:NO_RESOURCES
     *   SatelliteError:RADIO_NOT_AVAILABLE
     *   SatelliteError:REQUEST_NOT_SUPPORTED
     */
    public void setSatellitePlmn(@NonNull int simLogicalSlotIndex, @NonNull List<String> plmnList,
            @NonNull IIntegerConsumer errorCallback) {
        // stub implementation
    }

    /**
     * Request to enable or disable carrier supported satellite plmn scan and attach by modem.
     * Refer {@link #setSatellitePlmn} for the details of satellite PLMN scanning process.
     *
     * @param simLogicalSlotIndex Indicates the SIM logical slot index to which this API will be
     * applied. The modem will use this information to determine the relevant carrier.
     * @param satelliteEnabled {@code true} to enable satellite, {@code false} to disable satellite.
     * @param callback {@code true} to enable satellite, {@code false} to disable satellite.
     *
     * Valid errors returned:
     *   SatelliteError:NONE
     *   SatelliteError:INVALID_MODEM_STATE
     *   SatelliteError:MODEM_ERR
     *   SatelliteError:RADIO_NOT_AVAILABLE
     *   SatelliteError:REQUEST_NOT_SUPPORTED
     */
    public void setSatelliteEnabledForCarrier(@NonNull int simLogicalSlotIndex,
            @NonNull boolean satelliteEnabled, @NonNull IIntegerConsumer callback) {
        // stub implementation
    }

    /**
     * Request to get whether the satellite is enabled in the cellular modem associated with a
     * carrier.
     *
     * @param simLogicalSlotIndex Indicates the SIM logical slot index to which this API will be
     * applied. The modem will use this information to determine the relevant carrier.
     * @param errorCallback The callback to receive the error code result of the operation.
     * @param callback {@code true} to satellite enabled, {@code false} to satellite disabled.
     *
     * Valid errors returned:
     *   SatelliteError:NONE
     *   SatelliteError:INVALID_MODEM_STATE
     *   SatelliteError:MODEM_ERR
     *   SatelliteError:RADIO_NOT_AVAILABLE
     *   SatelliteError:REQUEST_NOT_SUPPORTED
     */
    public void requestIsSatelliteEnabledForCarrier(@NonNull int simLogicalSlotIndex,
            @NonNull IIntegerConsumer errorCallback, @NonNull IBooleanConsumer callback) {
        // stub implementation
    }
}
+38 −0
Original line number Diff line number Diff line
@@ -3033,4 +3033,42 @@ interface ITelephony {
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
                 + "android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)")
     List<String> getShaIdFromAllowList(String pkgName, int carrierId);

    /**
     * Add a restriction reason for disallowing satellite communication.
     *
     * @param subId The subId of the subscription to request for.
     * @param reason Reason for disallowing satellite communication for carrier.
     * @param callback Listener for the {@link SatelliteManager.SatelliteError} result of the
     * operation.
     */
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
    void addSatelliteAttachRestrictionForCarrier(int subId, int reason,
            in IIntegerConsumer callback);

    /**
     * Remove a restriction reason for disallowing satellite communication.
     *
     * @param subId The subId of the subscription to request for.
     * @param reason Reason for disallowing satellite communication.
     * @param callback Listener for the {@link SatelliteManager.SatelliteError} result of the
     * operation.
     */
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
    void removeSatelliteAttachRestrictionForCarrier(int subId, int reason,
            in IIntegerConsumer callback);

    /**
     * Get reasons for disallowing satellite communication, as requested by
     * {@link #addSatelliteAttachRestrictionForCarrier(int, int)}.
     *
     * @param subId The subId of the subscription to request for.
     *
     * @return Set of reasons for disallowing satellite communication.
     */
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
    int[] getSatelliteAttachRestrictionReasonsForCarrier(int subId);
}