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

Commit 6402b996 authored by Hakjun Choi's avatar Hakjun Choi Committed by Android (Google) Code Review
Browse files

Merge "Add new satellite APIs for cellular modems" into main

parents 24579c77 43897838
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);
}