Snap for 12715579 from a0d10db0c0799deb410d865251eee045680295c8 to mainline-os-statsd-release Change-Id: I61e291cb1537e584b4bf9bb295c41f0eff3ead92
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/EarfcnRangeWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/EarfcnRangeWrapper.java new file mode 100644 index 0000000..b2f9821 --- /dev/null +++ b/satellite_client/src/android/telephony/satellite/wrapper/EarfcnRangeWrapper.java
@@ -0,0 +1,139 @@ +/* + * 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 android.telephony.satellite.wrapper; + +import android.annotation.FlaggedApi; +import android.annotation.IntRange; +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.telephony.flags.Flags; + +import java.util.Objects; + +/** + * EARFCN (E-UTRA Absolute Radio Frequency Channel Number): A number that identifies a + * specific frequency channel in LTE/5G NR, used to define the carrier frequency. + * The range can be [0 ~ 65535] according to the 3GPP TS 36.101 + * + * In satellite communication: + * - Efficient frequency allocation across a wide coverage area. + * - Handles Doppler shift due to satellite movement. + * - Manages interference with terrestrial networks. + * + * See 3GPP TS 36.101 and 38.101-1 for details. + * + * @hide + */ +public class EarfcnRangeWrapper implements Parcelable { + + /** + * The start frequency of the earfcn range and is inclusive in the range + */ + private int mStartEarfcn; + + /** + * The end frequency of the earfcn range and is inclusive in the range. + */ + private int mEndEarfcn; + + private EarfcnRangeWrapper(@NonNull Parcel in) { + readFromParcel(in); + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mStartEarfcn); + dest.writeInt(mEndEarfcn); + } + + private void readFromParcel(Parcel in) { + mStartEarfcn = in.readInt(); + mEndEarfcn = in.readInt(); + } + + /** + * Constructor for the EarfcnRangeWrapper class. + * The range can be [0 ~ 65535] according to the 3GPP TS 36.101 + * + * @param startEarfcn The starting earfcn value. + * @param endEarfcn The ending earfcn value. + */ + public EarfcnRangeWrapper(@IntRange(from = 0, to = 65535) int startEarfcn, + @IntRange(from = 0, to = 65535) int endEarfcn) { + mStartEarfcn = startEarfcn; + mEndEarfcn = endEarfcn; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + @NonNull + public String toString() { + return "startEarfcn: " + mStartEarfcn + ", " + "endEarfcn: " + mEndEarfcn; + } + + @NonNull + public static final Creator<EarfcnRangeWrapper> CREATOR = new Creator<EarfcnRangeWrapper>() { + @Override + public EarfcnRangeWrapper createFromParcel(Parcel in) { + return new EarfcnRangeWrapper(in); + } + + @Override + public EarfcnRangeWrapper[] newArray(int size) { + return new EarfcnRangeWrapper[size]; + } + }; + + /** + * Returns the starting earfcn value for this range. + * It can be [0 ~ 65535] according to the 3GPP TS 36.101 + * + * @return The starting earfcn. + */ + public @IntRange(from = 0, to = 65535) int getStartEarfcn() { + return mStartEarfcn; + } + + /** + * Returns the ending earfcn value for this range. + * It can be [0 ~ 65535] according to the 3GPP TS 36.101 + * + * @return The ending earfcn. + */ + public @IntRange(from = 0, to = 65535) int getEndEarfcn() { + return mEndEarfcn; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof EarfcnRangeWrapper that)) return false; + + return (that.mStartEarfcn == mStartEarfcn) && (that.mEndEarfcn == mEndEarfcn); + } + + @Override + public int hashCode() { + return Objects.hash(mStartEarfcn, mEndEarfcn); + } +}
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteAccessConfigurationWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteAccessConfigurationWrapper.java new file mode 100644 index 0000000..694a2be --- /dev/null +++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteAccessConfigurationWrapper.java
@@ -0,0 +1,142 @@ +/* + * 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 android.telephony.satellite.wrapper; + +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.NonNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * SatelliteAccessConfigurationWrapper is used to store satellite access configuration + * that will be applied to the satellite communication at the corresponding region. + * + * @hide + */ +public class SatelliteAccessConfigurationWrapper implements Parcelable { + /** + * The list of satellites available at the current location. + */ + @NonNull + private List<SatelliteInfoWrapper> mSatelliteInfoList; + + /** + * The list of tag IDs associated with the current location + */ + @NonNull + private List<Integer> mTagIdList; + + /** + * Constructor for {@link SatelliteAccessConfigurationWrapper}. + * + * @param satelliteInfos The list of {@link SatelliteInfoWrapper} objects representing + * the satellites accessible with this configuration. + * @param tagidList The list of tag IDs associated with this configuration. + */ + public SatelliteAccessConfigurationWrapper(@NonNull List<SatelliteInfoWrapper> satelliteInfos, + @NonNull List<Integer> tagidList) { + mSatelliteInfoList = satelliteInfos; + mTagIdList = tagidList; + } + + public SatelliteAccessConfigurationWrapper(Parcel in) { + mSatelliteInfoList = in.createTypedArrayList(SatelliteInfoWrapper.CREATOR); + mTagIdList = new ArrayList<>(); + in.readList(mTagIdList, Integer.class.getClassLoader(), Integer.class); + } + + public static final Parcelable.Creator<SatelliteAccessConfigurationWrapper> CREATOR = + new Parcelable.Creator<SatelliteAccessConfigurationWrapper>() { + @Override + public SatelliteAccessConfigurationWrapper createFromParcel(Parcel in) { + return new SatelliteAccessConfigurationWrapper(in); + } + + @Override + public SatelliteAccessConfigurationWrapper[] newArray(int size) { + return new SatelliteAccessConfigurationWrapper[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + /** + * @param dest The Parcel in which the object should be written. + * @param flags Additional flags about how the object should be written. + * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}. + */ + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeTypedList(mSatelliteInfoList); + dest.writeList(mTagIdList); + } + + /** + * Returns a list of {@link SatelliteInfoWrapper} objects representing the satellites + * associated with this object. + * + * @return The list of {@link SatelliteInfoWrapper} objects. + */ + @NonNull + public List<SatelliteInfoWrapper> getSatelliteInfos() { + return mSatelliteInfoList; + } + + /** + * Returns a list of tag IDs associated with this object. + * + * @return The list of tag IDs. + */ + @NonNull + public List<Integer> getTagIds() { + return mTagIdList; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SatelliteAccessConfigurationWrapper that)) return false; + + return mSatelliteInfoList.equals(that.mSatelliteInfoList) + && Objects.equals(mTagIdList, that.mTagIdList); + } + + @Override + public int hashCode() { + int result = Objects.hash(mSatelliteInfoList); + result = 31 * result + Objects.hashCode(mTagIdList); + return result; + } + + @Override + @NonNull + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("SatelliteAccessConfigurationWrapper{"); + sb.append("mSatelliteInfoList=").append(mSatelliteInfoList); + sb.append(", mTagIds=").append(mTagIdList); + sb.append('}'); + return sb.toString(); + } +}
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteCommunicationAllowedStateCallbackWrapper2.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteCommunicationAllowedStateCallbackWrapper2.java new file mode 100644 index 0000000..744b09c --- /dev/null +++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteCommunicationAllowedStateCallbackWrapper2.java
@@ -0,0 +1,46 @@ +/* + * 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 android.telephony.satellite.wrapper; + +import android.annotation.Nullable; + +/** A callback class for monitoring satellite communication allowed state change events. */ +public interface SatelliteCommunicationAllowedStateCallbackWrapper2 { + /** + * Telephony does not guarantee that whenever there is a change in communication allowed state, + * this API will be called. Telephony does its best to detect the changes and notify its + * listeners accordingly. + * + * @param isAllowed {@code true} means satellite allow state is changed, + * {@code false} satellite allow state is not changed + */ + void onSatelliteCommunicationAllowedStateChanged(boolean isAllowed); + + /** + * Callback method invoked when the satellite access configuration changes + * + * @param satelliteAccessConfigurationWrapper The satellite access configuration associated with + * the current location. When satellite is not + * allowed at the current location, + * {@code satelliteAccessConfigurationWrapper} + * will be null. + * @hide + */ + default void onSatelliteAccessConfigurationChanged( + @Nullable SatelliteAccessConfigurationWrapper satelliteAccessConfigurationWrapper) { + }; +}
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteInfoWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteInfoWrapper.java new file mode 100644 index 0000000..bdbb379 --- /dev/null +++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteInfoWrapper.java
@@ -0,0 +1,195 @@ +/* + * 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 android.telephony.satellite.wrapper; + +import android.annotation.Nullable; +import android.os.Parcel; +import android.os.ParcelUuid; +import android.os.Parcelable; + +import androidx.annotation.NonNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +/** + * SatelliteInfoWrapper stores a satellite's identification, position, and frequency information + * facilitating efficient satellite communications. + * + * @hide + */ +public class SatelliteInfoWrapper implements Parcelable { + /** + * Unique identification number for the satellite. + * This ID is used to distinguish between different satellites in the network. + */ + @NonNull + private UUID mId; + + /** + * Position information of a geostationary satellite. + * This includes the longitude and altitude of the satellite. + * If the SatellitePosition is invalid, + * longitudeDegree and altitudeKm will be represented as DOUBLE.NaN. + */ + @NonNull + private SatellitePositionWrapper mPosition; + + /** + * The frequency band list to scan. Bands and earfcns won't overlap. + * Bands will be filled only if the whole band is needed. + * Maximum length of the vector is 8. + */ + private List<Integer> mBandList; + + /** + * EARFCN (E-UTRA Absolute Radio Frequency Channel Number) range list + * The supported frequency range list. + * Maximum length of the vector is 8. + */ + private final List<EarfcnRangeWrapper> mEarfcnRangeList; + + protected SatelliteInfoWrapper(Parcel in) { + ParcelUuid parcelUuid = in.readParcelable( + ParcelUuid.class.getClassLoader(), ParcelUuid.class); + if (parcelUuid != null) { + mId = parcelUuid.getUuid(); + } + mPosition = in.readParcelable(SatellitePositionWrapper.class.getClassLoader(), + SatellitePositionWrapper.class); + mBandList = new ArrayList<>(); + in.readList(mBandList, Integer.class.getClassLoader(), Integer.class); + mEarfcnRangeList = in.createTypedArrayList(EarfcnRangeWrapper.CREATOR); + } + + /** + * Constructor for {@link SatelliteInfoWrapper}. + * + * @param satelliteId The ID of the satellite. + * @param satellitePosition The {@link SatellitePositionWrapper} of the satellite. + * @param bandList The list of frequency bandList supported by the satellite. + * @param earfcnRanges The list of {@link EarfcnRangeWrapper} objects representing the + * EARFCN ranges supported by the satellite. + */ + public SatelliteInfoWrapper(@NonNull UUID satelliteId, + @NonNull SatellitePositionWrapper satellitePosition, + @NonNull List<Integer> bandList, @NonNull List<EarfcnRangeWrapper> earfcnRanges) { + mId = satelliteId; + mPosition = satellitePosition; + mBandList = bandList; + mEarfcnRangeList = earfcnRanges; + } + + public static final Parcelable.Creator<SatelliteInfoWrapper> + CREATOR = new Parcelable.Creator<SatelliteInfoWrapper>() { + @Override + public SatelliteInfoWrapper createFromParcel(Parcel in) { + return new SatelliteInfoWrapper(in); + } + + @Override + public SatelliteInfoWrapper[] newArray(int size) { + return new SatelliteInfoWrapper[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeParcelable(new ParcelUuid(mId), flags); + dest.writeParcelable(mPosition, flags); + dest.writeList(mBandList); + dest.writeTypedList(mEarfcnRangeList); + } + + /** + * Returns the ID of the satellite. + * + * @return The satellite ID. + */ + @NonNull + public UUID getSatelliteId() { + return mId; + } + + /** + * Returns the position of the satellite. + * + * @return The {@link SatellitePositionWrapper} of the satellite. + */ + @NonNull + public SatellitePositionWrapper getSatellitePosition() { + return mPosition; + } + + /** + * Returns the list of frequency bands supported by the satellite. + * + * @return The list of frequency bands. + */ + @NonNull + public List<Integer> getBands() { + return mBandList; + } + + /** + * Returns the list of EARFCN ranges supported by the satellite. + * + * @return The list of {@link EarfcnRangeWrapper} objects. + */ + @NonNull + public List<EarfcnRangeWrapper> getEarfcnRanges() { + return mEarfcnRangeList; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SatelliteInfoWrapper that)) return false; + + return mId.equals(that.mId) + && Objects.equals(mPosition, that.mPosition) + && Objects.equals(mBandList, that.mBandList) + && mEarfcnRangeList.equals(that.mEarfcnRangeList); + } + + @Override + public int hashCode() { + int result = Objects.hash(mId, mPosition, mEarfcnRangeList); + result = 31 * result + Objects.hashCode(mBandList); + return result; + } + + @Override + @NonNull + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("SatelliteInfoWrapper{"); + sb.append("mId=").append(mId); + sb.append(", mPosition=").append(mPosition); + sb.append(", mBandList=").append(mBandList); + sb.append(", mEarfcnRangeList=").append(mEarfcnRangeList); + sb.append('}'); + return sb.toString(); + } +}
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java index d2d13f0..2019eb1 100644 --- a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java +++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java
@@ -26,6 +26,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; +import android.os.Binder; import android.os.CancellationSignal; import android.os.OutcomeReceiver; import android.telephony.NetworkRegistrationInfo; @@ -35,15 +36,18 @@ import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import android.telephony.satellite.AntennaPosition; +import android.telephony.satellite.EarfcnRange; import android.telephony.satellite.EnableRequestAttributes; import android.telephony.satellite.NtnSignalStrength; import android.telephony.satellite.NtnSignalStrengthCallback; import android.telephony.satellite.PointingInfo; +import android.telephony.satellite.SatelliteAccessConfiguration; import android.telephony.satellite.SatelliteCapabilities; import android.telephony.satellite.SatelliteCapabilitiesCallback; import android.telephony.satellite.SatelliteCommunicationAllowedStateCallback; import android.telephony.satellite.SatelliteDatagram; import android.telephony.satellite.SatelliteDatagramCallback; +import android.telephony.satellite.SatelliteInfo; import android.telephony.satellite.SatelliteManager; import android.telephony.satellite.SatelliteModemStateCallback; import android.telephony.satellite.SatelliteProvisionStateCallback; @@ -52,6 +56,7 @@ import android.telephony.satellite.SatelliteSubscriberProvisionStatus; import android.telephony.satellite.SatelliteSupportedStateCallback; import android.telephony.satellite.SatelliteTransmissionUpdateCallback; +import android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback; import com.android.internal.telephony.flags.Flags; import com.android.telephony.Rlog; @@ -61,7 +66,7 @@ import java.lang.reflect.Method; import java.time.Duration; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -127,6 +132,14 @@ SatelliteCommunicationAllowedStateCallback> sSatelliteCommunicationAllowedStateCallbackWrapperMap = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap<SatelliteCommunicationAllowedStateCallbackWrapper2, + SatelliteCommunicationAllowedStateCallback> + sSatelliteCommunicationAllowedStateCallbackWrapperMap2 = new ConcurrentHashMap<>(); + + private static final ConcurrentHashMap<SelectedNbIotSatelliteSubscriptionCallbackWrapper, + SelectedNbIotSatelliteSubscriptionCallback> + sSelectedNbIotSatelliteSubscriptionCallbackWrapperMap = new ConcurrentHashMap<>(); + private final SatelliteManager mSatelliteManager; private final SubscriptionManager mSubscriptionManager; private final TelephonyManager mTelephonyManager; @@ -557,6 +570,13 @@ boolean isEmergency, @NonNull @CallbackExecutor Executor executor, @SatelliteResult @NonNull Consumer<Integer> resultListener) { + if (mSatelliteManager == null) { + logd("requestEnabled: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))); + return; + } + mSatelliteManager.requestEnabled(new EnableRequestAttributes.Builder(enableSatellite) .setDemoMode(enableDemoMode) .setEmergencyMode(isEmergency) @@ -567,6 +587,14 @@ public void requestIsEnabled( @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("requestIsEnabled: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + OutcomeReceiver internalCallback = new OutcomeReceiver<Boolean, SatelliteException>() { @Override @@ -586,6 +614,14 @@ public void requestIsDemoModeEnabled( @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("requestIsDemoModeEnabled: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + OutcomeReceiver internalCallback = new OutcomeReceiver<Boolean, SatelliteException>() { @Override @@ -605,6 +641,14 @@ public void requestIsEmergencyModeEnabled( @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("requestIsEmergencyModeEnabled: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + OutcomeReceiver internalCallback = new OutcomeReceiver<Boolean, SatelliteException>() { @Override @@ -624,6 +668,12 @@ public void requestIsSupported( @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("requestIsSupported: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onResult(false))); + return; + } + OutcomeReceiver internalCallback = new OutcomeReceiver<Boolean, SatelliteException>() { @Override @@ -643,6 +693,14 @@ public void requestCapabilities( @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<SatelliteCapabilitiesWrapper, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("requestCapabilities: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + OutcomeReceiver internalCallback = new OutcomeReceiver<SatelliteCapabilities, SatelliteException>() { @Override @@ -675,6 +733,12 @@ @NonNull @CallbackExecutor Executor executor, @SatelliteResult @NonNull Consumer<Integer> resultListener, @NonNull SatelliteTransmissionUpdateCallbackWrapper callback) { + if (mSatelliteManager == null) { + logd("startTransmissionUpdates: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))); + return; + } SatelliteTransmissionUpdateCallback internalCallback = new SatelliteTransmissionUpdateCallback() { @@ -729,6 +793,12 @@ @NonNull @CallbackExecutor Executor executor, @SatelliteResult @NonNull Consumer<Integer> resultListener, @NonNull SatelliteTransmissionUpdateCallbackWrapper2 callback) { + if (mSatelliteManager == null) { + logd("startTransmissionUpdates2: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))); + return; + } SatelliteTransmissionUpdateCallback internalCallback = new SatelliteTransmissionUpdateCallback() { @@ -787,6 +857,13 @@ @NonNull SatelliteTransmissionUpdateCallbackWrapper callback, @NonNull @CallbackExecutor Executor executor, @SatelliteResult @NonNull Consumer<Integer> resultListener) { + if (mSatelliteManager == null) { + logd("stopTransmissionUpdates: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))); + return; + } + SatelliteTransmissionUpdateCallback internalCallback = sSatelliteTransmissionUpdateCallbackWrapperMap.remove(callback); if (internalCallback != null) { @@ -805,6 +882,13 @@ @NonNull SatelliteTransmissionUpdateCallbackWrapper2 callback, @NonNull @CallbackExecutor Executor executor, @SatelliteResult @NonNull Consumer<Integer> resultListener) { + if (mSatelliteManager == null) { + logd("stopTransmissionUpdates2: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))); + return; + } + SatelliteTransmissionUpdateCallback internalCallback = sSatelliteTransmissionUpdateCallbackWrapperMap2.remove(callback); if (internalCallback != null) { @@ -823,6 +907,13 @@ @Nullable CancellationSignal cancellationSignal, @NonNull @CallbackExecutor Executor executor, @SatelliteResult @NonNull Consumer<Integer> resultListener) { + if (mSatelliteManager == null) { + logd("provisionService: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))); + return; + } + mSatelliteManager.provisionService( token, provisionData, cancellationSignal, executor, resultListener); } @@ -837,6 +928,13 @@ @NonNull String token, @NonNull @CallbackExecutor Executor executor, @SatelliteResult @NonNull Consumer<Integer> resultListener) { + if (mSatelliteManager == null) { + logd("deprovisionService: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))); + return; + } + mSatelliteManager.deprovisionService(token, executor, resultListener); } @@ -845,6 +943,11 @@ public int registerForProvisionStateChanged( @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteProvisionStateCallbackWrapper callback) { + if (mSatelliteManager == null) { + logd("registerForProvisionStateChanged: mSatelliteManager is null"); + return SatelliteManagerWrapper.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED; + } + SatelliteProvisionStateCallback internalCallback = new SatelliteProvisionStateCallback() { @Override @@ -871,6 +974,11 @@ */ public void unregisterForProvisionStateChanged( @NonNull SatelliteProvisionStateCallbackWrapper callback) { + if (mSatelliteManager == null){ + logd("unregisterForProvisionStateChanged: mSatelliteManager is null"); + return; + } + SatelliteProvisionStateCallback internalCallback = sSatelliteProvisionStateCallbackWrapperMap.remove(callback); if (internalCallback != null) { @@ -882,6 +990,14 @@ public void requestIsProvisioned( @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("requestIsProvisioned: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + OutcomeReceiver internalCallback = new OutcomeReceiver<Boolean, SatelliteException>() { @Override @@ -902,6 +1018,11 @@ public int registerForModemStateChanged( @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteModemStateCallbackWrapper callback) { + if (mSatelliteManager == null) { + logd("registerForModemStateChanged: mSatelliteManager is null"); + return SatelliteManagerWrapper.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED; + } + SatelliteModemStateCallback internalCallback = new SatelliteModemStateCallback() { public void onSatelliteModemStateChanged(@SatelliteModemState int state) { @@ -920,6 +1041,11 @@ public int registerForModemStateChanged( @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteModemStateCallbackWrapper2 callback) { + if (mSatelliteManager == null) { + logd("registerForModemStateChanged: mSatelliteManager is null"); + return SatelliteManagerWrapper.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED; + } + SatelliteModemStateCallback internalCallback = new SatelliteModemStateCallback() { public void onSatelliteModemStateChanged(@SatelliteModemState int state) { @@ -951,6 +1077,11 @@ */ public void unregisterForModemStateChanged( @NonNull SatelliteModemStateCallbackWrapper callback) { + if (mSatelliteManager == null) { + logd("unregisterForModemStateChanged: mSatelliteManager is null"); + return; + } + SatelliteModemStateCallback internalCallback = sSatelliteModemStateCallbackWrapperMap.remove( callback); if (internalCallback != null) { @@ -964,6 +1095,11 @@ */ public void unregisterForModemStateChanged( @NonNull SatelliteModemStateCallbackWrapper2 callback) { + if (mSatelliteManager == null) { + logd("unregisterForModemStateChanged: mSatelliteManager is null"); + return; + } + SatelliteModemStateCallback internalCallback = sSatelliteModemStateCallbackWrapperMap2.remove( callback); if (internalCallback != null) { @@ -976,6 +1112,11 @@ public int registerForIncomingDatagram( @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteDatagramCallbackWrapper callback) { + if (mSatelliteManager == null) { + logd("registerForIncomingDatagram: mSatelliteManager is null"); + return SatelliteManagerWrapper.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED; + } + SatelliteDatagramCallback internalCallback = new SatelliteDatagramCallback() { @Override @@ -1001,6 +1142,11 @@ * before, the request will be ignored. */ public void unregisterForIncomingDatagram(@NonNull SatelliteDatagramCallbackWrapper callback) { + if (mSatelliteManager == null) { + logd("unregisterForIncomingDatagram: mSatelliteManager is null"); + return; + } + SatelliteDatagramCallback internalCallback = sSatelliteDatagramCallbackWrapperMap.remove(callback); if (internalCallback != null) { @@ -1101,6 +1247,13 @@ public void pollPendingDatagrams( @NonNull @CallbackExecutor Executor executor, @SatelliteResult @NonNull Consumer<Integer> resultListener) { + if (mSatelliteManager == null) { + logd("pollPendingDatagrams: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))); + return; + } + mSatelliteManager.pollPendingDatagrams(executor, resultListener); } @@ -1117,6 +1270,13 @@ boolean needFullScreenPointingUI, @NonNull @CallbackExecutor Executor executor, @SatelliteResult @NonNull Consumer<Integer> resultListener) { + if (mSatelliteManager == null) { + logd("sendDatagram: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))); + return; + } + SatelliteDatagram datagramInternal = new SatelliteDatagram(datagram.getSatelliteDatagram()); mSatelliteManager.sendDatagram( datagramType, datagramInternal, needFullScreenPointingUI, executor, resultListener); @@ -1126,6 +1286,14 @@ public void requestIsCommunicationAllowedForCurrentLocation( @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("requestIsCommunicationAllowedForCurrentLocation: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + OutcomeReceiver internalCallback = new OutcomeReceiver<Boolean, SatelliteException>() { @Override @@ -1142,6 +1310,37 @@ executor, internalCallback); } + /** Request to get satellite access configuration for the current location. */ + public void requestSatelliteAccessConfigurationForCurrentLocation( + @NonNull @CallbackExecutor Executor executor, + @NonNull OutcomeReceiver<SatelliteAccessConfigurationWrapper, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("requestSatelliteAccessConfigurationForCurrentLocation: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + + OutcomeReceiver internalCallback = + new OutcomeReceiver<SatelliteAccessConfiguration, SatelliteException>() { + @Override + public void onResult(SatelliteAccessConfiguration result) { + callback.onResult(new SatelliteAccessConfigurationWrapper( + getSatelliteInfoListWrapper(result.getSatelliteInfos()), + result.getTagIds())); + } + + @Override + public void onError(SatelliteException exception) { + callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode())); + } + }; + + mSatelliteManager.requestSatelliteAccessConfigurationForCurrentLocation(executor, + internalCallback); + } + /** * Request to get the duration in seconds after which the satellite will be visible. This will be * {@link Duration#ZERO} if the satellite is currently visible. @@ -1149,6 +1348,14 @@ public void requestTimeForNextSatelliteVisibility( @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Duration, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("requestTimeForNextSatelliteVisibility: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + OutcomeReceiver internalCallback = new OutcomeReceiver<Duration, SatelliteException>() { @Override @@ -1165,9 +1372,82 @@ } /** + * Request to get the currently selected satellite subscription id as an {@link Integer}. + */ + public void requestSelectedNbIotSatelliteSubscriptionId( + @NonNull @CallbackExecutor Executor executor, + @NonNull OutcomeReceiver<Integer, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("requestSelectedNbIotSatelliteSubscriptionId: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + + OutcomeReceiver internalCallback = + new OutcomeReceiver<Integer, SatelliteException>() { + @Override + public void onResult(Integer result) { + callback.onResult(result); + } + + @Override + public void onError(SatelliteException exception) { + callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode())); + } + }; + mSatelliteManager.requestSelectedNbIotSatelliteSubscriptionId(executor, internalCallback); + } + + /** + * Wrapper API to register for selected satellite subscription changed event from the satellite + * service. + * + * @param executor The executor on which the callback will be called. + * @param callback The callback to handle the selected satellite subscription changed event. + */ + @SatelliteResult public int registerForSelectedNbIotSatelliteSubscriptionChanged( + @NonNull @CallbackExecutor Executor executor, + @NonNull SelectedNbIotSatelliteSubscriptionCallbackWrapper callback) { + SelectedNbIotSatelliteSubscriptionCallback internalCallback = + selectedSubId -> callback.onSelectedNbIotSatelliteSubscriptionChanged( + selectedSubId); + sSelectedNbIotSatelliteSubscriptionCallbackWrapperMap.put(callback, internalCallback); + return mSatelliteManager.registerForSelectedNbIotSatelliteSubscriptionChanged(executor, + internalCallback); + } + + /** + * Wrapper API to unregisters for selected satellite subscription changed event from the + * satellite service. If callback was not registered before, the request will be ignored. + * + * @param callback The callback that was passed to {@link + * #registerForSelectedNbIotSatelliteSubscriptionChanged(Executor, + * SelectedNbIotSatelliteSubscriptionCallbackWrapper)}. + */ + public void unregisterForSelectedNbIotSatelliteSubscriptionChanged( + @NonNull SelectedNbIotSatelliteSubscriptionCallbackWrapper callback) { + SelectedNbIotSatelliteSubscriptionCallback internalCallback = + sSelectedNbIotSatelliteSubscriptionCallbackWrapperMap.remove(callback); + if (internalCallback != null) { + mSatelliteManager.unregisterForSelectedNbIotSatelliteSubscriptionChanged( + internalCallback); + } else { + logd("unregisterForSelectedNbIotSatelliteSubscriptionChanged: internalCallback is" + + " null"); + } + } + + /** * Inform whether the device is aligned with the satellite for demo mode. */ public void setDeviceAlignedWithSatellite(boolean isAligned) { + if (mSatelliteManager == null) { + logd("setDeviceAlignedWithSatellite: mSatelliteManager is null"); + return; + } + mSatelliteManager.setDeviceAlignedWithSatellite(isAligned); } @@ -1196,6 +1476,14 @@ public void requestNtnSignalStrength( @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<NtnSignalStrengthWrapper, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("requestNtnSignalStrength: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + OutcomeReceiver internalCallback = new OutcomeReceiver<NtnSignalStrength, SatelliteException>() { @Override @@ -1216,6 +1504,11 @@ public void registerForNtnSignalStrengthChanged( @NonNull @CallbackExecutor Executor executor, @NonNull NtnSignalStrengthCallbackWrapper callback) { + if (mSatelliteManager == null){ + logd("registerForNtnSignalStrengthChanged: mSatelliteManager is null"); + return; + } + NtnSignalStrengthCallback internalCallback = new NtnSignalStrengthCallback() { @Override @@ -1235,6 +1528,11 @@ @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) public void unregisterForNtnSignalStrengthChanged( @NonNull NtnSignalStrengthCallbackWrapper callback) { + if (mSatelliteManager == null){ + logd("unregisterForNtnSignalStrengthChanged: mSatelliteManager is null"); + return; + } + NtnSignalStrengthCallback internalCallback = sNtnSignalStrengthCallbackWrapperMap.remove(callback); if (internalCallback != null) { @@ -1279,6 +1577,11 @@ public int registerForCapabilitiesChanged( @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteCapabilitiesCallbackWrapper callback) { + if (mSatelliteManager == null) { + logd("requestForCapabilitiesChanged: mSatelliteManager is null"); + return SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED; + } + SatelliteCapabilitiesCallback internalCallback = capabilities -> callback.onSatelliteCapabilitiesChanged( new SatelliteCapabilitiesWrapper( @@ -1300,6 +1603,11 @@ @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) public void unregisterForCapabilitiesChanged( @NonNull SatelliteCapabilitiesCallbackWrapper callback) { + if (mSatelliteManager == null) { + logd("unregisterForCapabilitiesChanged: mSatelliteManager is null"); + return; + } + SatelliteCapabilitiesCallback internalCallback = sSatelliteCapabilitiesCallbackWrapperMap.remove(callback); if (internalCallback != null) { @@ -1413,6 +1721,13 @@ public void requestAttachEnabledForCarrier(int subId, boolean enableSatellite, @NonNull @CallbackExecutor Executor executor, @SatelliteResult @NonNull Consumer<Integer> resultListener) { + if (mSatelliteManager == null) { + logd("requestAttachEnabledForCarrier: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))); + return; + } + mSatelliteManager.requestAttachEnabledForCarrier(subId, enableSatellite, executor, resultListener); } @@ -1438,6 +1753,14 @@ public void requestIsAttachEnabledForCarrier(int subId, @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("requestIsAttachEnabledForCarrier: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + OutcomeReceiver internalCallback = new OutcomeReceiver<Boolean, SatelliteException>() { @Override @@ -1470,6 +1793,13 @@ @SatelliteCommunicationRestrictionReason int reason, @NonNull @CallbackExecutor Executor executor, @SatelliteResult @NonNull Consumer<Integer> resultListener) { + if (mSatelliteManager == null) { + logd("addAttachRestrictionForCarrier: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))); + return; + } + mSatelliteManager.addAttachRestrictionForCarrier(subId, reason, executor, resultListener); } @@ -1490,6 +1820,13 @@ @SatelliteCommunicationRestrictionReason int reason, @NonNull @CallbackExecutor Executor executor, @SatelliteResult @NonNull Consumer<Integer> resultListener) { + if (mSatelliteManager == null) { + logd("removeAttachRestrictionForCarrier: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))); + return; + } + mSatelliteManager.removeAttachRestrictionForCarrier(subId, reason, executor, resultListener); } @@ -1506,6 +1843,11 @@ */ @SatelliteCommunicationRestrictionReason @NonNull public Set<Integer> getAttachRestrictionReasonsForCarrier(int subId) { + if (mSatelliteManager == null) { + logd("getAttachRestrictionReasonsForCarrier: mSatelliteManager is null"); + return Collections.emptySet(); + } + return mSatelliteManager.getAttachRestrictionReasonsForCarrier(subId); } @@ -1518,6 +1860,11 @@ * be returned. */ @NonNull public List<String> getSatellitePlmnsForCarrier(int subId) { + if (mSatelliteManager == null) { + logd("getSatellitePlmnsForCarrier: mSatelliteManager is null"); + return new ArrayList<>(); + } + return mSatelliteManager.getSatellitePlmnsForCarrier(subId); } @@ -1526,6 +1873,11 @@ public int registerForSupportedStateChanged( @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteSupportedStateCallbackWrapper callback) { + if (mSatelliteManager == null) { + logd("registerForSupportedStateChanged: mSatelliteManager is null"); + return SatelliteManagerWrapper.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED; + } + SatelliteSupportedStateCallback internalCallback = new SatelliteSupportedStateCallback() { @Override @@ -1544,6 +1896,14 @@ @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<SatelliteSessionStatsWrapper, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("requestSessionStats: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + OutcomeReceiver internalCallback = new OutcomeReceiver<SatelliteSessionStats, SatelliteException>() { @Override @@ -1577,6 +1937,11 @@ */ public void unregisterForSupportedStateChanged( @NonNull SatelliteSupportedStateCallbackWrapper callback) { + if (mSatelliteManager == null) { + logd("unregisterForSupportedStateChanged: mSatelliteManager is null"); + return; + } + SatelliteSupportedStateCallback internalCallback = sSatelliteSupportedStateCallbackWrapperMap.remove(callback); if (internalCallback != null) { @@ -1589,6 +1954,11 @@ public int registerForCommunicationAllowedStateChanged( @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteCommunicationAllowedStateCallbackWrapper callback) { + if (mSatelliteManager == null) { + logd("requestForCommunicationAllowedStateChanged: mSatelliteManager is null"); + return SatelliteManagerWrapper.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED; + } + SatelliteCommunicationAllowedStateCallback internalCallback = new SatelliteCommunicationAllowedStateCallback() { @Override @@ -1602,12 +1972,76 @@ return result; } + @NonNull + private List<SatelliteInfoWrapper> getSatelliteInfoListWrapper(@NonNull + List<SatelliteInfo> satelliteInfoList) { + List<SatelliteInfoWrapper> satelliteInfoWrapperList = new ArrayList<>(); + + for (SatelliteInfo info : satelliteInfoList) { + SatellitePositionWrapper satellitePositionWrapper = new SatellitePositionWrapper( + info.getSatellitePosition().getLongitudeDegrees(), + info.getSatellitePosition().getAltitudeKm()); + + List<EarfcnRangeWrapper> earfcnRangeWrapperList = new ArrayList<>(); + for (EarfcnRange range : info.getEarfcnRanges()) { + earfcnRangeWrapperList.add(new EarfcnRangeWrapper( + range.getStartEarfcn(), range.getEndEarfcn())); + } + + SatelliteInfoWrapper satelliteInfoWrapper = new SatelliteInfoWrapper( + info.getSatelliteId(), satellitePositionWrapper, + info.getBands(), earfcnRangeWrapperList); + + satelliteInfoWrapperList.add(satelliteInfoWrapper); + } + return satelliteInfoWrapperList; + } + + /** Registers for the satellite communication allowed state changed. */ + @SatelliteResult + public int registerForCommunicationAllowedStateChanged2( + @NonNull @CallbackExecutor Executor executor, + @NonNull SatelliteCommunicationAllowedStateCallbackWrapper2 callback) { + if (mSatelliteManager == null) { + logd("registerForCommunicationAllowedStateChanged2: mSatelliteManager is null"); + return SatelliteManagerWrapper.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED; + } + + SatelliteCommunicationAllowedStateCallback internalCallback = + new SatelliteCommunicationAllowedStateCallback() { + @Override + public void onSatelliteCommunicationAllowedStateChanged(boolean supported) { + callback.onSatelliteCommunicationAllowedStateChanged(supported); + } + + @Override + public void onSatelliteAccessConfigurationChanged(SatelliteAccessConfiguration + config) { + if (config != null) { + callback.onSatelliteAccessConfigurationChanged( + new SatelliteAccessConfigurationWrapper( + getSatelliteInfoListWrapper(config.getSatelliteInfos()), + config.getTagIds())); + } + } + }; + sSatelliteCommunicationAllowedStateCallbackWrapperMap2.put(callback, internalCallback); + int result = mSatelliteManager.registerForCommunicationAllowedStateChanged(executor, + internalCallback); + return result; + } + /** * Unregisters for the satellite communication allowed state changed. If callback was not * registered before, the request will be ignored. */ public void unregisterForCommunicationAllowedStateChanged( @NonNull SatelliteCommunicationAllowedStateCallbackWrapper callback) { + if (mSatelliteManager == null) { + logd("unregisterForCommunicationAllowedStateChanged: mSatelliteManager is null"); + return; + } + SatelliteCommunicationAllowedStateCallback internalCallback = sSatelliteCommunicationAllowedStateCallbackWrapperMap.remove(callback); if (internalCallback != null) { @@ -1616,6 +2050,19 @@ } /** + * Unregisters for the satellite communication allowed state changed. If callback was not + * registered before, the request will be ignored. + */ + public void unregisterForCommunicationAllowedStateChanged2( + @NonNull SatelliteCommunicationAllowedStateCallbackWrapper2 callback) { + SatelliteCommunicationAllowedStateCallback internalCallback = + sSatelliteCommunicationAllowedStateCallbackWrapperMap2.remove(callback); + if (internalCallback != null) { + mSatelliteManager.unregisterForCommunicationAllowedStateChanged(internalCallback); + } + } + + /** * Wrapper API to provide a way to check if the subscription is capable for non-terrestrial * networks for the carrier. * @@ -1655,6 +2102,14 @@ @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<List<SatelliteSubscriberProvisionStatusWrapper>, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("requestSatelliteSubscriberProvisionStatus: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + Objects.requireNonNull(executor); Objects.requireNonNull(callback); @@ -1684,6 +2139,14 @@ public void provisionSatellite(@NonNull List<SatelliteSubscriberInfoWrapper> list, @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("provisionSatellite: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + OutcomeReceiver internalCallback = new OutcomeReceiver<Boolean, SatelliteException>() { @Override @@ -1726,6 +2189,11 @@ } public boolean isSatelliteSubscriberIdSupported() { + if (mSatelliteManager == null) { + logd("isSatelliteSubscriberIdSupported: mSatelliteManager is null"); + return false; + } + try { final String methodName = "requestSatelliteSubscriberProvisionStatus"; Method method = mSatelliteManager.getClass().getMethod(methodName, Executor.class, @@ -1747,6 +2215,14 @@ public void deprovisionSatellite(@NonNull List<SatelliteSubscriberInfoWrapper> list, @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) { + if (mSatelliteManager == null) { + logd("deprovisionSatellite: mSatelliteManager is null"); + executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError( + new SatelliteExceptionWrapper( + SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)))); + return; + } + OutcomeReceiver internalCallback = new OutcomeReceiver<Boolean, SatelliteException>() { @Override @@ -1768,6 +2244,23 @@ .collect(Collectors.toList()), executor, internalCallback); } + /** + * Inform whether application supports NTN SMS in satellite mode. + * + * This method is used by default messaging application to inform framework whether it supports + * NTN SMS or not. + * + * @param ntnSmsSupported {@code true} If application supports NTN SMS, else {@code false}. + */ + public void setNtnSmsSupported(boolean ntnSmsSupported) { + if (mSatelliteManager == null) { + logd("setNtnSmsSupported: mSatelliteManager is null"); + return; + } + + mSatelliteManager.setNtnSmsSupported(ntnSmsSupported); + } + @Nullable private ServiceState getServiceStateForSubscriptionId(int subId) { if (!mSubscriptionManager.isValidSubscriptionId(subId)) {
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatellitePositionWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatellitePositionWrapper.java new file mode 100644 index 0000000..60b197e --- /dev/null +++ b/satellite_client/src/android/telephony/satellite/wrapper/SatellitePositionWrapper.java
@@ -0,0 +1,138 @@ +/* + * 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 android.telephony.satellite.wrapper; + +import android.annotation.FlaggedApi; +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.NonNull; + +import com.android.internal.telephony.flags.Flags; + +import java.util.Objects; + +/** + * The position of a satellite in Earth orbit. + * + * Longitude is the angular distance, measured in degrees, east or west of the prime longitude line + * ranging from -180 to 180 degrees + * Altitude is the distance from the center of the Earth to the satellite, measured in kilometers + * + * @hide + */ +public class SatellitePositionWrapper implements Parcelable { + + /** + * The longitude of the satellite in degrees, ranging from -180 to 180 degrees + */ + private double mLongitudeDegree; + + /** + * The distance from the center of the earth to the satellite, measured in kilometers + */ + private double mAltitudeKm; + + /** + * Constructor for {@link SatellitePositionWrapper} used to create an instance from a + * {@link Parcel}. + * + * @param in The {@link Parcel} to read the satellite position data from. + */ + public SatellitePositionWrapper(Parcel in) { + mLongitudeDegree = in.readDouble(); + mAltitudeKm = in.readDouble(); + } + + /** + * Constructor for {@link SatellitePositionWrapper}. + * + * @param longitudeDegree The longitude of the satellite in degrees. + * @param altitudeKm The altitude of the satellite in kilometers. + */ + public SatellitePositionWrapper(double longitudeDegree, double altitudeKm) { + mLongitudeDegree = longitudeDegree; + mAltitudeKm = altitudeKm; + } + + public static final Creator<SatellitePositionWrapper> CREATOR = + new Creator<SatellitePositionWrapper>() { + @Override + public SatellitePositionWrapper createFromParcel(Parcel in) { + return new SatellitePositionWrapper(in); + } + + @Override + public SatellitePositionWrapper[] newArray(int size) { + return new SatellitePositionWrapper[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + /** + * @param dest The Parcel in which the object should be written. + * @param flags Additional flags about how the object should be written. + * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}. + */ + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeDouble(mLongitudeDegree); + dest.writeDouble(mAltitudeKm); + } + + /** + * Returns the longitude of the satellite in degrees, ranging from -180 to 180 degrees. + * + * @return The longitude of the satellite. + */ + public double getLongitudeDegrees() { + return mLongitudeDegree; + } + + /** + * Returns the altitude of the satellite in kilometers + * + * @return The altitude of the satellite. + */ + public double getAltitudeKm() { + return mAltitudeKm; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SatellitePositionWrapper that)) return false; + + return Double.compare(that.mLongitudeDegree, mLongitudeDegree) == 0 + && Double.compare(that.mAltitudeKm, mAltitudeKm) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(mLongitudeDegree, mAltitudeKm); + } + + @Override + @NonNull + public String toString() { + return "mLongitudeDegree: " + mLongitudeDegree + ", " + "mAltitudeKm: " + mAltitudeKm; + } +}
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SelectedNbIotSatelliteSubscriptionCallbackWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SelectedNbIotSatelliteSubscriptionCallbackWrapper.java new file mode 100644 index 0000000..b716de5 --- /dev/null +++ b/satellite_client/src/android/telephony/satellite/wrapper/SelectedNbIotSatelliteSubscriptionCallbackWrapper.java
@@ -0,0 +1,29 @@ +/* + * 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 android.telephony.satellite.wrapper; + +/** + * A callback class for selected satellite subscription changed events. + */ +public interface SelectedNbIotSatelliteSubscriptionCallbackWrapper { + /** + * Called when selected satellite subscription has changed. + * + * @param selectedSubId The new satellite subscription id. + */ + void onSelectedNbIotSatelliteSubscriptionChanged(int selectedSubId); +} \ No newline at end of file