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

Commit 67f50390 authored by Aishwarya Mallampati's avatar Aishwarya Mallampati Committed by Android (Google) Code Review
Browse files

Merge "Added Satellite Messaging APIs."

parents 0435f125 d8c23e3f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.telephony.satellite;

import android.telephony.satellite.PointingInfo;
import android.telephony.satellite.SatelliteDatagram;

/**
 * Interface for satellite state listener.
@@ -26,4 +27,7 @@ oneway interface ISatelliteStateListener {
    void onSatelliteProvisionStateChanged(in boolean provisioned);
    void onSatellitePositionUpdate(in PointingInfo pointingInfo);
    void onMessageTransferStateUpdate(in int state);
    void onSatelliteModemStateChange(in int state);
    void onPendingMessageCount(in int count);
    void onSatelliteDatagrams(in SatelliteDatagram[] datagrams);
}
+60 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.os.Binder;

import java.lang.ref.WeakReference;
import java.util.List;
import java.util.concurrent.Executor;

/**
@@ -88,6 +89,34 @@ public class SatelliteCallback {
                @SatelliteManager.SatelliteMessageTransferState int state);
    }

    /**
     * Interface for satellite state change listener.
     */
    public interface SatelliteStateListener {
        /**
         * Called when satellite state changes.
         * @param state - The new satellite state.
         */
        void onSatelliteModemStateChange(@SatelliteManager.SatelliteModemState int state);

        /**
         * Called when there are pending messages to be received from satellite.
         * @param count - pending message count.
         */
        void onPendingMessageCount(int count);
    }

    /**
     * Interface for satellite datagram listener.
     */
    public interface SatelliteDatagramListener {
        /**
         * Called when there are incoming datagrams to be received.
         * @param datagrams - datagrams to be received over satellite.
         */
        void onSatelliteDatagrams(SatelliteDatagram[] datagrams);
    }

    private static class ISatelliteStateListenerStub extends ISatelliteStateListener.Stub {
        private WeakReference<SatelliteCallback> mSatelliteCallbackWeakRef;
        private Executor mExecutor;
@@ -124,5 +153,36 @@ public class SatelliteCallback {
            Binder.withCleanCallingIdentity(() -> mExecutor.execute(
                    () -> listener.onMessageTransferStateUpdate(state)));
        }


        @Override
        public void onSatelliteModemStateChange(@SatelliteManager.SatelliteModemState int state) {
            SatelliteStateListener listener =
                    (SatelliteStateListener) mSatelliteCallbackWeakRef.get();
            if (listener == null) return;

            Binder.withCleanCallingIdentity(() -> mExecutor.execute(
                    () -> listener.onSatelliteModemStateChange(state)));
        }

        @Override
        public void onPendingMessageCount(int count) {
            SatelliteStateListener listener =
                    (SatelliteStateListener) mSatelliteCallbackWeakRef.get();
            if (listener == null) return;

            Binder.withCleanCallingIdentity(() -> mExecutor.execute(
                    () -> listener.onPendingMessageCount(count)));
        }

        @Override
        public void onSatelliteDatagrams(SatelliteDatagram[] datagrams) {
            SatelliteDatagramListener listener =
                    (SatelliteDatagramListener) mSatelliteCallbackWeakRef.get();
            if (listener == null) return;

            Binder.withCleanCallingIdentity(() -> mExecutor.execute(
                    () -> listener.onSatelliteDatagrams(datagrams)));
        }
    }
}
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright 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;

parcelable SatelliteDatagram;
+75 −0
Original line number Diff line number Diff line
/*
 * 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;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * @hide
 */
public final class SatelliteDatagram implements Parcelable {
    /**
     * Datagram to be sent or received over satellite.
     */
    private byte[] mData;

    /**
     * @hide
     */
    public SatelliteDatagram(@NonNull byte[] data) {
        mData = data;
    }

    private SatelliteDatagram(Parcel in) {
        readFromParcel(in);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(@NonNull Parcel out, int flags) {
        out.writeByteArray(mData);
    }

    public static final @android.annotation.NonNull Creator<SatelliteDatagram> CREATOR =
            new Creator<SatelliteDatagram>() {
                @Override
                public SatelliteDatagram createFromParcel(Parcel in) {
                    return new SatelliteDatagram(in);
                }

                @Override
                public SatelliteDatagram[] newArray(int size) {
                    return new SatelliteDatagram[size];
                }
            };

    @Nullable
    public byte[] getSatelliteDatagram() {
        return mData;
    }

    private void readFromParcel(Parcel in) {
        mData = in.createByteArray();
    }
}
+203 −0
Original line number Diff line number Diff line
@@ -490,6 +490,44 @@ public class SatelliteManager {
    })
    public @interface SatelliteMessageTransferState {}

    /* Satellite modem is in idle state. */
    public static final int SATELLITE_MODEM_STATE_IDLE = 0;

    /* Satellite modem is listening for incoming messages. */
    public static final int SATELLITE_MODEM_STATE_LISTENING = 1;

    /* Satellite modem is sending and/or receiving messages. */
    public static final int SATELLITE_MODEM_STATE_MESSAGE_TRANSFERRING = 2;

    /* Satellite modem is powered off */
    public static final int SATELLITE_MODEM_STATE_OFF = 3;

    /** @hide */
    @IntDef(prefix = {"SATELLITE_STATE_"},
            value = {
                    SATELLITE_MODEM_STATE_IDLE,
                    SATELLITE_MODEM_STATE_LISTENING,
                    SATELLITE_MODEM_STATE_MESSAGE_TRANSFERRING,
                    SATELLITE_MODEM_STATE_OFF
            })
    @Retention(RetentionPolicy.SOURCE)
    public @interface SatelliteModemState {}

    /** SOS SMS */
    public static final int DATAGRAM_TYPE_SOS_SMS = 0;

    /** Location sharing message */
    public static final int DATAGRAM_TYPE_LOCATION_SHARING = 3;

    @IntDef(
            prefix = "DATAGRAM_TYPE_",
            value = {
                    DATAGRAM_TYPE_SOS_SMS,
                    DATAGRAM_TYPE_LOCATION_SHARING,
            })
    @Retention(RetentionPolicy.SOURCE)
    public @interface DatagramType {}

    /**
     * Start receiving satellite position updates.
     * This can be called by the pointing UI when the user starts pointing to the satellite.
@@ -867,6 +905,171 @@ public class SatelliteManager {
        }
    }

    /**
     * Register for listening to satellite modem state changes.
     *
     * @param executor - The executor on which the callback will be called.
     * @param callback - The callback to handle the satellite state change event. This
     *                 SatelliteCallback should implement the interface
     *                 {@link SatelliteCallback.SatelliteStateListener}.
     *
     * @return The error code of the request.
     * @throws SecurityException if the caller doesn't have required permission.
     * @throws IllegalStateException if the Telephony process is not currently available.
     */
    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
    @SatelliteError
    public int registerForSatelliteModemStateChange(@NonNull @CallbackExecutor Executor executor,
            @NonNull SatelliteCallback callback) {
        Objects.requireNonNull(executor);
        Objects.requireNonNull(callback);

        try {
            ITelephony telephony = getITelephony();
            if (telephony != null) {
                callback.init(executor);
                return telephony.registerForSatelliteModemStateChange(mSubId,
                        callback.getCallbackStub());
            } else {
                throw new IllegalStateException("telephony service is null.");
            }
        } catch (RemoteException ex) {
            loge("registerForSatelliteModemStateChange() RemoteException:" + ex);
            ex.rethrowFromSystemServer();
        }
        return SATELLITE_REQUEST_FAILED;
    }

    /**
     * Unregister to stop listening to satellite modem state changes.
     *
     * @param callback - The callback that was passed to
     * {@link #registerForSatelliteModemStateChange(Executor, SatelliteCallback)}
     *
     * @return The error code of the request.
     * @throws SecurityException if the caller doesn't have required permission.
     * @throws IllegalStateException if the Telephony process is not currently available.
     */
    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
    @SatelliteError
    public int unregisterForSatelliteModemStateChange(@NonNull SatelliteCallback callback) {
        Objects.requireNonNull(callback);

        if (callback.getCallbackStub() == null) {
            loge("unregisterForSatelliteModemStateChange: callbackStub is null");
            return SATELLITE_INVALID_ARGUMENTS;
        }

        try {
            ITelephony telephony = getITelephony();
            if (telephony != null) {
                return telephony.unregisterForSatelliteModemStateChange(mSubId,
                        callback.getCallbackStub());
            } else {
                throw new IllegalStateException("telephony service is null.");
            }
        } catch (RemoteException ex) {
            loge("unregisterForSatelliteModemStateChange() RemoteException:" + ex);
            ex.rethrowFromSystemServer();
        }
        return SATELLITE_REQUEST_FAILED;
    }

    /**
     * Register to receive incoming datagrams over satellite.
     *
     * @param datagramType - type of datagram
     * @param executor - The executor on which the callback will be called.
     * @param callback - The callback to handle incoming datagrams over satellite. This
     *                 SatelliteCallback should implement the interface
     *                 {@link SatelliteCallback.SatelliteDatagramListener}.
     *
     * @return The error code of the request.
     * @throws SecurityException if the caller doesn't have required permission.
     * @throws IllegalStateException if the Telephony process is not currently available.
     */
    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
    @SatelliteError
    public int registerForSatelliteDatagram(@DatagramType int datagramType,
            @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteCallback callback) {
        Objects.requireNonNull(executor);
        Objects.requireNonNull(callback);

        try {
            ITelephony telephony = getITelephony();
            if (telephony != null) {
                callback.init(executor);
                return telephony.registerForSatelliteDatagram(mSubId, datagramType,
                            callback.getCallbackStub());
            } else {
                throw new IllegalStateException("telephony service is null.");
            }
        } catch (RemoteException ex) {
            loge("registerForSatelliteDatagram() RemoteException:" + ex);
            ex.rethrowFromSystemServer();
        }
        return SATELLITE_REQUEST_FAILED;
    }

    /**
     * Unregister to stop receiving incoming datagrams over satellite.
     *
     * @param callback - The callback that was passed to
     * {@link #registerForSatelliteDatagram(int, Executor, SatelliteCallback)}
     *
     * @return The error code of the request.
     * @throws SecurityException if the caller doesn't have required permission.
     * @throws IllegalStateException if the Telephony process is not currently available.
     */
    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
    @SatelliteError
    public int unregisterForSatelliteDatagram(@NonNull SatelliteCallback callback) {
        Objects.requireNonNull(callback);

        if (callback.getCallbackStub() == null) {
            loge("unregisterForSatelliteDatagram: callbackStub is null");
            return SATELLITE_INVALID_ARGUMENTS;
        }

        try {
            ITelephony telephony = getITelephony();
            if (telephony != null) {
                return telephony.unregisterForSatelliteDatagram(mSubId,
                        callback.getCallbackStub());
            } else {
                throw new IllegalStateException("telephony service is null.");
            }
        } catch (RemoteException ex) {
            loge("unregisterForSatelliteDatagram() RemoteException:" + ex);
            ex.rethrowFromSystemServer();
        }
        return SATELLITE_REQUEST_FAILED;
    }

    /**
     * Poll pending satellite datagrams over satellite.
     *
     * @return The result of the operation.
     * @throws SecurityException if the caller doesn't have required permission.
     * @throws IllegalStateException if the Telephony process is not currently available.
     */
    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
    @SatelliteError
    public int pollPendingSatelliteDatagrams() {
        try {
            ITelephony telephony = getITelephony();
            if (telephony != null) {
                return telephony.pollPendingSatelliteDatagrams(mSubId);
            } else {
                throw new IllegalStateException("telephony service is null.");
            }
        } catch (RemoteException ex) {
            loge("pollPendingSatelliteDatagrams() RemoteException:" + ex);
            ex.rethrowFromSystemServer();
        }
        return SATELLITE_REQUEST_FAILED;
    }

    private static ITelephony getITelephony() {
        ITelephony binder = ITelephony.Stub.asInterface(TelephonyFrameworkInitializer
                .getTelephonyServiceManager()
Loading