Add satellite provision APIs

Bug: 266013384
Test: atest android.telephony.cts.SatelliteManagerTest

Change-Id: I36d000adab8d9b96672be4ff1ab90f046a83c423
This commit is contained in:
Thomas Nguyen
2023-02-01 11:21:00 -08:00
committed by Aishwarya Mallampati
parent 42d58582d0
commit 4fcec83066
6 changed files with 582 additions and 127 deletions

View File

@@ -19,10 +19,11 @@ package android.telephony.satellite;
import android.telephony.satellite.PointingInfo;
/**
* Callback for position updates from the satellite service.
* Interface for satellite state listener.
* @hide
*/
oneway interface ISatellitePositionUpdateCallback {
oneway interface ISatelliteStateListener {
void onSatelliteProvisionStateChanged(in int[] features, in boolean provisioned);
void onSatellitePositionUpdate(in PointingInfo pointingInfo);
void onMessageTransferStateUpdate(in int state);
}

View File

@@ -0,0 +1,132 @@
/*
* 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.os.Binder;
import android.telephony.satellite.stub.SatelliteImplBase;
import java.lang.ref.WeakReference;
import java.util.concurrent.Executor;
/**
* A callback class for monitoring changes in specific satellite service states on the device,
* including provision state, position update, message transfer state and others.
* <p>
* To register a callback, use a {@link SatelliteCallback} which implements the interested
* interfaces. For example,
* FakeSatelliteProvisionStateCallback extends {@link SatelliteCallback} implements
* {@link SatelliteCallback.SatelliteProvisionStateListener}.
* <p>
* Then override the methods for the state that you wish to receive updates for, and
* pass your SatelliteCallback object to the corresponding register function like
* {@link SatelliteManager#registerForSatelliteProvisionStateChanged}.
* <p>
*
* @hide
*/
public class SatelliteCallback {
private ISatelliteStateListener mCallbackStub;
/**
* The SatelliteCallback needs an executor to execute the callback interfaces.
*/
public void init(@NonNull Executor executor) {
if (executor == null) {
throw new IllegalArgumentException("SatelliteCallback executor must be non-null");
}
mCallbackStub = new ISatelliteStateListenerStub(this, executor);
}
public ISatelliteStateListener getCallbackStub() {
return mCallbackStub;
}
/**
* Interface for satellite provision state change listener.
*/
public interface SatelliteProvisionStateListener {
/**
* Called when satellite provision state changes.
*
* @param features The list of provisioned features.
* @param provisioned The new provision state. {@code true} means satellite is provisioned
* {@code false} means satellite is not provisioned.
*/
void onSatelliteProvisionStateChanged(
@SatelliteImplBase.Feature int[] features, boolean provisioned);
}
/**
* Interface for position update change listener.
*/
public interface SatellitePositionUpdateListener {
/**
* Called when the satellite position changes.
*
* @param pointingInfo The pointing info containing the satellite location.
*/
void onSatellitePositionUpdate(@NonNull PointingInfo pointingInfo);
/**
* Called when satellite message transfer state changes.
*
* @param state The new message transfer state.
*/
void onMessageTransferStateUpdate(
@SatelliteManager.SatelliteMessageTransferState int state);
}
private static class ISatelliteStateListenerStub extends ISatelliteStateListener.Stub {
private WeakReference<SatelliteCallback> mSatelliteCallbackWeakRef;
private Executor mExecutor;
ISatelliteStateListenerStub(SatelliteCallback satelliteCallback, Executor executor) {
mSatelliteCallbackWeakRef = new WeakReference<>(satelliteCallback);
mExecutor = executor;
}
public void onSatelliteProvisionStateChanged(
@SatelliteImplBase.Feature int[] features, boolean provisioned) {
SatelliteProvisionStateListener listener =
(SatelliteProvisionStateListener) mSatelliteCallbackWeakRef.get();
if (listener == null) return;
Binder.withCleanCallingIdentity(() -> mExecutor.execute(
() -> listener.onSatelliteProvisionStateChanged(features, provisioned)));
}
public void onSatellitePositionUpdate(@NonNull PointingInfo pointingInfo) {
SatellitePositionUpdateListener listener =
(SatellitePositionUpdateListener) mSatelliteCallbackWeakRef.get();
if (listener == null) return;
Binder.withCleanCallingIdentity(() -> mExecutor.execute(
() -> listener.onSatellitePositionUpdate(pointingInfo)));
}
public void onMessageTransferStateUpdate(
@SatelliteManager.SatelliteMessageTransferState int state) {
SatellitePositionUpdateListener listener =
(SatellitePositionUpdateListener) mSatelliteCallbackWeakRef.get();
if (listener == null) return;
Binder.withCleanCallingIdentity(() -> mExecutor.execute(
() -> listener.onMessageTransferStateUpdate(state)));
}
}
}

View File

@@ -26,26 +26,29 @@ import android.annotation.RequiresPermission;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.CancellationSignal;
import android.os.ICancellationSignal;
import android.os.RemoteException;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyFrameworkInitializer;
import android.util.ArrayMap;
import android.telephony.satellite.stub.SatelliteImplBase;
import com.android.internal.telephony.IIntArrayConsumer;
import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.ITelephony;
import com.android.telephony.Rlog;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
/**
* Manages satellite operations such as provisioning, pointing, messaging, location sharing, etc.
* To get the object, call {@link Context#getSystemService(Context.SATELLITE_SERVICE)}.
* To get the object, call {@link Context#getSystemService(String)}. This object is associated
* with the {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} and the satellite service is
* associated with the device rather than a subscription.
* To create an instance of {@link SatelliteManager} associated with a specific subscription ID,
* call {@link #createForSubscriptionId(int)}.
*
@@ -56,18 +59,11 @@ public class SatelliteManager {
private static final String TAG = "SatelliteManager";
/**
* Map of all SatellitePositionUpdateCallback and their associated callback ids.
*/
private final Map<SatellitePositionUpdateCallback, Integer> mSatellitePositionUpdateCallbacks =
new ArrayMap<>();
/**
* AtomicInteger for the id of the next SatellitePositionUpdateCallback.
*/
private final AtomicInteger mSatellitePositionUpdateCallbackId = new AtomicInteger(0);
/**
* The subscription ID for this SatelliteManager.
* The subscription ID for this SatelliteManager. If the
* {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} is used, the satellite service will be
* associated with the device rather than a subscription. If an active subscription ID
* {@link SubscriptionManager#isActiveSubId(int)} is provided, the satellite service will be
* associated with that active subscription.
*/
private final int mSubId;
@@ -82,7 +78,6 @@ public class SatelliteManager {
* @param context The context the SatelliteManager belongs to.
*/
public SatelliteManager(@Nullable Context context) {
// TODO: replace DEFAULT_SUBSCRIPTION_ID with DEFAULT_SATELLITE_SUBSCRIPTION_ID
this(context, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
}
@@ -120,23 +115,24 @@ public class SatelliteManager {
*/
public static final int SATELLITE_SERVICE_SERVER_ERROR = 2;
/**
* Unexpected telephony internal error.
* Telephony is not in a valid state to serve requests from clients.
*/
public static final int SATELLITE_SERVICE_TELEPHONY_INTERNAL_ERROR = 3;
public static final int SATELLITE_SERVICE_INVALID_TELEPHONY_STATE = 3;
/**
* Modem error received from the satellite service.
* RIL layer got an unexpected or incorrect response from modem for a request.
*/
public static final int SATELLITE_SERVICE_MODEM_ERROR = 4;
public static final int SATELLITE_SERVICE_UNEXPECTED_MODEM_RESPONSE = 4;
/**
* System error received from the satellite service.
* An error in the RIL layer occurs when processing a request. This generic RIL error should be
* used only when other RIL specific errors cannot be used.
*/
public static final int SATELLITE_SERVICE_SYSTEM_ERROR = 5;
public static final int SATELLITE_SERVICE_RIL_ERROR = 5;
/**
* Invalid arguments passed.
* RIL layer has received a request with invalid arguments from the Telephony framework.
*/
public static final int SATELLITE_SERVICE_INVALID_ARGUMENTS = 6;
/**
* Invalid modem state.
* Satellite modem is not in a valid state to serve requests from clients.
*/
public static final int SATELLITE_SERVICE_INVALID_MODEM_STATE = 7;
/**
@@ -144,67 +140,203 @@ public class SatelliteManager {
*/
public static final int SATELLITE_SERVICE_INVALID_SIM_STATE = 8;
/**
* Invalid state.
* RIL layer is not in a valid state to serve requests from clients.
*/
public static final int SATELLITE_SERVICE_INVALID_STATE = 9;
public static final int SATELLITE_SERVICE_INVALID_RIL_STATE = 9;
/**
* Satellite service is unavailable.
* Radio did not start or is resetting.
*/
public static final int SATELLITE_SERVICE_NOT_AVAILABLE = 10;
public static final int SATELLITE_SERVICE_RADIO_NOT_AVAILABLE = 10;
/**
* Satellite service is not supported by the device or OS.
* The request is not supported by either the satellite modem or the network.
*/
public static final int SATELLITE_SERVICE_NOT_SUPPORTED = 11;
public static final int SATELLITE_SERVICE_REQUEST_NOT_SUPPORTED = 11;
/**
* Satellite service is rate limited.
* Requests denied by the satellite modem or the network due to overly-frequent requests.
*/
public static final int SATELLITE_SERVICE_RATE_LIMITED = 12;
public static final int SATELLITE_SERVICE_REQUEST_RATE_LIMITED = 12;
/**
* Satellite service has no memory available.
* Satellite modem or network has no resources available to handle requests from clients.
*/
public static final int SATELLITE_SERVICE_NO_MEMORY = 13;
public static final int SATELLITE_SERVICE_NO_RESOURCES = 13;
/**
* Satellite service has no resources available.
* Telephony framework failed to send a request to the satellite service on the device or the
* satellite modem.
*/
public static final int SATELLITE_SERVICE_NO_RESOURCES = 14;
public static final int SATELLITE_SERVICE_REQUEST_FAILED = 14;
/**
* Failed to send a request to the satellite service.
* A generic error which should be used only when other specific errors cannot be used.
*/
public static final int SATELLITE_SERVICE_REQUEST_FAILED = 15;
public static final int SATELLITE_SERVICE_ERROR = 15;
/**
* Failed to send a request to the satellite service for the given subscription ID.
* Satellite service is disabled on the requested subscription or the device.
*/
public static final int SATELLITE_SERVICE_INVALID_SUBSCRIPTION_ID = 16;
public static final int SATELLITE_SERVICE_DISABLED = 16;
/**
* Error received from satellite service.
* Satellite is already provisioned for the subscription or the device.
*/
public static final int SATELLITE_SERVICE_ERROR = 17;
public static final int SATELLITE_SERVICE_ALREADY_PROVISIONED = 17;
/**
* Satellite service is disabled on the requested subscription.
* Provisioning is already in progress.
*/
public static final int SATELLITE_SERVICE_DISABLED = 18;
public static final int SATELLITE_SERVICE_PROVISION_IN_PROGRESS = 18;
/**
* The ongoing request was aborted by either the satellite modem or the network.
*/
public static final int SATELLITE_SERVICE_REQUEST_ABORTED = 19;
/**
* The device/subscription is barred to access the satellite service.
*/
public static final int SATELLITE_SERVICE_ACCESS_BARRED = 20;
/**
* The requesting feature is not supported by the satellite service provider.
*/
public static final int SATELLITE_SERVICE_FEATURE_NOT_SUPPORTED = 21;
/**
* The modem of the device is not compatible with the satellite service provider.
*/
public static final int SATELLITE_SERVICE_MODEM_INCOMPATIBLE = 22;
/**
* The satellite network is not ready to serve requests from clients.
*/
public static final int SATELLITE_SERVICE_NETWORK_NOT_READY = 23;
/**
* The satellite server is not ready to serve requests from clients.
*/
public static final int SATELLITE_SERVICE_SERVER_NOT_READY = 24;
/**
* The request was rejected by the satellite server.
*/
public static final int SATELLITE_SERVICE_SERVER_REJECT = 25;
/**
* Satellite modem timeout to receive ACK or response from the satellite network after
* sending a request to the network.
*/
public static final int SATELLITE_SERVICE_NETWORK_TIMEOUT = 26;
/**
* Satellite modem cannot detect any satellite signal.
*/
public static final int SATELLITE_SERVICE_NO_SATELLITE_SIGNAL = 27;
/**
* Device does not have a subscription.
*/
public static final int SATELLITE_SERVICE_NO_SUBSCRIPTION = 28;
/**
* Operation is not allowed by either the satellite modem, or satellite network, or satellite
* server.
*/
public static final int SATELLITE_SERVICE_OPERATION_NOT_ALLOWED = 29;
/**
* The radio technology is not supported by the satellite service provider.
*/
public static final int SATELLITE_SERVICE_RADIO_TECHNOLOGY_NOT_SUPPORTED = 30;
/**
* SIM is absent.
*/
public static final int SATELLITE_SERVICE_SIM_ABSENT = 31;
/**
* SIM is busy.
*/
public static final int SATELLITE_SERVICE_SIM_BUSY = 32;
/**
* Received error from SIM card.
*/
public static final int SATELLITE_SERVICE_SIM_ERR = 33;
/**
* The target EF is full.
*/
public static final int SATELLITE_SERVICE_SIM_FULL = 34;
/**
* The subscription/user is not authorized to register with the satellite service provider.
*/
public static final int SATELLITE_SERVICE_SUBSCRIBER_NOT_AUTHORIZED = 35;
/**
* The callback was already registered with Telephony framework.
*/
public static final int SATELLITE_SERVICE_CALLBACK_ALREADY_REGISTERED = 36;
/**
* The callback was not registered with Telephony framework.
*/
public static final int SATELLITE_SERVICE_CALLBACK_NOT_REGISTERED = 37;
/**
* The request cannot be performed since the subscriber/user's account balance is not
* sufficient.
*/
public static final int SATELLITE_SERVICE_NOT_SUFFICIENT_ACCOUNT_BALANCE = 38;
/**
* While processing a request from the Telephony framework, the satellite modem detects
* terrestrial signal, aborts the request, and switches to the terrestrial network.
*/
public static final int SATELLITE_SERVICE_SWITCHED_FROM_SATELLITE_TO_TERRESTRIAL = 39;
/**
* The subscriber/user is not registered with the service provider.
*/
public static final int SATELLITE_SERVICE_UNIDENTIFIED_SUBSCRIBER = 40;
/**
* The contact to be added/removed is either not existing or not valid.
*/
public static final int SATELLITE_SERVICE_INVALID_CONTACT = 41;
/**
* The encoding scheme is not supported by either the satellite provider or the device.
*/
public static final int SATELLITE_SERVICE_ENCODING_NOT_SUPPORTED = 42;
/**
* Received error from the satellite network. This generic error code should be used only when
* the error cannot be mapped to other specific network error codes.
*/
public static final int SATELLITE_SERVICE_NETWORK_ERROR = 43;
/**
* Modem hit unexpected error scenario while handling this request.
*/
public static final int SATELLITE_SERVICE_MODEM_ERROR = 44;
/** @hide */
@IntDef(prefix = {"SATELLITE_SERVICE_"}, value = {
SATELLITE_SERVICE_SUCCESS,
SATELLITE_SERVICE_SERVER_NOT_REACHABLE,
SATELLITE_SERVICE_SERVER_ERROR,
SATELLITE_SERVICE_TELEPHONY_INTERNAL_ERROR,
SATELLITE_SERVICE_MODEM_ERROR,
SATELLITE_SERVICE_SYSTEM_ERROR,
SATELLITE_SERVICE_INVALID_TELEPHONY_STATE,
SATELLITE_SERVICE_UNEXPECTED_MODEM_RESPONSE,
SATELLITE_SERVICE_RIL_ERROR,
SATELLITE_SERVICE_INVALID_ARGUMENTS,
SATELLITE_SERVICE_INVALID_MODEM_STATE,
SATELLITE_SERVICE_INVALID_SIM_STATE,
SATELLITE_SERVICE_INVALID_STATE,
SATELLITE_SERVICE_NOT_AVAILABLE,
SATELLITE_SERVICE_NOT_SUPPORTED,
SATELLITE_SERVICE_RATE_LIMITED,
SATELLITE_SERVICE_NO_MEMORY,
SATELLITE_SERVICE_INVALID_RIL_STATE,
SATELLITE_SERVICE_RADIO_NOT_AVAILABLE,
SATELLITE_SERVICE_REQUEST_NOT_SUPPORTED,
SATELLITE_SERVICE_REQUEST_RATE_LIMITED,
SATELLITE_SERVICE_NO_RESOURCES,
SATELLITE_SERVICE_REQUEST_FAILED,
SATELLITE_SERVICE_INVALID_SUBSCRIPTION_ID,
SATELLITE_SERVICE_ERROR,
SATELLITE_SERVICE_DISABLED
SATELLITE_SERVICE_DISABLED,
SATELLITE_SERVICE_ALREADY_PROVISIONED,
SATELLITE_SERVICE_PROVISION_IN_PROGRESS,
SATELLITE_SERVICE_REQUEST_ABORTED,
SATELLITE_SERVICE_ACCESS_BARRED,
SATELLITE_SERVICE_FEATURE_NOT_SUPPORTED,
SATELLITE_SERVICE_MODEM_INCOMPATIBLE,
SATELLITE_SERVICE_NETWORK_NOT_READY,
SATELLITE_SERVICE_SERVER_NOT_READY,
SATELLITE_SERVICE_SERVER_REJECT,
SATELLITE_SERVICE_NETWORK_TIMEOUT,
SATELLITE_SERVICE_NO_SATELLITE_SIGNAL,
SATELLITE_SERVICE_NO_SUBSCRIPTION,
SATELLITE_SERVICE_OPERATION_NOT_ALLOWED,
SATELLITE_SERVICE_RADIO_TECHNOLOGY_NOT_SUPPORTED,
SATELLITE_SERVICE_SIM_ABSENT,
SATELLITE_SERVICE_SIM_BUSY,
SATELLITE_SERVICE_SIM_ERR,
SATELLITE_SERVICE_SIM_FULL,
SATELLITE_SERVICE_SUBSCRIBER_NOT_AUTHORIZED,
SATELLITE_SERVICE_CALLBACK_ALREADY_REGISTERED,
SATELLITE_SERVICE_CALLBACK_NOT_REGISTERED,
SATELLITE_SERVICE_NOT_SUFFICIENT_ACCOUNT_BALANCE,
SATELLITE_SERVICE_SWITCHED_FROM_SATELLITE_TO_TERRESTRIAL,
SATELLITE_SERVICE_UNIDENTIFIED_SUBSCRIBER,
SATELLITE_SERVICE_INVALID_CONTACT,
SATELLITE_SERVICE_ENCODING_NOT_SUPPORTED,
SATELLITE_SERVICE_NETWORK_ERROR,
SATELLITE_SERVICE_MODEM_ERROR
})
@Retention(RetentionPolicy.SOURCE)
public @interface SatelliteServiceResult {}
@@ -240,25 +372,6 @@ public class SatelliteManager {
})
public @interface SatelliteMessageTransferState {}
/**
* Callback for position updates from the satellite service.
*/
public interface SatellitePositionUpdateCallback {
/**
* Called when the satellite position changes.
*
* @param pointingInfo The pointing info containing the satellite location.
*/
void onSatellitePositionUpdate(@NonNull PointingInfo pointingInfo);
/**
* Called when satellite message transfer state changes.
*
* @param state The new message transfer state.
*/
void onMessageTransferStateUpdate(@SatelliteMessageTransferState int state);
}
/**
* Start receiving satellite position updates.
* This can be called by the pointing UI when the user starts pointing to the satellite.
@@ -266,48 +379,23 @@ public class SatelliteManager {
* Satellite position updates are started only on {@link #SATELLITE_SERVICE_SUCCESS}.
* All other results indicate that this operation failed.
*
* @param executor The executor to run callbacks on.
* @param callback The callback to notify of changes in satellite position.
* @param executor - The executor on which the callback will be called.
* @param callback The callback to notify of changes in satellite position. This
* SatelliteCallback should implement the interface
* {@link SatelliteCallback.SatellitePositionUpdateListener}.
* @return The result of the operation.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
@SatelliteServiceResult public int startSatellitePositionUpdates(
@NonNull @CallbackExecutor Executor executor,
@NonNull SatellitePositionUpdateCallback callback) {
@NonNull Executor executor, @NonNull SatelliteCallback callback) {
Objects.requireNonNull(executor);
Objects.requireNonNull(callback);
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
int id;
if (mSatellitePositionUpdateCallbacks.containsKey(callback)) {
id = mSatellitePositionUpdateCallbacks.get(callback);
} else {
id = mSatellitePositionUpdateCallbackId.getAndIncrement();
}
int result = telephony.startSatellitePositionUpdates(mSubId, id,
new ISatellitePositionUpdateCallback.Stub() {
@Override
public void onSatellitePositionUpdate(
@NonNull PointingInfo pointingInfo) {
logd("onSatellitePositionUpdate: pointingInfo=" + pointingInfo);
executor.execute(() -> Binder.withCleanCallingIdentity(
() -> callback.onSatellitePositionUpdate(pointingInfo)));
}
@Override
public void onMessageTransferStateUpdate(
@SatelliteMessageTransferState int state) {
logd("onMessageTransferStateUpdate: state=" + state);
executor.execute(() -> Binder.withCleanCallingIdentity(
() -> callback.onMessageTransferStateUpdate(state)));
}
});
if (result == SATELLITE_SERVICE_SUCCESS) {
mSatellitePositionUpdateCallbacks.put(callback, id);
}
return result;
callback.init(executor);
return telephony.startSatellitePositionUpdates(mSubId, callback.getCallbackStub());
} else {
throw new IllegalStateException("telephony service is null.");
}
@@ -325,30 +413,20 @@ public class SatelliteManager {
* All other results indicate that this operation failed.
*
* @param callback The callback that was passed in {@link
* #startSatellitePositionUpdates(Executor, SatellitePositionUpdateCallback)}.
* #startSatellitePositionUpdates(Executor, SatelliteCallback)}.
* @return The result of the operation.
* @throws IllegalArgumentException if the callback is invalid.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
@SatelliteServiceResult public int stopSatellitePositionUpdates(
@NonNull SatellitePositionUpdateCallback callback) {
@NonNull SatelliteCallback callback) {
Objects.requireNonNull(callback);
if (!mSatellitePositionUpdateCallbacks.containsKey(callback)) {
throw new IllegalArgumentException(
"startSatellitePositionUpdates was never called with the callback provided.");
}
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
int result = telephony.stopSatellitePositionUpdates(mSubId,
mSatellitePositionUpdateCallbacks.get(callback));
if (result == SATELLITE_SERVICE_SUCCESS) {
mSatellitePositionUpdateCallbacks.remove(callback);
// TODO: Notify SmsHandler that pointing UI stopped
}
return result;
return telephony.stopSatellitePositionUpdates(mSubId, callback.getCallbackStub());
// TODO: Notify SmsHandler that pointing UI stopped
} else {
throw new IllegalStateException("telephony service is null.");
}
@@ -399,6 +477,164 @@ public class SatelliteManager {
return SATELLITE_SERVICE_REQUEST_FAILED;
}
/**
* Register the subscription with a satellite provider. This is needed if the provider allows
* dynamic registration.
*
* @param features List of features to be provisioned.
* @param executor The optional executor to run callbacks on.
* @param callback The optional callback to get the error code of the request.
* @param cancellationSignal The optional signal used by the caller to cancel the provision
* request. Even when the cancellation is signaled, Telephony will
* still trigger the callback to return the result of this 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)
public void provisionSatelliteService(
@NonNull @SatelliteImplBase.Feature int[] features,
@Nullable @CallbackExecutor Executor executor,
@SatelliteServiceResult @Nullable Consumer<Integer> callback,
@Nullable CancellationSignal cancellationSignal) {
Objects.requireNonNull(features);
ICancellationSignal cancelRemote = null;
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
IIntegerConsumer callbackStub = new IIntegerConsumer.Stub() {
@Override
public void accept(int result) {
if (executor == null || callback == null) {
logd("provisionSatelliteService: executor and/or callback is null");
return;
}
Binder.withCleanCallingIdentity(() -> {
executor.execute(() -> callback.accept(result));
});
}
};
cancelRemote = telephony.provisionSatelliteService(mSubId, features, callbackStub);
} else {
throw new IllegalStateException("telephony service is null.");
}
} catch (RemoteException ex) {
loge("provisionSatelliteService RemoteException=" + ex);
ex.rethrowFromSystemServer();
}
if (cancellationSignal != null) {
cancellationSignal.setRemote(cancelRemote);
}
}
/**
* Register for the satellite provision state change.
*
* @param executor - The executor on which the callback will be called.
* @param callback The callback to handle the satellite provision state changed event. This
* SatelliteCallback should implement the interface
* {@link SatelliteCallback.SatelliteProvisionStateListener}.
* @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)
@SatelliteServiceResult
public int registerForSatelliteProvisionStateChanged(
@NonNull Executor executor, @NonNull SatelliteCallback callback) {
Objects.requireNonNull(executor);
Objects.requireNonNull(callback);
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
callback.init(executor);
return telephony.registerForSatelliteProvisionStateChanged(
mSubId, callback.getCallbackStub());
} else {
throw new IllegalStateException("telephony service is null.");
}
} catch (RemoteException ex) {
loge("registerForSatelliteProvisionStateChanged RemoteException: " + ex);
ex.rethrowFromSystemServer();
}
return SATELLITE_SERVICE_REQUEST_FAILED;
}
/**
* Unregister for the satellite provision state change.
*
* @param callback The callback that was passed to
* {@link #registerForSatelliteProvisionStateChanged(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)
@SatelliteServiceResult
public int unregisterForSatelliteProvisionStateChanged(@NonNull SatelliteCallback callback) {
Objects.requireNonNull(callback);
if (callback.getCallbackStub() == null) {
loge("unregisterForSatelliteProvisionStateChanged: callbackStub is null");
return SATELLITE_SERVICE_CALLBACK_NOT_REGISTERED;
}
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
return telephony.unregisterForSatelliteProvisionStateChanged(
mSubId, callback.getCallbackStub());
} else {
throw new IllegalStateException("telephony service is null.");
}
} catch (RemoteException ex) {
loge("unregisterForSatelliteProvisionStateChanged RemoteException: " + ex);
ex.rethrowFromSystemServer();
}
return SATELLITE_SERVICE_REQUEST_FAILED;
}
/**
* Get the list of provisioned satellite features.
*
* @param executor The executor to run callbacks on.
* @param resultListener The callback to get the list of provisioned features when the request
* returns success result.
* @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)
@SatelliteServiceResult
public int getProvisionedSatelliteFeatures(
@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<int[]> resultListener) {
Objects.requireNonNull(resultListener);
Objects.requireNonNull(executor);
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
IIntArrayConsumer callbackStub = new IIntArrayConsumer.Stub() {
@Override
public void accept(int[] result) {
Binder.withCleanCallingIdentity(() -> {
executor.execute(() -> resultListener.accept(result));
});
}
};
return telephony.getProvisionedSatelliteFeatures(mSubId, callbackStub);
} else {
throw new IllegalStateException("telephony service is null.");
}
} catch (RemoteException ex) {
loge("getProvisionedSatelliteFeatures() RemoteException:" + ex);
ex.rethrowFromSystemServer();
}
return SATELLITE_SERVICE_REQUEST_FAILED;
}
private static ITelephony getITelephony() {
ITelephony binder = ITelephony.Stub.asInterface(TelephonyFrameworkInitializer
.getTelephonyServiceManager()

View File

@@ -0,0 +1,23 @@
/*
* 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 com.android.internal.telephony;
// Copies consumer pattern for an operation that requires an int array result from another
// process to finish.
oneway interface IIntArrayConsumer {
void accept(in int[] result);
}

View File

@@ -21,6 +21,7 @@ import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.os.ICancellationSignal;
import android.os.IBinder;
import android.os.Messenger;
import android.os.ParcelFileDescriptor;
@@ -66,13 +67,14 @@ import android.telephony.ims.aidl.IImsRcsFeature;
import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.telephony.ims.aidl.IRcsConfigCallback;
import android.telephony.satellite.ISatellitePositionUpdateCallback;
import android.telephony.satellite.ISatelliteStateListener;
import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.internal.telephony.CellNetworkScanResult;
import com.android.internal.telephony.IBooleanConsumer;
import com.android.internal.telephony.ICallForwardingInfoCallback;
import com.android.internal.telephony.IccLogicalChannelRequest;
import com.android.internal.telephony.IImsStateCallback;
import com.android.internal.telephony.IIntArrayConsumer;
import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.INumberVerificationCallback;
import com.android.internal.telephony.OperatorInfo;
@@ -2702,16 +2704,52 @@ interface ITelephony {
/**
* Start receiving satellite pointing updates.
*/
int startSatellitePositionUpdates(int subId, int callbackId,
in ISatellitePositionUpdateCallback callback);
int startSatellitePositionUpdates(int subId, in ISatelliteStateListener callback);
/**
* Stop receiving satellite pointing updates.
*/
int stopSatellitePositionUpdates(int subId, int callbackId);
int stopSatellitePositionUpdates(int subId, ISatelliteStateListener callback);
/**
* Get maximum number of characters per text message on satellite.
*/
int getMaxCharactersPerSatelliteTextMessage(int subId, IIntegerConsumer internalCallback);
}
/**
* Register the subscription with a satellite provider.
* This is needed to register the subscription if the provider allows dynamic registration.
*
* @param subId The subId of the subscription to be provisioned.
* @param features List of features to be provisioned.
* @param callback The callback to get the error code of the request.
* @return The signal transport used by callers to cancel the provision request.
*/
ICancellationSignal provisionSatelliteService(int subId, in int[] features,
in IIntegerConsumer callback);
/**
* Register for the satellite provision state change.
*
* @param subId The subId of the subscription to be provisioned.
* @param callback The callback to handle the satellite provision state changed event.
*/
int registerForSatelliteProvisionStateChanged(int subId, ISatelliteStateListener callback);
/**
* Unregister for the satellite provision state change.
*
* @param subId The subId of the subscription associated with the satellite service.
* @param callback The callback that was passed to
* registerForSatelliteProvisionStateChanged.
*/
int unregisterForSatelliteProvisionStateChanged(int subId, ISatelliteStateListener callback);
/**
* Get the list of provisioned satellite features.
*
* @param subId The subId of the subscription to be provisioned.
* @param callback The callback to get the list of provisioned satellite features.
*/
int getProvisionedSatelliteFeatures(int subId, IIntArrayConsumer callback);
}

View File

@@ -120,6 +120,31 @@ public interface RILConstants {
int BLOCKED_DUE_TO_CALL = 69; /* SMS is blocked due to call control */
int RF_HARDWARE_ISSUE = 70; /* RF HW issue is detected */
int NO_RF_CALIBRATION_INFO = 71; /* No RF calibration in device */
int ENCODING_NOT_SUPPORTED = 72; /* The encoding scheme is not supported by
either the network or the MS. */
int FEATURE_NOT_SUPPORTED = 73; /* The requesting feature is not supported by
the service provider. */
int INVALID_CONTACT = 74; /* The contact to be added is either not
existing or not valid. */
int MODEM_INCOMPATIBLE = 75; /* The modem of the MS is not compatible with
the service provider. */
int NETWORK_TIMEOUT = 76; /* Modem timeout to receive ACK or response from
network after sending a request to it. */
int NO_SATELLITE_SIGNAL = 77; /* Modem fails to communicate with the satellite
network since there is no satellite signal.*/
int NOT_SUFFICIENT_ACCOUNT_BALANCE = 78; /* The request cannot be performed since the
subscriber's account balance is not
sufficient. */
int RADIO_TECHNOLOGY_NOT_SUPPORTED = 79; /* The radio technology is not supported by the
service provider. */
int SUBSCRIBER_NOT_AUTHORIZED = 80; /* The subscription is not authorized to
register with the service provider. */
int SWITCHED_FROM_SATELLITE_TO_TERRESTRIAL = 81; /* While processing a request from the
Framework the satellite modem detects
terrestrial signal, aborts the request, and
switches to the terrestrial network. */
int UNIDENTIFIED_SUBSCRIBER = 82; /* The subscriber is not registered with the
service provider */
// Below is list of OEM specific error codes which can by used by OEMs in case they don't want to
// reveal particular replacement for Generic failure