Merge "Do CSFB instead of scanning with CS preferred network list"
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 5ec4f65..901c8b2 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -145,10 +145,10 @@
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.stub.ImsConfigImplBase;
import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.telephony.satellite.ISatelliteCapabilitiesConsumer;
import android.telephony.satellite.ISatelliteStateListener;
import android.telephony.satellite.PointingInfo;
import android.telephony.satellite.SatelliteCapabilities;
+import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteManager;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -175,7 +175,6 @@
import com.android.internal.telephony.IBooleanConsumer;
import com.android.internal.telephony.ICallForwardingInfoCallback;
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.ITelephony;
@@ -394,18 +393,24 @@
private static final int EVENT_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG_DONE = 124;
private static final int CMD_PROVISION_SATELLITE_SERVICE = 125;
private static final int EVENT_PROVISION_SATELLITE_SERVICE_DONE = 126;
- private static final int CMD_CANCEL_PROVISION_SATELLITE_SERVICE = 127;
- private static final int EVENT_CANCEL_PROVISION_SATELLITE_SERVICE_DONE = 128;
- private static final int CMD_GET_PROVISIONED_SATELLITE_FEATURES = 129;
- private static final int EVENT_GET_PROVISIONED_SATELLITE_FEATURES_DONE = 130;
- private static final int CMD_SET_SATELLITE_POWER = 131;
- private static final int EVENT_SET_SATELLITE_POWER_DONE = 132;
- private static final int CMD_IS_SATELLITE_POWER_ON = 133;
- private static final int EVENT_IS_SATELLITE_POWER_ON_DONE = 134;
- private static final int CMD_IS_SATELLITE_SUPPORTED = 135;
- private static final int EVENT_IS_SATELLITE_SUPPORTED_DONE = 136;
- private static final int CMD_GET_SATELLITE_CAPABILITIES = 137;
- private static final int EVENT_GET_SATELLITE_CAPABILITIES_DONE = 138;
+ private static final int CMD_DEPROVISION_SATELLITE_SERVICE = 127;
+ private static final int EVENT_DEPROVISION_SATELLITE_SERVICE_DONE = 128;
+ private static final int CMD_SET_SATELLITE_ENABLED = 129;
+ private static final int EVENT_SET_SATELLITE_ENABLED_DONE = 130;
+ private static final int CMD_IS_SATELLITE_ENABLED = 131;
+ private static final int EVENT_IS_SATELLITE_ENABLED_DONE = 132;
+ private static final int CMD_IS_SATELLITE_SUPPORTED = 133;
+ private static final int EVENT_IS_SATELLITE_SUPPORTED_DONE = 134;
+ private static final int CMD_GET_SATELLITE_CAPABILITIES = 135;
+ private static final int EVENT_GET_SATELLITE_CAPABILITIES_DONE = 136;
+ private static final int CMD_POLL_PENDING_SATELLITE_DATAGRAMS = 137;
+ private static final int EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE = 138;
+ private static final int CMD_SEND_SATELLITE_DATAGRAM = 139;
+ private static final int EVENT_SEND_SATELLITE_DATAGRAM_DONE = 140;
+ private static final int CMD_IS_SATELLITE_COMMUNICATION_ALLOWED = 141;
+ private static final int EVENT_IS_SATELLITE_COMMUNICATION_ALLOWED_DONE = 142;
+ private static final int CMD_GET_TIME_SATELLITE_NEXT_VISIBLE = 143;
+ private static final int EVENT_GET_TIME_SATELLITE_NEXT_VISIBLE_DONE = 144;
// Parameters of select command.
private static final int SELECT_COMMAND = 0xA4;
private static final int SELECT_P1 = 0x04;
@@ -436,20 +441,39 @@
private static final int USER_ACTIVITY_NOTIFICATION_DELAY = 200;
private Set<Integer> mCarrierPrivilegeTestOverrideSubIds = new ArraySet<>();
- private ConcurrentHashMap<IBinder, SatellitePositionUpdateHandler>
- mSatellitePositionUpdateHandlers = new ConcurrentHashMap<>();
+
/**
* Map key: subId, value: callback to get error code of the provision request.
*/
- private ConcurrentHashMap<Integer, IIntegerConsumer> mSatelliteProvisionCallbacks =
+ private final ConcurrentHashMap<Integer, Consumer<Integer>> mSatelliteProvisionCallbacks =
new ConcurrentHashMap<>();
-
+ /**
+ * Map key: subId, value: SatellitePositionUpdateHandler to notify registrants.
+ */
+ private final ConcurrentHashMap<IBinder, SatellitePositionUpdateHandler>
+ mSatellitePositionUpdateHandlers = new ConcurrentHashMap<>();
/**
* Map key: subId, value: SatelliteProvisionStateChangedHandler to notify registrants.
*/
- private ConcurrentHashMap<Integer, SatelliteProvisionStateChangedHandler>
+ private final ConcurrentHashMap<Integer, SatelliteProvisionStateChangedHandler>
mSatelliteProvisionStateChangedHandlers = new ConcurrentHashMap<>();
+ private Boolean mIsSatelliteSupported = null;
+ private final Object mIsSatelliteSupportedLock = new Object();
+ private final ResultReceiver mSatelliteSupportedReceiver;
+
+ /**
+ * Map key: subId, value: SatelliteStateChangeHandler to notify registrants.
+ */
+ private ConcurrentHashMap<Integer, SatelliteStateListenerHandler>
+ mSatelliteStateListenerHandlers = new ConcurrentHashMap<>();
+
+ /**
+ * Map key: subId, value: SatelliteDatagramListenerHandler to notify registrants.
+ */
+ private ConcurrentHashMap<Integer, SatelliteDatagramListenerHandler>
+ mSatelliteDatagramListenerHandlers = new ConcurrentHashMap<>();
+
private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
@@ -545,17 +569,30 @@
}
private static final class ProvisionSatelliteServiceArgument {
- public @NonNull int[] features;
- public @NonNull IIntegerConsumer callback;
+ public @NonNull String token;
+ public @NonNull Consumer<Integer> callback;
public int subId;
- ProvisionSatelliteServiceArgument(int[] features, IIntegerConsumer callback, int subId) {
- this.features = features;
+ ProvisionSatelliteServiceArgument(String token, Consumer<Integer> callback, int subId) {
+ this.token = token;
this.callback = callback;
this.subId = subId;
}
}
+ private static final class SendSatelliteDatagramArgument {
+ public @SatelliteManager.DatagramType int datagramType;
+ public @NonNull SatelliteDatagram datagram;
+ public @NonNull Consumer<Integer> callback;
+
+ SendSatelliteDatagramArgument(@SatelliteManager.DatagramType int datagramType,
+ SatelliteDatagram datagram, Consumer<Integer> callback) {
+ this.datagramType = datagramType;
+ this.datagram = datagram;
+ this.callback = callback;
+ }
+ }
+
private static final class SatellitePositionUpdateHandler extends Handler {
public static final int EVENT_POSITION_UPDATE = 1;
public static final int EVENT_MESSAGE_TRANSFER_STATE_UPDATE = 2;
@@ -584,7 +621,8 @@
AsyncResult ar = (AsyncResult) msg.obj;
int state = (int) ar.result;
try {
- mCallback.onMessageTransferStateUpdate(state);
+ // TODO: get correct responses back from indication
+ mCallback.onMessageTransferStateUpdate(state, 0, 0, 0);
} catch (RemoteException e) {
loge("EVENT_MESSAGE_TRANSFER_STATE_UPDATE RemoteException: " + e);
}
@@ -622,19 +660,17 @@
case EVENT_PROVISION_STATE_CHANGED: {
AsyncResult ar = (AsyncResult) msg.obj;
boolean provisioned = (boolean) ar.userObj;
- int[] features = (int[]) ar.result;
log("Received EVENT_PROVISION_STATE_CHANGED for subId=" + mSubId
- + ", features=" + Arrays.toString(features)
+ ", provisioned=" + provisioned);
mListeners.values().forEach(listener -> {
try {
- listener.onSatelliteProvisionStateChanged(features, provisioned);
+ listener.onSatelliteProvisionStateChanged(provisioned);
} catch (RemoteException e) {
log("EVENT_PROVISION_STATE_CHANGED RemoteException: " + e);
}
});
- setSatelliteEnabled(provisioned);
+ setSatelliteProvisioned(provisioned);
/**
* TODO: Take bugreport if provisioned is true and user did not initiate the
* provision procedure for the corresponding subscription.
@@ -646,12 +682,115 @@
}
}
- private void setSatelliteEnabled(boolean isEnabled) {
+ private void setSatelliteProvisioned(boolean isProvisioned) {
if (mSubId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
SubscriptionManager.setSubscriptionProperty(
- mSubId, SubscriptionManager.SATELLITE_ENABLED, isEnabled ? "1" : "0");
+ mSubId, SubscriptionManager.SATELLITE_ENABLED, isProvisioned ? "1" : "0");
} else {
- //TODO (b/267826133): set enabled via SatelliteController.
+ //TODO (b/267826133): set via SatelliteController.
+ }
+ }
+ }
+
+ private static final class SatelliteStateListenerHandler extends Handler {
+ public static final int EVENT_SATELLITE_MODEM_STATE_CHANGE = 1;
+ public static final int EVENT_PENDING_MESSAGE_COUNT = 2;
+
+ private ConcurrentHashMap<IBinder, ISatelliteStateListener> mListeners;
+ private final int mSubId;
+
+ SatelliteStateListenerHandler(Looper looper, int subId) {
+ super(looper);
+ mSubId = subId;
+ mListeners = new ConcurrentHashMap<>();
+ }
+
+ public void addListener(ISatelliteStateListener listener) {
+ mListeners.put(listener.asBinder(), listener);
+ }
+
+ public boolean removeListener(ISatelliteStateListener listener) {
+ return (mListeners.remove(listener.asBinder()) != null);
+ }
+
+ @Override
+ public void handleMessage(@NonNull Message msg) {
+ switch (msg.what) {
+ case EVENT_SATELLITE_MODEM_STATE_CHANGE : {
+ AsyncResult ar = (AsyncResult) msg.obj;
+ int state = (int) ar.result;
+ log("Received EVENT_SATELLITE_MODEM_STATE_CHANGE for subId=" + mSubId
+ + ", state=" + state);
+ mListeners.values().forEach(listener -> {
+ try {
+ listener.onSatelliteModemStateChange(state);
+ } catch (RemoteException e) {
+ log("EVENT_SATELLITE_MODEM_STATE_CHANGE RemoteException: " + e);
+ }
+ });
+ break;
+ }
+ case EVENT_PENDING_MESSAGE_COUNT: {
+ AsyncResult ar = (AsyncResult) msg.obj;
+ int count = (int) ar.result;
+ log("Received EVENT_PENDING_MESSAGE_COUNT for subId=" + mSubId
+ + ", count=" + count);
+ mListeners.values().forEach(listener -> {
+ try {
+ listener.onPendingMessageCount(count);
+ } catch (RemoteException e) {
+ log("EVENT_PENDING_MESSAGE_COUNT RemoteException: " + e);
+ }
+ });
+ break;
+ }
+ default:
+ loge("SatelliteStateListenerHandler unknown event: " + msg.what);
+ }
+ }
+ }
+
+ private static final class SatelliteDatagramListenerHandler extends Handler {
+ public static final int EVENT_SATELLITE_DATAGRAMS_RECEIVED = 1;
+
+ private ConcurrentHashMap<IBinder, ISatelliteStateListener> mListeners;
+ private final int mSubId;
+
+ SatelliteDatagramListenerHandler(Looper looper, int subId) {
+ super(looper);
+ mSubId = subId;
+ mListeners = new ConcurrentHashMap<>();
+ }
+
+ public void addListener(ISatelliteStateListener listener) {
+ mListeners.put(listener.asBinder(), listener);
+ }
+
+ public boolean removeListener(ISatelliteStateListener listener) {
+ return (mListeners.remove(listener.asBinder()) != null);
+ }
+
+ @Override
+ public void handleMessage(@NonNull Message msg) {
+ switch (msg.what) {
+ case EVENT_SATELLITE_DATAGRAMS_RECEIVED : {
+ AsyncResult ar = (AsyncResult) msg.obj;
+ byte[][] datagrams = (byte[][]) ar.result;
+ SatelliteDatagram[] satelliteDatagramArray =
+ convertToSatelliteDatagramArray(datagrams);
+
+ log("Received EVENT_SATELLITE_DATAGRAMS_RECEIVED for subId=" + mSubId);
+ mListeners.values().forEach(listener -> {
+ try {
+ listener.onSatelliteDatagrams(satelliteDatagramArray);
+ } catch (RemoteException e) {
+ log("EVENT_SATELLITE_DATAGRAMS_RECEIVED RemoteException: " + e);
+ }
+ });
+ break;
+ }
+ default:
+ loge("SatelliteDatagramListenerHandler unknown event: " + msg.what);
}
}
}
@@ -1663,13 +1802,14 @@
break;
}
- case CMD_SET_ALLOWED_CARRIERS:
+ case CMD_SET_ALLOWED_CARRIERS: {
request = (MainThreadRequest) msg.obj;
CarrierRestrictionRules argument =
(CarrierRestrictionRules) request.argument;
onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
break;
+ }
case EVENT_SET_ALLOWED_CARRIERS_DONE:
ar = (AsyncResult) msg.obj;
@@ -1957,7 +2097,7 @@
case EVENT_CMD_MODEM_REBOOT_DONE:
handleNullReturnEvent(msg, "rebootModem");
break;
- case CMD_REQUEST_ENABLE_MODEM:
+ case CMD_REQUEST_ENABLE_MODEM: {
request = (MainThreadRequest) msg.obj;
boolean enable = (boolean) request.argument;
onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
@@ -1965,6 +2105,7 @@
PhoneConfigurationManager.getInstance()
.enablePhone(request.phone, enable, onCompleted);
break;
+ }
case EVENT_ENABLE_MODEM_DONE: {
ar = (AsyncResult) msg.obj;
request = (MainThreadRequest) ar.userObj;
@@ -2411,9 +2552,8 @@
phone.startSatellitePositionUpdates(onCompleted);
} else {
loge("startSatellitePositionUpdates: No phone object");
- request.result =
- SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
- notifyRequester(request);
+ ((Consumer<Integer>) request.argument).accept(
+ SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
}
break;
}
@@ -2421,20 +2561,8 @@
case EVENT_START_SATELLITE_POSITION_UPDATES_DONE: {
ar = (AsyncResult) msg.obj;
request = (MainThreadRequest) ar.userObj;
- if (ar.exception == null) {
- request.result = SatelliteManager.SATELLITE_SERVICE_SUCCESS;
- } else {
- request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
- if (ar.exception instanceof CommandException) {
- CommandException.Error error =
- ((CommandException) (ar.exception)).getCommandError();
- request.result = RILUtils.convertToSatelliteError(error);
- loge("startSatellitePositionUpdates CommandException: " + ar.exception);
- } else {
- loge("startSatellitePositionUpdates unknown exception:" + ar.exception);
- }
- }
- notifyRequester(request);
+ int error = getSatelliteError(ar, "startSatellitePositionUpdates", false);
+ ((Consumer<Integer>) request.argument).accept(error);
break;
}
@@ -2447,9 +2575,8 @@
phone.stopSatellitePositionUpdates(onCompleted);
} else {
loge("stopSatellitePositionUpdates: No phone object");
- request.result =
- SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
- notifyRequester(request);
+ ((Consumer<Integer>) request.argument).accept(
+ SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
}
break;
}
@@ -2457,20 +2584,8 @@
case EVENT_STOP_SATELLITE_POSITION_UPDATES_DONE: {
ar = (AsyncResult) msg.obj;
request = (MainThreadRequest) ar.userObj;
- if (ar.exception == null) {
- request.result = SatelliteManager.SATELLITE_SERVICE_SUCCESS;
- } else {
- request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
- if (ar.exception instanceof CommandException) {
- CommandException.Error error =
- ((CommandException) (ar.exception)).getCommandError();
- request.result = RILUtils.convertToSatelliteError(error);
- loge("stopSatellitePositionUpdates CommandException: " + ar.exception);
- } else {
- loge("stopSatellitePositionUpdates unknown exception:" + ar.exception);
- }
- }
- notifyRequester(request);
+ int error = getSatelliteError(ar, "stopSatellitePositionUpdates", false);
+ ((Consumer<Integer>) request.argument).accept(error);
break;
}
@@ -2483,9 +2598,8 @@
phone.getMaxCharactersPerSatelliteTextMessage(onCompleted);
} else {
loge("getMaxCharactersPerSatelliteTextMessage: No phone object");
- request.result = SatelliteManager
- .SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
- notifyRequester(request);
+ ((ResultReceiver) request.argument).send(
+ SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
}
break;
}
@@ -2493,46 +2607,31 @@
case EVENT_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG_DONE: {
ar = (AsyncResult) msg.obj;
request = (MainThreadRequest) ar.userObj;
- Consumer<Integer> callback = (Consumer<Integer>) request.argument;
- if (ar.exception != null) {
- request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
- if (ar.exception instanceof CommandException) {
- CommandException.Error error =
- ((CommandException) (ar.exception)).getCommandError();
- request.result = RILUtils.convertToSatelliteError(error);
- loge("getMaxCharactersPerSatelliteTextMessage: "
- + "CommandException: " + ar.exception);
- } else {
- loge("getMaxCharactersPerSatelliteTextMessage: "
- + "unknown exception:" + ar.exception);
- }
- } else if (ar.result == null) {
- request.result = SatelliteManager
- .SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
- loge("getMaxCharactersPerSatelliteTextMessage: result is null");
- } else {
- request.result = SatelliteManager.SATELLITE_SERVICE_SUCCESS;
+ int error =
+ getSatelliteError(ar, "getMaxCharactersPerSatelliteTextMessage", true);
+ Bundle bundle = new Bundle();
+ if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
int maxCharLimit = ((int[]) ar.result)[0];
if (DBG) log("getMaxCharactersPerSatelliteTextMessage: " + maxCharLimit);
- callback.accept(maxCharLimit);
+ bundle.putInt(SatelliteManager.KEY_MAX_CHARACTERS_PER_SATELLITE_TEXT,
+ maxCharLimit);
}
- notifyRequester(request);
+ ((ResultReceiver) request.argument).send(error, bundle);
break;
}
case CMD_PROVISION_SATELLITE_SERVICE: {
request = (MainThreadRequest) msg.obj;
- onCompleted =
- obtainMessage(EVENT_PROVISION_SATELLITE_SERVICE_DONE, request);
+ onCompleted = obtainMessage(EVENT_PROVISION_SATELLITE_SERVICE_DONE, request);
Phone phone = getPhoneFromRequest(request);
+ ProvisionSatelliteServiceArgument argument =
+ (ProvisionSatelliteServiceArgument) request.argument;
if (phone != null) {
- handleCmdProvisionSatelliteService(
- (ProvisionSatelliteServiceArgument) request.argument,
- phone, onCompleted);
+ handleCmdProvisionSatelliteService(argument, phone, onCompleted);
} else {
loge("provisionSatelliteService: No phone object");
- request.result =
- SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
+ argument.callback.accept(
+ SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
notifyRequester(request);
}
break;
@@ -2541,187 +2640,94 @@
case EVENT_PROVISION_SATELLITE_SERVICE_DONE: {
ar = (AsyncResult) msg.obj;
request = (MainThreadRequest) ar.userObj;
- if (ar.exception == null) {
- request.result = SatelliteManager.SATELLITE_SERVICE_SUCCESS;
- } else {
- request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
- if (ar.exception instanceof CommandException) {
- CommandException.Error error =
- ((CommandException) (ar.exception)).getCommandError();
- request.result = RILUtils.convertToSatelliteError(error);
- loge("provisionSatelliteService CommandException: " + ar.exception);
- } else {
- loge("provisionSatelliteService unknown exception:" + ar.exception);
- }
- }
- handleEventProvisionSatelliteServiceDone(request);
+ int errorCode = getSatelliteError(ar, "provisionSatelliteService", false);
+ handleEventProvisionSatelliteServiceDone(
+ (ProvisionSatelliteServiceArgument) request.argument, errorCode);
notifyRequester(request);
break;
}
- case CMD_CANCEL_PROVISION_SATELLITE_SERVICE: {
+ case CMD_DEPROVISION_SATELLITE_SERVICE: {
request = (MainThreadRequest) msg.obj;
- onCompleted =
- obtainMessage(EVENT_CANCEL_PROVISION_SATELLITE_SERVICE_DONE, request);
- handleCmdCancelProvisionSatelliteService((int) request.argument, onCompleted);
- break;
- }
-
- case EVENT_CANCEL_PROVISION_SATELLITE_SERVICE_DONE: {
- ar = (AsyncResult) msg.obj;
- request = (MainThreadRequest) ar.userObj;
-
- if (ar.exception == null) {
- request.result = SatelliteManager.SATELLITE_SERVICE_SUCCESS;
- log("cancelProvisionSatelliteService succeeded for subId="
- + (int) request.argument);
- } else {
- request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
- if (ar.exception instanceof CommandException) {
- CommandException.Error error =
- ((CommandException) (ar.exception)).getCommandError();
- request.result = RILUtils.convertToSatelliteError(error);
- loge("cancelProvisionSatelliteService CommandException: "
- + ar.exception + ", error code:" + request.result);
- } else {
- loge("cancelProvisionSatelliteService unknown exception:"
- + ar.exception);
- }
- }
- notifyRequester(request);
- break;
- }
-
- case CMD_GET_PROVISIONED_SATELLITE_FEATURES: {
- request = (MainThreadRequest) msg.obj;
- onCompleted = obtainMessage(EVENT_GET_PROVISIONED_SATELLITE_FEATURES_DONE,
- request);
+ onCompleted = obtainMessage(EVENT_DEPROVISION_SATELLITE_SERVICE_DONE, request);
Phone phone = getPhoneFromRequest(request);
+ ProvisionSatelliteServiceArgument argument =
+ (ProvisionSatelliteServiceArgument) request.argument;
if (phone != null) {
- phone.getProvisionedSatelliteFeatures(onCompleted);
+ handleCmdDeprovisionSatelliteService(argument, phone, onCompleted);
} else {
- loge("getProvisionedSatelliteFeatures: No phone object");
- request.result = SatelliteManager
- .SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
+ loge("deprovisionSatelliteService: No phone object");
+ if (argument.callback != null) {
+ argument.callback.accept(
+ SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+ }
notifyRequester(request);
}
break;
}
- case EVENT_GET_PROVISIONED_SATELLITE_FEATURES_DONE: {
+ case EVENT_DEPROVISION_SATELLITE_SERVICE_DONE: {
ar = (AsyncResult) msg.obj;
request = (MainThreadRequest) ar.userObj;
- if (ar.exception != null) {
- request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
- if (ar.exception instanceof CommandException) {
- CommandException.Error error =
- ((CommandException) (ar.exception)).getCommandError();
- request.result = RILUtils.convertToSatelliteError(error);
- loge("getProvisionedSatelliteFeatures: "
- + "CommandException: " + ar.exception);
- } else {
- loge("getProvisionedSatelliteFeatures: "
- + "unknown exception:" + ar.exception);
- }
- } else if (ar.result == null) {
- request.result = SatelliteManager
- .SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
- loge("getProvisionedSatelliteFeatures: result is null");
- } else {
- request.result = SatelliteManager.SATELLITE_SERVICE_SUCCESS;
- int[] features = ((int[]) ar.result);
- if (DBG) {
- log("getProvisionedSatelliteFeatures features:"
- + Arrays.toString(features));
- }
- IIntArrayConsumer callback = (IIntArrayConsumer) request.argument;
- if (callback != null) {
- try {
- callback.accept(features);
- } catch (RemoteException ex) {
- log("getProvisionedSatelliteFeatures: remote callback"
- + " not available");
- }
- } else {
- log("getProvisionedSatelliteFeatures: callback is null");
- }
- }
+ int errorCode = getSatelliteError(ar, "deprovisionSatelliteService", false);
+ handleEventDeprovisionSatelliteServiceDone(
+ (ProvisionSatelliteServiceArgument) request.argument, errorCode);
notifyRequester(request);
break;
}
- case CMD_SET_SATELLITE_POWER: {
+ case CMD_SET_SATELLITE_ENABLED: {
request = (MainThreadRequest) msg.obj;
- onCompleted = obtainMessage(EVENT_SET_SATELLITE_POWER_DONE, request);
+ onCompleted = obtainMessage(EVENT_SET_SATELLITE_ENABLED_DONE, request);
+ Pair<Boolean, Consumer<Integer>> argument =
+ (Pair<Boolean, Consumer<Integer>>) request.argument;
Phone phone = getPhoneFromRequest(request);
if (phone != null) {
- phone.setSatellitePower(onCompleted, (boolean) request.argument);
+ boolean enable = argument.first.booleanValue();
+ phone.setSatellitePower(onCompleted, enable);
} else {
- loge("setSatellitePower: No phone object");
- request.result = SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
+ loge("setSatelliteEnabled: No phone object");
+ argument.second.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
notifyRequester(request);
}
break;
}
- case EVENT_SET_SATELLITE_POWER_DONE: {
+ case EVENT_SET_SATELLITE_ENABLED_DONE: {
ar = (AsyncResult) msg.obj;
request = (MainThreadRequest) ar.userObj;
- if (ar.exception == null) {
- request.result = SatelliteManager.SATELLITE_SERVICE_SUCCESS;
- } else {
- request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
- if (ar.exception instanceof CommandException) {
- CommandException.Error error =
- ((CommandException) (ar.exception)).getCommandError();
- request.result = RILUtils.convertToSatelliteError(error);
- loge("setSatellitePower CommandException: " + ar.exception);
- } else {
- loge("setSatellitePower unknown exception:" + ar.exception);
- }
- }
- notifyRequester(request);
+ Pair<Boolean, Consumer<Integer>> argument =
+ (Pair<Boolean, Consumer<Integer>>) request.argument;
+ int error = getSatelliteError(ar, "setSatelliteEnabled", false);
+ argument.second.accept(error);
break;
}
- case CMD_IS_SATELLITE_POWER_ON: {
+ case CMD_IS_SATELLITE_ENABLED: {
request = (MainThreadRequest) msg.obj;
- onCompleted = obtainMessage(EVENT_IS_SATELLITE_POWER_ON_DONE, request);
+ onCompleted = obtainMessage(EVENT_IS_SATELLITE_ENABLED_DONE, request);
Phone phone = getPhoneFromRequest(request);
if (phone != null) {
phone.isSatellitePowerOn(onCompleted);
} else {
- loge("isSatellitePowerOn: No phone object");
- request.result = SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
- notifyRequester(request);
+ loge("isSatelliteEnabled: No phone object");
+ ((ResultReceiver) request.argument).send(
+ SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
}
break;
}
- case EVENT_IS_SATELLITE_POWER_ON_DONE: {
+ case EVENT_IS_SATELLITE_ENABLED_DONE: {
ar = (AsyncResult) msg.obj;
request = (MainThreadRequest) ar.userObj;
- Consumer<Boolean> callback = (Consumer<Boolean>) request.argument;
- if (ar.exception != null) {
- request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
- if (ar.exception instanceof CommandException) {
- CommandException.Error error =
- ((CommandException) (ar.exception)).getCommandError();
- request.result = RILUtils.convertToSatelliteError(error);
- loge("isSatellitePowerOn CommandException: " + ar.exception);
- } else {
- loge("isSatellitePowerOn unknown exception:" + ar.exception);
- }
- } else if (ar.result == null) {
- request.result = SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
- loge("isSatellitePowerOn: result is null");
- } else {
- request.result = SatelliteManager.SATELLITE_SERVICE_SUCCESS;
- boolean powerOn = ((int[]) ar.result)[0] == 1;
- if (DBG) log("isSatellitePowerOn: " + powerOn);
- callback.accept(powerOn);
+ int error = getSatelliteError(ar, "isSatelliteEnabled", true);
+ Bundle bundle = new Bundle();
+ if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
+ boolean enabled = ((int[]) ar.result)[0] == 1;
+ if (DBG) log("isSatelliteEnabled: " + enabled);
+ bundle.putBoolean(SatelliteManager.KEY_SATELLITE_ENABLED, enabled);
}
- notifyRequester(request);
+ ((ResultReceiver) request.argument).send(error, bundle);
break;
}
@@ -2733,8 +2739,8 @@
phone.isSatelliteSupported(onCompleted);
} else {
loge("isSatelliteSupported: No phone object");
- request.result = SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
- notifyRequester(request);
+ ((ResultReceiver) request.argument).send(
+ SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
}
break;
}
@@ -2742,27 +2748,21 @@
case EVENT_IS_SATELLITE_SUPPORTED_DONE: {
ar = (AsyncResult) msg.obj;
request = (MainThreadRequest) ar.userObj;
- Consumer<Boolean> callback = (Consumer<Boolean>) request.argument;
- if (ar.exception != null) {
- request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
- if (ar.exception instanceof CommandException) {
- CommandException.Error error =
- ((CommandException) (ar.exception)).getCommandError();
- request.result = RILUtils.convertToSatelliteError(error);
- loge("isSatelliteSupported CommandException: " + ar.exception);
- } else {
- loge("isSatelliteSupported unknown exception:" + ar.exception);
+ int error = getSatelliteError(ar, "isSatelliteSupported", true);
+ Bundle bundle = new Bundle();
+ if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
+ boolean supported = ((int[]) ar.result)[0] == 1;
+ if (DBG) log("isSatelliteSupported: " + supported);
+ bundle.putBoolean(SatelliteManager.KEY_SATELLITE_SUPPORTED, supported);
+ synchronized (mIsSatelliteSupportedLock) {
+ mIsSatelliteSupported = supported;
}
- } else if (ar.result == null) {
- request.result = SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
- loge("isSatelliteSupported: result is null");
} else {
- request.result = SatelliteManager.SATELLITE_SERVICE_SUCCESS;
- boolean powerOn = ((int[]) ar.result)[0] == 1;
- if (DBG) log("isSatelliteSupported: " + powerOn);
- callback.accept(powerOn);
+ synchronized (mIsSatelliteSupportedLock) {
+ mIsSatelliteSupported = null;
+ }
}
- notifyRequester(request);
+ ((ResultReceiver) request.argument).send(error, bundle);
break;
}
@@ -2774,8 +2774,8 @@
phone.getSatelliteCapabilities(onCompleted);
} else {
loge("getSatelliteCapabilities: No phone object");
- request.result = SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
- notifyRequester(request);
+ ((ResultReceiver) request.argument).send(
+ SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
}
break;
}
@@ -2783,31 +2783,155 @@
case EVENT_GET_SATELLITE_CAPABILITIES_DONE: {
ar = (AsyncResult) msg.obj;
request = (MainThreadRequest) ar.userObj;
- Consumer<SatelliteCapabilities> callback =
- (Consumer<SatelliteCapabilities>) request.argument;
+ int error = getSatelliteError(ar, "getSatelliteCapabilities", true);
+ Bundle bundle = new Bundle();
+ if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
+ SatelliteCapabilities capabilities = (SatelliteCapabilities) ar.result;
+ if (DBG) log("getSatelliteCapabilities: " + capabilities);
+ bundle.putParcelable(SatelliteManager.KEY_SATELLITE_CAPABILITIES,
+ capabilities);
+ }
+ ((ResultReceiver) request.argument).send(error, bundle);
+ break;
+ }
+
+ case CMD_POLL_PENDING_SATELLITE_DATAGRAMS: {
+ request = (MainThreadRequest) msg.obj;
+ onCompleted = obtainMessage(EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE,
+ request);
+ Phone phone = getPhoneFromRequest(request);
+ if (phone != null) {
+ phone.pollPendingSatelliteDatagrams(onCompleted);
+ } else {
+ loge("pollPendingSatelliteDatagrams: No phone object");
+ request.result = SatelliteManager
+ .SATELLITE_INVALID_TELEPHONY_STATE;
+ notifyRequester(request);
+ }
+ break;
+ }
+
+ case EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE: {
+ ar = (AsyncResult) msg.obj;
+ request = (MainThreadRequest) ar.userObj;
if (ar.exception != null) {
request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
if (ar.exception instanceof CommandException) {
CommandException.Error error =
((CommandException) (ar.exception)).getCommandError();
request.result = RILUtils.convertToSatelliteError(error);
- loge("getSatelliteCapabilities CommandException: " + ar.exception);
+ loge("pollPendingSatelliteDatagrams: "
+ + "CommandException: " + ar.exception);
} else {
- loge("getSatelliteCapabilities unknown exception:" + ar.exception);
+ loge("pollPendingSatelliteDatagrams: "
+ + "unknown exception:" + ar.exception);
}
} else if (ar.result == null) {
- request.result = SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
- loge("getSatelliteCapabilities: result is null");
+ request.result = SatelliteManager
+ .SATELLITE_INVALID_TELEPHONY_STATE;
+ loge("pollPendingSatelliteDatagrams: result is null");
} else {
- request.result = SatelliteManager.SATELLITE_SERVICE_SUCCESS;
- SatelliteCapabilities capabilities = (SatelliteCapabilities) ar.result;
- if (DBG) log("getSatelliteCapabilities: " + capabilities);
- callback.accept(capabilities);
+ request.result = SatelliteManager.SATELLITE_ERROR_NONE;
}
notifyRequester(request);
break;
}
+ case CMD_SEND_SATELLITE_DATAGRAM: {
+ request = (MainThreadRequest) msg.obj;
+ onCompleted =
+ obtainMessage(EVENT_SEND_SATELLITE_DATAGRAM_DONE, request);
+ Phone phone = getPhoneFromRequest(request);
+ SendSatelliteDatagramArgument argument =
+ (SendSatelliteDatagramArgument) request.argument;
+ if (phone != null) {
+ phone.sendSatelliteDatagram(onCompleted, argument.datagram);
+ } else {
+ loge("sendSatelliteDatagram: No phone object");
+ argument.callback
+ .accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+ }
+ break;
+ }
+
+ case EVENT_SEND_SATELLITE_DATAGRAM_DONE: {
+ ar = (AsyncResult) msg.obj;
+ request = (MainThreadRequest) ar.userObj;
+ int error = getSatelliteError(ar, "sendSatelliteDatagram",
+ false);
+ SendSatelliteDatagramArgument argument =
+ (SendSatelliteDatagramArgument) request.argument;
+ argument.callback.accept(error);
+ break;
+ }
+
+ case CMD_IS_SATELLITE_COMMUNICATION_ALLOWED: {
+ request = (MainThreadRequest) msg.obj;
+ onCompleted = obtainMessage(EVENT_IS_SATELLITE_COMMUNICATION_ALLOWED_DONE,
+ request);
+ Phone phone = getPhoneFromRequest(request);
+ if (phone != null) {
+ phone.isSatelliteCommunicationAllowedForCurrentLocation(onCompleted);
+ } else {
+ loge("isSatelliteCommunicationAllowedForCurrentLocation: No phone object");
+ ((ResultReceiver) request.argument).send(
+ SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+ }
+ break;
+ }
+
+ case EVENT_IS_SATELLITE_COMMUNICATION_ALLOWED_DONE: {
+ ar = (AsyncResult) msg.obj;
+ request = (MainThreadRequest) ar.userObj;
+ int error = getSatelliteError(
+ ar, "isSatelliteCommunicationAllowedForCurrentLocation", true);
+ Bundle bundle = new Bundle();
+ if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
+ boolean communicationAllowed = ((int[]) ar.result)[0] == 1;
+ if (DBG) {
+ log("isSatelliteCommunicationAllowedForCurrentLocation: "
+ + communicationAllowed);
+ }
+ bundle.putBoolean(SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED,
+ communicationAllowed);
+ }
+ ((ResultReceiver) request.argument).send(error, bundle);
+ break;
+ }
+
+ case CMD_GET_TIME_SATELLITE_NEXT_VISIBLE: {
+ request = (MainThreadRequest) msg.obj;
+ onCompleted = obtainMessage(EVENT_GET_TIME_SATELLITE_NEXT_VISIBLE_DONE,
+ request);
+ Phone phone = getPhoneFromRequest(request);
+ if (phone != null) {
+ phone.requestTimeForNextSatelliteVisibility(onCompleted);
+ } else {
+ loge("requestTimeForNextSatelliteVisibility: No phone object");
+ ((ResultReceiver) request.argument).send(
+ SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+ }
+ break;
+ }
+
+ case EVENT_GET_TIME_SATELLITE_NEXT_VISIBLE_DONE: {
+ ar = (AsyncResult) msg.obj;
+ request = (MainThreadRequest) ar.userObj;
+ int error =
+ getSatelliteError(ar, "requestTimeForNextSatelliteVisibility", true);
+ Bundle bundle = new Bundle();
+ if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
+ int nextVisibilityDuration = ((int[]) ar.result)[0];
+ if (DBG) {
+ log("requestTimeForNextSatelliteVisibility: " + nextVisibilityDuration);
+ }
+ bundle.putInt(SatelliteManager.KEY_SATELLITE_NEXT_VISIBILITY,
+ nextVisibilityDuration);
+ }
+ ((ResultReceiver) request.argument).send(error, bundle);
+ break;
+ }
+
default:
Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
break;
@@ -3020,6 +3144,24 @@
PropertyInvalidatedCache.invalidateCache(TelephonyManager.CACHE_KEY_PHONE_ACCOUNT_TO_SUBID);
publish();
CarrierAllowListInfo.loadInstance(mApp);
+ mSatelliteSupportedReceiver = new ResultReceiver(mMainThreadHandler) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode == SatelliteManager.SATELLITE_ERROR_NONE
+ && resultData.containsKey(SatelliteManager.KEY_SATELLITE_SUPPORTED)) {
+ synchronized (mIsSatelliteSupportedLock) {
+ mIsSatelliteSupported = resultData.getBoolean(
+ SatelliteManager.KEY_SATELLITE_SUPPORTED);
+ }
+ } else {
+ synchronized (mIsSatelliteSupportedLock) {
+ mIsSatelliteSupported = null;
+ }
+ }
+ }
+ };
+ requestIsSatelliteSupported(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+ mSatelliteSupportedReceiver);
}
@VisibleForTesting
@@ -6041,7 +6183,7 @@
private boolean isActiveSubscription(int subId) {
if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- return SubscriptionManagerService.getInstance().isActiveSubId(subId,
+ return getSubscriptionManagerService().isActiveSubId(subId,
mApp.getOpPackageName(), mApp.getFeatureId());
}
return mSubscriptionController.isActiveSubId(subId);
@@ -8007,7 +8149,7 @@
ParcelUuid groupUuid;
if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- final SubscriptionInfo info = SubscriptionManagerService.getInstance()
+ final SubscriptionInfo info = getSubscriptionManagerService()
.getSubscriptionInfo(subId);
groupUuid = info.getGroupUuid();
} else {
@@ -8024,7 +8166,7 @@
final List<String> mergedSubscriberIds = new ArrayList<>();
List<SubscriptionInfo> groupInfos;
if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- groupInfos = SubscriptionManagerService.getInstance()
+ groupInfos = getSubscriptionManagerService()
.getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
mApp.getAttributionTag());
} else {
@@ -8594,7 +8736,7 @@
try {
SubscriptionInfo info;
if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- info = SubscriptionManagerService.getInstance().getActiveSubscriptionInfo(subId,
+ info = getSubscriptionManagerService().getActiveSubscriptionInfo(subId,
phone.getContext().getOpPackageName(),
phone.getContext().getAttributionTag());
if (info == null) {
@@ -8661,7 +8803,7 @@
*/
private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- return SubscriptionManagerService.getInstance().getActiveSubscriptionInfoList(
+ return getSubscriptionManagerService().getActiveSubscriptionInfoList(
mApp.getOpPackageName(), mApp.getAttributionTag());
}
return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName(),
@@ -8876,7 +9018,7 @@
try {
// isActiveSubId requires READ_PHONE_STATE, which we already check for above
if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
+ SubscriptionInfoInternal subInfo = getSubscriptionManagerService()
.getSubscriptionInfoInternal(subId);
if (subInfo == null || !subInfo.isActive()) {
Rlog.d(LOG_TAG, "getServiceStateForSubscriber returning null for inactive "
@@ -12619,120 +12761,127 @@
}
/**
- * Power on or off the satellite modem.
+ * Enable or disable the satellite modem. If the satellite modem is enabled, this will also
+ * disable the cellular modem, and if the satellite modem is disabled, this will also re-enable
+ * the cellular modem.
*
- * @param subId The subId to set satellite power for.
- * @param powerOn {@code true} to power on the satellite modem and {@code false} to power off.
- * @return The result of the operation.
+ * @param subId The subId of the subscription to set satellite enabled for.
+ * @param enable {@code true} to enable the satellite modem and {@code false} to disable.
+ * @param callback The callback to get the error code of the request.
*
* @throws SecurityException if the caller doesn't have the required permission.
*/
@Override
- @SatelliteManager.SatelliteServiceResult public int setSatellitePower(int subId,
- boolean powerOn) {
- enforceSatelliteCommunicationPermission("setSatellitePower");
+ public void setSatelliteEnabled(int subId, boolean enable, @NonNull IIntegerConsumer callback) {
+ enforceSatelliteCommunicationPermission("setSatelliteEnabled");
+ Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
+ if (!isSatelliteSupported()) {
+ result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
+ return;
+ }
final int validSubId = getValidSatelliteSubId(subId);
- if (!isSatelliteEnabled(validSubId)) {
- return SatelliteManager.SATELLITE_SERVICE_DISABLED;
+ if (!isSatelliteProvisioned(validSubId)) {
+ result.accept(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED);
+ return;
}
- Phone phone = getPhoneOrDefault(validSubId, "setSatellitePower");
+ Phone phone = getPhoneOrDefault(validSubId, "setSatelliteEnabled");
if (phone == null) {
- return SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
+ result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+ return;
}
- int result = (int) sendRequest(CMD_SET_SATELLITE_POWER, powerOn, subId);
- if (DBG) log("setSatellitePower result: " + result);
- return result;
+ Pair<Boolean, Consumer<Integer>> arg = new Pair<>(enable, result);
+ sendRequestAsync(CMD_SET_SATELLITE_ENABLED, arg, phone, null);
}
/**
- * Check whether the satellite modem is powered on.
+ * Request to get whether the satellite modem is enabled.
*
- * @param subId The subId to check satellite power for.
- * @param callback The callback that will be used to send the result if the operation is
- * successful. Returns {@code true} if the satellite modem is powered on and
- * {@code false} otherwise.
- * @return The result of the operation.
+ * @param subId The subId of the subscription to check whether satellite is enabled for.
+ * @param result The result receiver that returns whether the satellite modem is enabled
+ * if the request is successful or an error code if the request failed.
*
* @throws SecurityException if the caller doesn't have the required permission.
*/
@Override
- @SatelliteManager.SatelliteServiceResult public int isSatellitePowerOn(int subId,
- @NonNull IBooleanConsumer callback) {
- enforceSatelliteCommunicationPermission("isSatellitePowerOn");
+ public void requestIsSatelliteEnabled(int subId, @NonNull ResultReceiver result) {
+ enforceSatelliteCommunicationPermission("requestIsSatelliteEnabled");
+ if (!isSatelliteSupported()) {
+ result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
+ return;
+ }
final int validSubId = getValidSatelliteSubId(subId);
- if (!isSatelliteEnabled(validSubId)) {
- return SatelliteManager.SATELLITE_SERVICE_DISABLED;
+ if (!isSatelliteProvisioned(validSubId)) {
+ result.send(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED, null);
+ return;
}
- Phone phone = getPhoneOrDefault(validSubId, "isSatellitePowerOn");
+ Phone phone = getPhoneOrDefault(validSubId, "requestIsSatelliteEnabled");
if (phone == null) {
- return SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
+ result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+ return;
}
- Consumer<Boolean> argument = FunctionalUtils.ignoreRemoteException(callback::accept);
- int result = (int) sendRequest(CMD_IS_SATELLITE_POWER_ON, argument, subId);
- if (DBG) log("isSatellitePowerOn result: " + result);
- return result;
+ sendRequest(CMD_IS_SATELLITE_ENABLED, result, subId);
}
/**
- * Check whether the satellite service is supported on the device.
+ * Request to get whether the satellite service is supported on the device.
*
- * @param subId The subId to check satellite service support for.
- * @param callback The callback that will be used to send the result if the operation is
- * successful. Returns {@code true} if the satellite service is supported on
- * the device and {@code false} otherwise.
- * @return The result of the operation.
- *
- * @throws SecurityException if the caller doesn't have the required permission.
+ * @param subId The subId of the subscription to check satellite service support for.
+ * @param result The result receiver that returns whether the satellite service is supported on
+ * the device if the request is successful or an error code if the request failed.
*/
@Override
- @SatelliteManager.SatelliteServiceResult public int isSatelliteSupported(int subId,
- @NonNull IBooleanConsumer callback) {
- enforceSatelliteCommunicationPermission("isSatelliteSupported");
-
- final int validSubId = getValidSatelliteSubId(subId);
- Phone phone = getPhoneOrDefault(validSubId, "isSatelliteSupported");
- if (phone == null) {
- return SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
+ public void requestIsSatelliteSupported(int subId, @NonNull ResultReceiver result) {
+ synchronized (mIsSatelliteSupportedLock) {
+ if (mIsSatelliteSupported != null) {
+ /* We have already successfully queried the satellite modem. */
+ Bundle bundle = new Bundle();
+ bundle.putBoolean(SatelliteManager.KEY_SATELLITE_SUPPORTED, mIsSatelliteSupported);
+ result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, bundle);
+ return;
+ }
}
- Consumer<Boolean> argument = FunctionalUtils.ignoreRemoteException(callback::accept);
- int result = (int) sendRequest(CMD_IS_SATELLITE_SUPPORTED, argument, subId);
- if (DBG) log("isSatelliteSupported result: " + result);
- return result;
+ final int validSubId = getValidSatelliteSubId(subId);
+ Phone phone = getPhoneOrDefault(validSubId, "requestIsSatelliteSupported");
+ if (phone == null) {
+ result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+ return;
+ }
+
+ sendRequestAsync(CMD_IS_SATELLITE_SUPPORTED, result, phone, null);
}
/**
- * Get the {@link SatelliteCapabilities} with all capabilities of the satellite service.
+ * Request to get the {@link SatelliteCapabilities} of the satellite service.
*
- * @param subId The subId to get the satellite capabilities for.
- * @param callback The callback that will be used to send the {@link SatelliteCapabilities}
- * if the operation is successful.
- * @return The result of the operation.
+ * @param subId The subId of the subscription to get the satellite capabilities for.
+ * @param result The result receiver that returns the {@link SatelliteCapabilities}
+ * if the request is successful or an error code if the request failed.
*
* @throws SecurityException if the caller doesn't have required permission.
*/
@Override
- @SatelliteManager.SatelliteServiceResult public int getSatelliteCapabilities(int subId,
- @NonNull ISatelliteCapabilitiesConsumer callback) {
- enforceSatelliteCommunicationPermission("getSatelliteCapabilities");
-
- final int validSubId = getValidSatelliteSubId(subId);
- Phone phone = getPhoneOrDefault(validSubId, "getSatelliteCapabilities");
- if (phone == null) {
- return SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
+ public void requestSatelliteCapabilities(int subId, @NonNull ResultReceiver result) {
+ enforceSatelliteCommunicationPermission("requestSatelliteCapabilities");
+ if (!isSatelliteSupported()) {
+ result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
+ return;
}
- Consumer<SatelliteCapabilities> argument =
- FunctionalUtils.ignoreRemoteException(callback::accept);
- int result = (int) sendRequest(CMD_GET_SATELLITE_CAPABILITIES, argument, subId);
- if (DBG) log("getSatelliteCapabilities result: " + result);
- return result;
+ final int validSubId = getValidSatelliteSubId(subId);
+ Phone phone = getPhoneOrDefault(validSubId, "requestSatelliteCapabilities");
+ if (phone == null) {
+ result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+ return;
+ }
+
+ sendRequestAsync(CMD_GET_SATELLITE_CAPABILITIES, result, phone, null);
}
/**
@@ -12740,31 +12889,41 @@
* This can be called by the pointing UI when the user starts pointing to the satellite.
* Modem should continue to report the pointing input as the device or satellite moves.
*
- * @param subId The subId to start satellite position updates for.
+ * @param subId The subId of the subscription to start satellite position updates for.
+ * @param errorCallback The callback to get the error code of the request.
* @param callback The callback to notify of changes in satellite position.
- * @return The result of the operation.
*
* @throws SecurityException if the caller doesn't have the required permission.
*/
@Override
- @SatelliteManager.SatelliteServiceResult public int startSatellitePositionUpdates(int subId,
+ public void startSatellitePositionUpdates(int subId, @NonNull IIntegerConsumer errorCallback,
@NonNull ISatelliteStateListener callback) {
enforceSatelliteCommunicationPermission("startSatellitePositionUpdates");
+ Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(errorCallback::accept);
+ if (!isSatelliteSupported()) {
+ result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
+ return;
+ }
final int validSubId = getValidSatelliteSubId(subId);
- if (!isSatelliteEnabled(validSubId)) {
- return SatelliteManager.SATELLITE_SERVICE_DISABLED;
+ if (!isSatelliteProvisioned(validSubId)) {
+ result.accept(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED);
+ return;
}
Phone phone = getPhoneOrDefault(validSubId, "startSatellitePositionUpdates");
if (phone == null) {
- return SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
+ result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+ return;
}
if (mSatellitePositionUpdateHandlers.containsKey(callback.asBinder())) {
- log("startSatellitePositionUpdates: callback already registered: "
- + callback.asBinder());
- return SatelliteManager.SATELLITE_SERVICE_CALLBACK_ALREADY_REGISTERED;
+ if (DBG) {
+ log("startSatellitePositionUpdates: callback already registered: "
+ + callback.asBinder());
+ }
+ result.accept(SatelliteManager.SATELLITE_ERROR_NONE);
+ return;
}
SatellitePositionUpdateHandler handler =
@@ -12775,42 +12934,48 @@
SatellitePositionUpdateHandler.EVENT_MESSAGE_TRANSFER_STATE_UPDATE, null);
mSatellitePositionUpdateHandlers.put(callback.asBinder(), handler);
- int result = (int) sendRequest(CMD_START_SATELLITE_POSITION_UPDATES, null, validSubId);
- if (DBG) log("startSatellitePositionUpdates result: " + result);
- return result;
+ sendRequestAsync(CMD_START_SATELLITE_POSITION_UPDATES, result, phone, null);
}
/**
* Stop receiving satellite position updates.
* This can be called by the pointing UI when the user stops pointing to the satellite.
*
- * @param subId The subId to stop satellite position updates for.
- * @param callback The callback that was passed in {@link
- * #startSatellitePositionUpdates(int, ISatelliteStateListener)}
- * @return The result of the operation.
+ * @param subId The subId of the subscription to stop satellite position updates for.
+ * @param errorCallback The callback to get the error code of the request.
+ * @param callback The callback that was passed to {@link
+ * #startSatellitePositionUpdates(int, IIntegerConsumer, ISatelliteStateListener)}
*
* @throws SecurityException if the caller doesn't have the required permission.
*/
@Override
- @SatelliteManager.SatelliteServiceResult public int stopSatellitePositionUpdates(int subId,
+ public void stopSatellitePositionUpdates(int subId, @NonNull IIntegerConsumer errorCallback,
@NonNull ISatelliteStateListener callback) {
enforceSatelliteCommunicationPermission("stopSatellitePositionUpdates");
+ Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(errorCallback::accept);
+ if (!isSatelliteSupported()) {
+ result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
+ return;
+ }
final int validSubId = getValidSatelliteSubId(subId);
- if (!isSatelliteEnabled(validSubId)) {
- return SatelliteManager.SATELLITE_SERVICE_DISABLED;
+ if (!isSatelliteProvisioned(validSubId)) {
+ result.accept(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED);
+ return;
}
Phone phone = getPhoneOrDefault(validSubId, "stopSatellitePositionUpdates");
if (phone == null) {
- return SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
+ result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+ return;
}
SatellitePositionUpdateHandler handler =
mSatellitePositionUpdateHandlers.remove(callback.asBinder());
if (handler == null) {
- loge("stopSatellitePositionUpdates: No SatellitePositionArgument");
- return SatelliteManager.SATELLITE_SERVICE_CALLBACK_NOT_REGISTERED;
+ loge("stopSatellitePositionUpdates: No SatellitePositionUpdateHandler");
+ result.accept(SatelliteManager.SATELLITE_INVALID_ARGUMENTS);
+ return;
} else {
phone.unregisterForSatellitePointingInfoChanged(handler);
phone.unregisterForSatelliteMessagesTransferComplete(handler);
@@ -12818,42 +12983,45 @@
if (!mSatellitePositionUpdateHandlers.isEmpty()) {
log("stopSatellitePositionUpdates: other listeners still exist.");
- return SatelliteManager.SATELLITE_SERVICE_SUCCESS;
+ result.accept(SatelliteManager.SATELLITE_ERROR_NONE);
+ return;
}
- int result = (int) sendRequest(CMD_STOP_SATELLITE_POSITION_UPDATES, null, validSubId);
- if (DBG) log("stopSatellitePositionUpdates result: " + result);
- return result;
+ sendRequestAsync(CMD_STOP_SATELLITE_POSITION_UPDATES, result, phone, null);
}
/**
- * Get maximum number of characters per text message on satellite.
- * @param subId - The subId of the subscription.
- * @param callback - The callback that will be used to send maximum characters limit
- * if operation is successful.
- * @return The result of the operation.
+ * Request to get the maximum number of characters per text message on satellite.
+ *
+ * @param subId The subId of the subscription to get the maximum number of characters for.
+ * @param result The result receiver that returns the maximum number of characters per text
+ * message on satellite if the request is successful or an error code
+ * if the request failed.
*
* @throws SecurityException if the caller doesn't have the required permission.
*/
@Override
- public int getMaxCharactersPerSatelliteTextMessage(int subId, IIntegerConsumer callback) {
- enforceSatelliteCommunicationPermission("getMaxCharactersPerSatelliteTextMessage");
+ public void requestMaxCharactersPerSatelliteTextMessage(int subId,
+ @NonNull ResultReceiver result) {
+ enforceSatelliteCommunicationPermission("requestMaxCharactersPerSatelliteTextMessage");
+ if (!isSatelliteSupported()) {
+ result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
+ return;
+ }
final int validSubId = getValidSatelliteSubId(subId);
- if (!isSatelliteEnabled(validSubId)) {
- return SatelliteManager.SATELLITE_SERVICE_DISABLED;
+ if (!isSatelliteProvisioned(validSubId)) {
+ result.send(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED, null);
+ return;
}
- Phone phone = getPhoneOrDefault(validSubId, "getMaxCharactersPerSatelliteTextMessage");
+ Phone phone = getPhoneOrDefault(validSubId, "requestMaxCharactersPerSatelliteTextMessage");
if (phone == null) {
- return SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
+ result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+ return;
}
- Consumer<Integer> argument = FunctionalUtils.ignoreRemoteException(callback::accept);
- int result = (int) sendRequest(
- CMD_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG, argument, validSubId);
- if (DBG) log("getMaxCharPerTextMessageOnSatellite result: " + result);
- return result;
+ sendRequestAsync(CMD_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG, result, phone, null);
}
/**
@@ -12861,191 +13029,451 @@
* 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 token The token to be used as a unique identifier for provisioning with satellite
+ * gateway.
* @param callback The callback to get the error code of the request.
- * @return The signal transport used by the caller to cancel the provision request.
+ *
+ * @return The signal transport used by the caller to cancel the provision request,
+ * or {@code null} if the request failed.
+ *
* @throws SecurityException if the caller doesn't have the required permission.
*/
@Override
- public ICancellationSignal provisionSatelliteService(int subId, int[] features,
- IIntegerConsumer callback) {
+ @Nullable public ICancellationSignal provisionSatelliteService(int subId,
+ @NonNull String token, @NonNull IIntegerConsumer callback) {
enforceSatelliteCommunicationPermission("provisionSatelliteService");
+ Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
+ if (!isSatelliteSupported()) {
+ result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
+ return null;
+ }
final int validSubId = getValidSatelliteSubId(subId);
- String callbackRemoteExErrorMessage = "provisionSatelliteService: callback not available.";
Phone phone = getPhoneOrDefault(validSubId, "provisionSatelliteService");
if (phone == null) {
- sendResponse(callback, SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE,
- callbackRemoteExErrorMessage);
+ result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
return null;
}
if (mSatelliteProvisionCallbacks.containsKey(validSubId)) {
- sendResponse(callback, SatelliteManager.SATELLITE_SERVICE_PROVISION_IN_PROGRESS,
- callbackRemoteExErrorMessage);
+ result.accept(SatelliteManager.SATELLITE_SERVICE_PROVISION_IN_PROGRESS);
return null;
}
- if (isSatelliteEnabled(validSubId)) {
- sendResponse(callback, SatelliteManager.SATELLITE_SERVICE_ALREADY_PROVISIONED,
- callbackRemoteExErrorMessage);
+ if (isSatelliteProvisioned(validSubId)) {
+ result.accept(SatelliteManager.SATELLITE_ERROR_NONE);
return null;
}
sendRequestAsync(CMD_PROVISION_SATELLITE_SERVICE,
- new ProvisionSatelliteServiceArgument(features, callback, validSubId), phone, null);
+ new ProvisionSatelliteServiceArgument(token, result, validSubId), phone, null);
ICancellationSignal cancelTransport = CancellationSignal.createTransport();
- CancellationSignal.fromTransport(cancelTransport)
- .setOnCancelListener(() -> {
- sendRequestAsync(CMD_CANCEL_PROVISION_SATELLITE_SERVICE, validSubId);
- });
+ CancellationSignal.fromTransport(cancelTransport).setOnCancelListener(() -> {
+ sendRequestAsync(CMD_DEPROVISION_SATELLITE_SERVICE,
+ new ProvisionSatelliteServiceArgument(token, null, validSubId),
+ phone, null);
+ });
return cancelTransport;
}
/**
+ * Unregister the device/subscription with the satellite provider.
+ * This is needed if the provider allows dynamic registration. Once deprovisioned,
+ * {@link SatelliteCallback.SatelliteProvisionStateListener#onSatelliteProvisionStateChanged}
+ * should report as deprovisioned.
+ *
+ * @param subId The subId of the subscription to be deprovisioned.
+ * @param token The token of the device/subscription to be deprovisioned.
+ * @param callback The callback to get the error code of the request.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ public void deprovisionSatelliteService(int subId,
+ @NonNull String token, @NonNull IIntegerConsumer callback) {
+ enforceSatelliteCommunicationPermission("deprovisionSatelliteService");
+ Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
+ if (!isSatelliteSupported()) {
+ result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
+ return;
+ }
+
+ final int validSubId = getValidSatelliteSubId(subId);
+ if (!isSatelliteProvisioned(validSubId)) {
+ result.accept(SatelliteManager.SATELLITE_ERROR_NONE);
+ return;
+ }
+
+ Phone phone = getPhoneOrDefault(validSubId, "deprovisionSatelliteService");
+ if (phone == null) {
+ result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+ return;
+ }
+
+ sendRequestAsync(CMD_DEPROVISION_SATELLITE_SERVICE,
+ new ProvisionSatelliteServiceArgument(token, result, validSubId), phone, null);
+ }
+
+ /**
* Register for the satellite provision state change.
*
- * @param subId The subId of the subscription associated with the satellite service.
+ * @param subId The subId of the subscription to register for provision state changes.
* @param callback The callback to handle the satellite provision state changed event.
+ *
+ * @return The {@link SatelliteManager.SatelliteError} result of the operation.
+ *
* @throws SecurityException if the caller doesn't have the required permission.
*/
@Override
- @SatelliteManager.SatelliteServiceResult
- public int registerForSatelliteProvisionStateChanged(
- int subId, ISatelliteStateListener callback) {
- //enforceSatelliteCommunicationPermission("registerForSatelliteProvisionStateChanged");
-
- final int validSubId = getValidSatelliteSubId(subId);
- Phone phone = getPhoneOrDefault(
- validSubId, "registerForSatelliteProvisionStateChanged");
- if (phone == null) {
- return SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
- }
-
- SatelliteProvisionStateChangedHandler satelliteProvisionStateChangedHandler =
- mSatelliteProvisionStateChangedHandlers.get(validSubId);
- if (satelliteProvisionStateChangedHandler == null) {
- satelliteProvisionStateChangedHandler =
- new SatelliteProvisionStateChangedHandler(
- Looper.getMainLooper(), validSubId);
- phone.registerForSatelliteProvisionStateChanged(
- satelliteProvisionStateChangedHandler,
- SatelliteProvisionStateChangedHandler.EVENT_PROVISION_STATE_CHANGED, null);
- }
-
- if (callback != null) {
- satelliteProvisionStateChangedHandler.addListener(callback);
- }
- mSatelliteProvisionStateChangedHandlers.put(
- validSubId, satelliteProvisionStateChangedHandler);
- return SatelliteManager.SATELLITE_SERVICE_SUCCESS;
+ @SatelliteManager.SatelliteError public int registerForSatelliteProvisionStateChanged(int subId,
+ @NonNull ISatelliteStateListener callback) {
+ enforceSatelliteCommunicationPermission("registerForSatelliteProvisionStateChanged");
+ return registerForSatelliteProvisionStateChangedInternal(subId, 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
- * {@link #registerForSatelliteProvisionStateChanged(int, ISatelliteStateListener)}
+ * @param subId The subId of the subscription to unregister for provision state changes.
+ * @param errorCallback The callback to get the error code of the request.
+ * @param callback The callback that was passed to {@link
+ * #registerForSatelliteProvisionStateChanged(int, ISatelliteStateListener)}.
+ *
+ * @return The {@link SatelliteManager.SatelliteError} result of the operation.
+ *
* @throws SecurityException if the caller doesn't have the required permission.
*/
@Override
- @SatelliteManager.SatelliteServiceResult
- public int unregisterForSatelliteProvisionStateChanged(
- int subId, ISatelliteStateListener callback) {
+ @SatelliteManager.SatelliteError public int unregisterForSatelliteProvisionStateChanged(
+ int subId, @NonNull ISatelliteStateListener callback) {
enforceSatelliteCommunicationPermission("unregisterForSatelliteProvisionStateChanged");
+ if (!isSatelliteSupported()) {
+ return SatelliteManager.SATELLITE_NOT_SUPPORTED;
+ }
final int validSubId = getValidSatelliteSubId(subId);
SatelliteProvisionStateChangedHandler satelliteProvisionStateChangedHandler =
mSatelliteProvisionStateChangedHandlers.get(validSubId);
if (satelliteProvisionStateChangedHandler != null) {
if (satelliteProvisionStateChangedHandler.removeListener(callback)) {
- return SatelliteManager.SATELLITE_SERVICE_SUCCESS;
+ return SatelliteManager.SATELLITE_ERROR_NONE;
}
}
- return SatelliteManager.SATELLITE_SERVICE_CALLBACK_NOT_REGISTERED;
+ return SatelliteManager.SATELLITE_INVALID_ARGUMENTS;
}
/**
- * Get the list of provisioned satellite features.
+ * Request to get whether the device is provisioned with a satellite provider.
*
- * @param subId The subId of the subscription associated with the satellite service.
- * @param callback The callback to get the list of provisioned satellite features.
- * @return The error code of the request.
+ * @param subId The subId of the subscription to get whether the device is provisioned for.
+ * @param result The result receiver that returns whether the device is provisioned with a
+ * satellite provider if the request is successful or an error code if the
+ * request failed.
+ *
* @throws SecurityException if the caller doesn't have the required permission.
*/
@Override
- @SatelliteManager.SatelliteServiceResult
- public int getProvisionedSatelliteFeatures(int subId, IIntArrayConsumer callback) {
- enforceSatelliteCommunicationPermission("getProvisionedSatelliteFeatures");
+ public void requestIsSatelliteProvisioned(int subId, @NonNull ResultReceiver result) {
+ enforceSatelliteCommunicationPermission("requestIsSatelliteProvisioned");
+ if (!isSatelliteSupported()) {
+ result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
+ return;
+ }
final int validSubId = getValidSatelliteSubId(subId);
- if (!isSatelliteEnabled(validSubId)) {
- return SatelliteManager.SATELLITE_SERVICE_DISABLED;
- }
+ Bundle bundle = new Bundle();
+ bundle.putBoolean(SatelliteManager.KEY_SATELLITE_PROVISIONED,
+ isSatelliteProvisioned(validSubId));
+ result.send(SatelliteManager.SATELLITE_ERROR_NONE, bundle);
+ }
- final Phone phone = getPhoneOrDefault(validSubId, "getProvisionedSatelliteFeatures");
+ /**
+ * Register for listening to satellite state changes.
+ *
+ * @param subId The subId of the subscription to register for satellite modem state changes.
+ * @param callback The callback to handle the satellite state change event.
+ *
+ * @return The {@link SatelliteManager.SatelliteError} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ @SatelliteManager.SatelliteError public int registerForSatelliteModemStateChange(int subId,
+ @NonNull ISatelliteStateListener callback) {
+ enforceSatelliteCommunicationPermission("registerForSatelliteModemStateChange");
+
+ final int validSubId = getValidSatelliteSubId(subId);
+ Phone phone = getPhoneOrDefault(
+ validSubId, "registerForSatelliteModemStateChange");
if (phone == null) {
- return SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE;
+ return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
}
- int result = (int) sendRequest(
- CMD_GET_PROVISIONED_SATELLITE_FEATURES, callback, validSubId);
- if (DBG) log("getProvisionedSatelliteFeatures result: " + result);
+ SatelliteStateListenerHandler satelliteStateListenerHandler =
+ mSatelliteStateListenerHandlers.get(validSubId);
+ if (satelliteStateListenerHandler == null) {
+ satelliteStateListenerHandler = new SatelliteStateListenerHandler(
+ Looper.getMainLooper(), validSubId);
+ phone.registerForSatelliteModemStateChange(satelliteStateListenerHandler,
+ SatelliteStateListenerHandler.EVENT_SATELLITE_MODEM_STATE_CHANGE, null);
+ phone.registerForPendingMessageCount(satelliteStateListenerHandler,
+ SatelliteStateListenerHandler.EVENT_PENDING_MESSAGE_COUNT, null);
+ }
+
+ satelliteStateListenerHandler.addListener(callback);
+ mSatelliteStateListenerHandlers.put(validSubId, satelliteStateListenerHandler);
+ return SatelliteManager.SATELLITE_ERROR_NONE;
+ }
+
+ /**
+ * Unregister from listening to satellite state changes.
+ *
+ * @param subId The subId of the subscription to unregister for satellite modem state changes.
+ * @param callback The callback that was passed to
+ * {@link #registerForSatelliteModemStateChange(int, ISatelliteStateListener)}.
+ *
+ * @return The {@link SatelliteManager.SatelliteError} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ @SatelliteManager.SatelliteError public int unregisterForSatelliteModemStateChange(int subId,
+ @NonNull ISatelliteStateListener callback) {
+ enforceSatelliteCommunicationPermission("unregisterForSatelliteModemStateChange");
+
+ final int validSubId = getValidSatelliteSubId(subId);
+ SatelliteStateListenerHandler satelliteStateListenerHandler =
+ mSatelliteStateListenerHandlers.get(validSubId);
+ if (satelliteStateListenerHandler != null) {
+ if (satelliteStateListenerHandler.removeListener(callback)) {
+ return SatelliteManager.SATELLITE_ERROR_NONE;
+ }
+ }
+ return SatelliteManager.SATELLITE_INVALID_ARGUMENTS;
+ }
+
+ /**
+ * Register to receive incoming datagrams over satellite.
+ *
+ * @param subId The subId of the subscription to register for incoming satellite datagrams.
+ * @param datagramType Type of datagram.
+ * @param callback The callback to handle incoming datagrams over satellite.
+ *
+ * @return The {@link SatelliteManager.SatelliteError} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ @SatelliteManager.SatelliteError public int registerForSatelliteDatagram(int subId,
+ @SatelliteManager.DatagramType int datagramType,
+ @NonNull ISatelliteStateListener callback) {
+ enforceSatelliteCommunicationPermission("registerForSatelliteDatagram");
+
+ final int validSubId = getValidSatelliteSubId(subId);
+ Phone phone = getPhoneOrDefault(validSubId, "registerForSatelliteDatagram");
+ if (phone == null) {
+ return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+ }
+
+ SatelliteDatagramListenerHandler satelliteDatagramListenerHandler =
+ mSatelliteDatagramListenerHandlers.get(validSubId);
+ if (satelliteDatagramListenerHandler == null) {
+ satelliteDatagramListenerHandler = new SatelliteDatagramListenerHandler(
+ Looper.getMainLooper(), validSubId);
+ phone.registerForNewSatelliteDatagram(satelliteDatagramListenerHandler,
+ SatelliteDatagramListenerHandler.EVENT_SATELLITE_DATAGRAMS_RECEIVED, null);
+ }
+
+ satelliteDatagramListenerHandler.addListener(callback);
+ mSatelliteDatagramListenerHandlers.put(validSubId, satelliteDatagramListenerHandler);
+ return SatelliteManager.SATELLITE_ERROR_NONE;
+ }
+
+ /**
+ * Unregister to stop receiving incoming datagrams over satellite.
+ *
+ * @param subId The subId of the subscription to unregister for incoming satellite datagrams.
+ * @param callback The callback that was passed to
+ * {@link #registerForSatelliteDatagram(int, int, ISatelliteStateListener)}.
+ *
+ * @return The {@link SatelliteManager.SatelliteError} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ @SatelliteManager.SatelliteError public int unregisterForSatelliteDatagram(int subId,
+ @NonNull ISatelliteStateListener callback) {
+ enforceSatelliteCommunicationPermission("unregisterForSatelliteDatagram");
+
+ final int validSubId = getValidSatelliteSubId(subId);
+ SatelliteDatagramListenerHandler satelliteDatagramListenerHandler =
+ mSatelliteDatagramListenerHandlers.get(validSubId);
+ if (satelliteDatagramListenerHandler != null) {
+ if (satelliteDatagramListenerHandler.removeListener(callback)) {
+ return SatelliteManager.SATELLITE_ERROR_NONE;
+ }
+ }
+ return SatelliteManager.SATELLITE_INVALID_ARGUMENTS;
+ }
+
+ /**
+ * Poll pending satellite datagrams over satellite.
+ *
+ * @param subId The subId of the subscription to poll pending satellite datagrams for.
+ *
+ * @return The {@link SatelliteManager.SatelliteError} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override @SatelliteManager.SatelliteError public int pollPendingSatelliteDatagrams(int subId) {
+ enforceSatelliteCommunicationPermission("pollPendingSatelliteDatagrams");
+
+ final int validSubId = getValidSatelliteSubId(subId);
+ if (!isSatelliteProvisioned(validSubId)) {
+ return SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED;
+ }
+
+ Phone phone = getPhoneOrDefault(validSubId, "pollPendingSatelliteDatagrams");
+ if (phone == null) {
+ return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+ }
+
+ int result = (int) sendRequest(CMD_POLL_PENDING_SATELLITE_DATAGRAMS, null, validSubId);
+ if (DBG) log("pollPendingSatelliteDatagrams result: " + result);
return result;
}
+ /**
+ * Send datagram over satellite.
+ *
+ * @param subId The subId of the subscription to send satellite datagrams for.
+ * @param datagramType Type of datagram.
+ * @param datagram Datagram to send over satellite.
+ * @param callback The callback to get the error code of the request.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ public void sendSatelliteDatagram(int subId, @SatelliteManager.DatagramType int datagramType,
+ SatelliteDatagram datagram, IIntegerConsumer callback) {
+ enforceSatelliteCommunicationPermission("sendSatelliteDatagram");
+ Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
+
+ final int validSubId = getValidSatelliteSubId(subId);
+ if (!isSatelliteProvisioned(validSubId)) {
+ result.accept(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED);
+ return;
+ }
+
+ Phone phone = getPhoneOrDefault(validSubId, "sendSatelliteDatagram");
+ if (phone == null) {
+ result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+ return;
+ }
+
+ // check if we need to start PointingUI.
+
+ sendRequestAsync(CMD_SEND_SATELLITE_DATAGRAM,
+ new SendSatelliteDatagramArgument(datagramType, datagram, result),
+ phone, null);
+ }
+
+ /**
+ * Request to get whether satellite communication is allowed for the current location.
+ *
+ * @param subId The subId of the subscription to check whether satellite communication is
+ * allowed for the current location for.
+ * @param result The result receiver that returns whether satellite communication is allowed
+ * for the current location if the request is successful or an error code
+ * if the request failed.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ public void requestIsSatelliteCommunicationAllowedForCurrentLocation(int subId,
+ @NonNull ResultReceiver result) {
+ enforceSatelliteCommunicationPermission(
+ "requestIsSatelliteCommunicationAllowedForCurrentLocation");
+ if (!isSatelliteSupported()) {
+ result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
+ return;
+ }
+
+ final int validSubId = getValidSatelliteSubId(subId);
+ if (!isSatelliteProvisioned(validSubId)) {
+ result.send(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED, null);
+ return;
+ }
+
+ Phone phone = getPhoneOrDefault(validSubId,
+ "requestIsSatelliteCommunicationAllowedForCurrentLocation");
+ if (phone == null) {
+ result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+ return;
+ }
+
+ sendRequest(CMD_IS_SATELLITE_COMMUNICATION_ALLOWED, result, subId);
+ }
+
+ /**
+ * Request to get the time after which the satellite will next be visible
+ *
+ * @param subId The subId to get the time after which the satellite will next be visible for.
+ * @param result The result receiver that returns the time after which the satellite will next
+ * be visible if the request is successful or an error code if the request failed.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ public void requestTimeForNextSatelliteVisibility(int subId, @NonNull ResultReceiver result) {
+ enforceSatelliteCommunicationPermission("requestTimeForNextSatelliteVisibility");
+ if (!isSatelliteSupported()) {
+ result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
+ return;
+ }
+
+ final int validSubId = getValidSatelliteSubId(subId);
+ if (!isSatelliteProvisioned(validSubId)) {
+ result.send(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED, null);
+ return;
+ }
+
+ Phone phone = getPhoneOrDefault(validSubId, "requestTimeForNextSatelliteVisibility");
+ if (phone == null) {
+ result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+ return;
+ }
+
+ sendRequestAsync(CMD_GET_TIME_SATELLITE_NEXT_VISIBLE, result, phone, null);
+ }
+
private void handleCmdProvisionSatelliteService(@NonNull ProvisionSatelliteServiceArgument arg,
@NonNull Phone phone, Message onCompleted) {
- String callbackRemoteExErrorMessage =
- "handleCmdProvisionSatelliteService: callback not available.";
- if (arg == null) {
- loge("handleCmdProvisionSatelliteService: arg is null");
- return;
- }
- if (phone == null) {
- loge("handleCmdProvisionSatelliteService: phone is null");
- sendResponse(arg.callback, SatelliteManager.SATELLITE_SERVICE_INVALID_TELEPHONY_STATE,
- callbackRemoteExErrorMessage);
- return;
- }
-
if (!mSatelliteProvisionCallbacks.containsKey(arg.subId)) {
mSatelliteProvisionCallbacks.put(arg.subId, arg.callback);
- phone.provisionSatelliteService(onCompleted, phone.getImei(), phone.getMsisdn(),
- getSatelliteImsi(arg.subId), arg.features);
+ phone.provisionSatelliteService(onCompleted, arg.token);
} else {
- sendResponse(arg.callback, SatelliteManager.SATELLITE_SERVICE_PROVISION_IN_PROGRESS,
- callbackRemoteExErrorMessage);
+ arg.callback.accept(SatelliteManager.SATELLITE_SERVICE_PROVISION_IN_PROGRESS);
}
}
- private void handleEventProvisionSatelliteServiceDone(MainThreadRequest request) {
- final ProvisionSatelliteServiceArgument arg =
- (ProvisionSatelliteServiceArgument) request.argument;
- if (arg == null) {
- loge("handleEventProvisionSatelliteServiceDone: arg is null");
- return;
- }
+ private void handleEventProvisionSatelliteServiceDone(
+ @NonNull ProvisionSatelliteServiceArgument arg,
+ @SatelliteManager.SatelliteError int result) {
+ log("handleEventProvisionSatelliteServiceDone: result="
+ + result + ", subId=" + arg.subId);
- IIntegerConsumer callback = mSatelliteProvisionCallbacks.remove(arg.subId);
+ Consumer<Integer> callback = mSatelliteProvisionCallbacks.remove(arg.subId);
if (callback == null) {
loge("handleEventProvisionSatelliteServiceDone: callback is null for subId="
+ arg.subId);
return;
}
+ callback.accept(result);
- int result = (int) request.result;
- if (DBG) {
- log("handleEventProvisionSatelliteServiceDone: result="
- + result + ", subId=" + arg.subId);
- }
- sendResponse(callback, result,
- "handleEventProvisionSatelliteServiceDone: callback not available.");
-
- if (result == SatelliteManager.SATELLITE_SERVICE_SUCCESS) {
- setSatelliteEnabled(arg.subId, true);
+ if (result == SatelliteManager.SATELLITE_ERROR_NONE) {
+ setSatelliteProvisioned(arg.subId, true);
}
/**
@@ -13053,38 +13481,43 @@
* or SatelliteController.
* TODO (b/267826133) we need to do this for all subscriptions on the device.
*/
- registerForSatelliteProvisionStateChanged(arg.subId, null);
+ registerForSatelliteProvisionStateChangedInternal(arg.subId, null);
}
- private void handleCmdCancelProvisionSatelliteService(int subId, Message onCompleted) {
- final Phone phone = getPhoneOrDefault(
- subId, "handleCmdCancelProvisionSatelliteService");
- if (phone == null) {
+ private void handleCmdDeprovisionSatelliteService(
+ @NonNull ProvisionSatelliteServiceArgument arg, @NonNull Phone phone,
+ @NonNull Message onCompleted) {
+ if (arg == null) {
+ loge("handleCmdDeprovisionSatelliteService: arg is null");
return;
}
- phone.cancelProvisionSatelliteService(onCompleted, getSatelliteImsi(subId));
+ if (phone == null) {
+ loge("handleCmdDeprovisionSatelliteService: phone is null");
+ if (arg.callback != null) {
+ arg.callback.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+ }
+ return;
+ }
+ phone.deprovisionSatelliteService(onCompleted, arg.token);
}
- private void sendResponse(@NonNull IIntegerConsumer callback, int result, String message) {
- Objects.requireNonNull(callback);
-
- try {
- callback.accept(result);
- } catch (RemoteException e) {
- Log.w(LOG_TAG, message);
+ private void handleEventDeprovisionSatelliteServiceDone(
+ @NonNull ProvisionSatelliteServiceArgument arg,
+ @SatelliteManager.SatelliteError int result) {
+ if (arg == null) {
+ loge("handleEventDeprovisionSatelliteServiceDone: arg is null");
+ return;
}
- }
+ log("handleEventDeprovisionSatelliteServiceDone: result="
+ + result + ", subId=" + arg.subId);
- private String getSatelliteImsi(int subId) {
- if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
- return "";
+ if (arg.callback != null) {
+ arg.callback.accept(result);
}
- if (mSubscriptionController == null) {
- loge("getSatelliteImsi: mSubscriptionController is null");
- return "";
+ if (result == SatelliteManager.SATELLITE_ERROR_NONE) {
+ setSatelliteProvisioned(arg.subId, false);
}
- return mSubscriptionController.getImsiPrivileged(subId);
}
private Phone getPhoneOrDefault(int subId, String caller) {
@@ -13101,15 +13534,15 @@
}
/**
- * Check if satellite is enabled for a subscription.
+ * Check if satellite is provisioned for a subscription or the device.
*
* Note: this is the version without permission check for telephony internal use only. The
* caller need to take care of the permission check.
*/
- private boolean isSatelliteEnabled(int subId) {
+ private boolean isSatelliteProvisioned(int subId) {
if (subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
if (mSubscriptionController == null) {
- loge("setSatelliteEnabled mSubscriptionController is null");
+ loge("isSatelliteProvisioned mSubscriptionController is null");
return false;
}
@@ -13126,22 +13559,22 @@
}
/**
- * Set satellite enabled for a subscription.
+ * Set satellite provisioned for a subscription or the device.
*
* The permission {@link android.Manifest.permission#MODIFY_PHONE_STATE} will be enforced by
* {@link SubscriptionController} when setting satellite enabled for an active subscription.
* Otherwise, {@link android.Manifest.permission#SATELLITE_COMMUNICATION} will be enforced.
*/
- private void setSatelliteEnabled(int subId, boolean isEnabled) {
+ private synchronized void setSatelliteProvisioned(int subId, boolean isEnabled) {
if (subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
if (mSubscriptionController == null) {
- loge("setSatelliteEnabled mSubscriptionController is null");
+ loge("setSatelliteProvisioned mSubscriptionController is null");
return;
}
mSubscriptionController.setSubscriptionProperty(
subId, SubscriptionManager.SATELLITE_ENABLED, isEnabled ? "1" : "0");
} else {
- //TODO (b/267826133): enable via SatelliteController
+ //TODO (b/267826133): set via SatelliteController
}
}
@@ -13166,6 +13599,96 @@
}
/**
+ * If we have not successfully queried the satellite modem for its satellite service support,
+ * we will retry the query one more time. Otherwise, we will return the queried result.
+ */
+ private boolean isSatelliteSupported() {
+ synchronized (mIsSatelliteSupportedLock) {
+ if (mIsSatelliteSupported != null) {
+ /* We have already successfully queried the satellite modem. */
+ return mIsSatelliteSupported;
+ }
+ }
+ /**
+ * We have not successfully checked whether the modem supports satellite service.
+ * Thus, we need to retry it now.
+ */
+ requestIsSatelliteSupported(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+ mSatelliteSupportedReceiver);
+ return false;
+ }
+
+ /**
+ * Get the {@link SatelliteManager.SatelliteError} from the provided result.
+ *
+ * @param ar AsyncResult used to determine the error code.
+ * @param caller The satellite request.
+ * @param checkResult Whether to check if the result exists.
+ *
+ * @return The {@link SatelliteManager.SatelliteError} error code from the request.
+ */
+ @SatelliteManager.SatelliteError private int getSatelliteError(@NonNull AsyncResult ar,
+ @NonNull String caller, boolean checkResult) {
+ int errorCode;
+ if (ar.exception == null) {
+ errorCode = SatelliteManager.SATELLITE_ERROR_NONE;
+ if (checkResult && ar.result == null) {
+ loge(caller + ": result is null");
+ errorCode = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+ }
+ } else {
+ errorCode = SatelliteManager.SATELLITE_ERROR;
+ if (ar.exception instanceof CommandException) {
+ CommandException.Error error =
+ ((CommandException) (ar.exception)).getCommandError();
+ errorCode = RILUtils.convertToSatelliteError(error);
+ loge(caller + " CommandException: " + ar.exception);
+ } else {
+ loge(caller + " unknown exception: " + ar.exception);
+ }
+ }
+ log(caller + " error: " + errorCode);
+ return errorCode;
+ }
+
+ /**
+ * Register for the satellite provision state change.
+ *
+ * @param subId The subId of the subscription associated with the satellite service.
+ * @param callback The callback to handle the satellite provision state changed event.
+ *
+ * @return The {@link SatelliteManager.SatelliteError} result of the operation.
+ */
+ @SatelliteManager.SatelliteError private int registerForSatelliteProvisionStateChangedInternal(
+ int subId, @Nullable ISatelliteStateListener callback) {
+ if (!isSatelliteSupported()) {
+ return SatelliteManager.SATELLITE_NOT_SUPPORTED;
+ }
+
+ final int validSubId = getValidSatelliteSubId(subId);
+ Phone phone = getPhoneOrDefault(validSubId, "registerForSatelliteProvisionStateChanged");
+ if (phone == null) {
+ return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+ }
+
+ SatelliteProvisionStateChangedHandler satelliteProvisionStateChangedHandler =
+ mSatelliteProvisionStateChangedHandlers.get(validSubId);
+ if (satelliteProvisionStateChangedHandler == null) {
+ satelliteProvisionStateChangedHandler = new SatelliteProvisionStateChangedHandler(
+ Looper.getMainLooper(), validSubId);
+ phone.registerForSatelliteProvisionStateChanged(satelliteProvisionStateChangedHandler,
+ SatelliteProvisionStateChangedHandler.EVENT_PROVISION_STATE_CHANGED, null);
+ }
+
+ if (callback != null) {
+ satelliteProvisionStateChangedHandler.addListener(callback);
+ }
+ mSatelliteProvisionStateChangedHandlers.put(
+ validSubId, satelliteProvisionStateChangedHandler);
+ return SatelliteManager.SATELLITE_ERROR_NONE;
+ }
+
+ /**
* Check whether the caller (or self, if not processing an IPC) can read device identifiers.
*
* <p>This method behaves in one of the following ways:
@@ -13190,6 +13713,13 @@
}
/**
+ * @return The subscription manager service instance.
+ */
+ public SubscriptionManagerService getSubscriptionManagerService() {
+ return SubscriptionManagerService.getInstance();
+ }
+
+ /**
* Class binds the consumer[callback] and carrierId.
*/
private static class CallerCallbackInfo {
@@ -13209,4 +13739,14 @@
return mCarrierId;
}
}
-}
\ No newline at end of file
+
+ private static SatelliteDatagram[] convertToSatelliteDatagramArray(byte[][] datagrams) {
+ // Convert 2D byte array into SatelliteDatagramArray.
+ SatelliteDatagram[] satelliteDatagramArray =
+ new SatelliteDatagram[datagrams.length];
+ for (int i = 0; i < datagrams.length; i++) {
+ satelliteDatagramArray[i] = new SatelliteDatagram(datagrams[i]);
+ }
+ return satelliteDatagramArray;
+ }
+}
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 519655e..2c43c7f 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -593,38 +593,36 @@
new DomainSelectionConnection.DomainSelectionConnectionCallback() {
@Override
public void onSelectionTerminated(@DisconnectCauses int cause) {
- if (mEmergencyCallDomainSelectionConnection != null) {
+ mDomainSelectionMainExecutor.execute(() -> {
Log.i(this, "onSelectionTerminated cause=" + cause);
+ if (mEmergencyCallDomainSelectionConnection == null) {
+ Log.i(this, "onSelectionTerminated no DomainSelectionConnection");
+ return;
+ }
// Cross stack redial
if (cause == android.telephony.DisconnectCause.EMERGENCY_TEMP_FAILURE
|| cause == android.telephony.DisconnectCause.EMERGENCY_PERM_FAILURE) {
if (mEmergencyConnection != null) {
- final boolean isPermanentFailure =
+ boolean isPermanentFailure =
cause == android.telephony.DisconnectCause.EMERGENCY_PERM_FAILURE;
- Log.i(this, "onSelectionTerminated trigger cross stack redial"
- + " permanent=" + isPermanentFailure);
- mDomainSelectionMainExecutor.execute(() -> {
- Log.i(this, "onSelectionTerminated execute cross stack redial"
- + " permanent=" + isPermanentFailure);
- TelephonyConnection c = mEmergencyConnection;
- Phone phone = mEmergencyCallDomainSelectionConnection.getPhone();
- mEmergencyConnection.removeTelephonyConnectionListener(
- mEmergencyConnectionListener);
- mEmergencyStateTracker.endCall(
- mEmergencyConnection.getTelecomCallId());
- releaseEmergencyCallDomainSelection(true);
- retryOutgoingOriginalConnection(c, phone, isPermanentFailure);
- });
+ Log.i(this, "onSelectionTerminated permanent=" + isPermanentFailure);
+ TelephonyConnection c = mEmergencyConnection;
+ Phone phone = mEmergencyCallDomainSelectionConnection.getPhone();
+ mEmergencyConnection.removeTelephonyConnectionListener(
+ mEmergencyConnectionListener);
+ releaseEmergencyCallDomainSelection(true);
+ mEmergencyStateTracker.endCall(mEmergencyCallId);
+ mEmergencyCallId = null;
+ retryOutgoingOriginalConnection(c, phone, isPermanentFailure);
return;
}
}
- mEmergencyCallDomainSelectionConnection = null;
if (mEmergencyConnection != null) {
mEmergencyConnection.hangup(android.telephony.DisconnectCause.OUT_OF_NETWORK);
mEmergencyConnection = null;
}
- }
+ });
}
};
@@ -2386,9 +2384,9 @@
Log.i(this, "maybeReselectDomainForEmergencyCall endCall()");
c.removeTelephonyConnectionListener(mEmergencyConnectionListener);
- mEmergencyStateTracker.endCall(c.getTelecomCallId());
releaseEmergencyCallDomainSelection(true);
-
+ mEmergencyStateTracker.endCall(c.getTelecomCallId());
+ mEmergencyCallId = null;
return false;
}
@@ -2410,7 +2408,7 @@
+ ", psCause:" + reasonInfo);
if (mDomainSelectionConnection != null && c.getOriginalConnection() != null) {
- Phone phone = c.getPhone();
+ Phone phone = c.getPhone().getDefaultPhone();
final String number = c.getAddress().getSchemeSpecificPart();
int videoState = c.getOriginalConnection().getVideoState();
SelectionAttributes selectionAttributes = NormalCallDomainSelectionConnection
@@ -2424,7 +2422,7 @@
.reselectDomain(selectionAttributes);
if (future != null) {
future.thenAcceptAsync((result) -> {
- onNormalCallRedial(c, result, videoState);
+ onNormalCallRedial(c, phone, result, videoState);
}, mDomainSelectionMainExecutor);
return true;
}
@@ -2598,14 +2596,13 @@
onEmergencyRedialOnDomain(connection, phone, result);
}
- private void onNormalCallRedial(TelephonyConnection connection,
+ private void onNormalCallRedial(TelephonyConnection connection, Phone phone,
@NetworkRegistrationInfo.Domain int domain, int videocallState) {
Log.v(LOG_TAG, "Redialing the call in domain:"
+ DomainSelectionService.getDomainName(domain));
String number = connection.getAddress().getSchemeSpecificPart();
- Phone phone = connection.getPhone();
Bundle extras = new Bundle();
extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, domain);
@@ -2647,8 +2644,8 @@
if (TextUtils.equals(mEmergencyCallId, c.getTelecomCallId())) {
Log.i(this, "onLocalHangup " + mEmergencyCallId);
c.removeTelephonyConnectionListener(mEmergencyConnectionListener);
- mEmergencyStateTracker.endCall(c.getTelecomCallId());
releaseEmergencyCallDomainSelection(true);
+ mEmergencyStateTracker.endCall(c.getTelecomCallId());
mEmergencyCallId = null;
}
}
diff --git a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
index e8825be..a23d0b7 100644
--- a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
@@ -255,7 +255,7 @@
if (result.getAccessNetwork() == UNKNOWN) {
if ((mPreferredNetworkScanType == SCAN_TYPE_FULL_SERVICE_FOLLOWED_BY_LIMITED_SERVICE)
- || (mScanType == DomainSelectionService.SCAN_TYPE_FULL_SERVICE)) {
+ && (mScanType == DomainSelectionService.SCAN_TYPE_FULL_SERVICE)) {
mScanType = DomainSelectionService.SCAN_TYPE_LIMITED_SERVICE;
mWwanSelectorCallback.onRequestEmergencyNetworkScan(
mLastPreferredNetworks, mScanType, mCancelSignal,
diff --git a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
index 4cc793d..e702279 100644
--- a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
+++ b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
@@ -21,7 +21,6 @@
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
@@ -42,9 +41,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.TelephonyTestBase;
+import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.IIntegerConsumer;
+import com.android.internal.telephony.subscription.SubscriptionManagerService;
import org.junit.Before;
import org.junit.Test;
@@ -54,7 +54,7 @@
import java.util.Locale;
/**
- * Unit Test for CarrierConfigLoader.
+ * Unit Test for PhoneInterfaceManager.
*/
@RunWith(AndroidJUnit4.class)
public class PhoneInterfaceManagerTest extends TelephonyTestBase {
@@ -67,6 +67,9 @@
@Mock
Phone mPhone;
+ @Mock
+ private SubscriptionManagerService mSubscriptionManagerService;
+
@Before
@UiThreadTest
public void setUp() throws Exception {
@@ -76,6 +79,9 @@
// alive on a test devices. You must use the spy to mock behavior. Mocks stemming from the
// passed context will remain unused.
mPhoneInterfaceManager = spy(PhoneInterfaceManager.init(mPhoneGlobals));
+ doReturn(mSubscriptionManagerService).when(mPhoneInterfaceManager)
+ .getSubscriptionManagerService();
+ TelephonyManager.setupISubForTest(mSubscriptionManagerService);
mSharedPreferences = mPhoneInterfaceManager.getSharedPreferences();
mSharedPreferences.edit().remove(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED).commit();
mIIntegerConsumer = mock(IIntegerConsumer.class);
diff --git a/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java b/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
index 8b0ac5c..817220c 100644
--- a/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
+++ b/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.service.euicc.EuiccService;
import android.telephony.euicc.EuiccManager;
import androidx.test.InstrumentationRegistry;
@@ -111,6 +112,24 @@
assertEquals("bar", euiccUiIntent.getStringExtra("foo"));
}
+ @Test
+ public void testTransferEmbeddedSubscriptionsAction() {
+ mIntent = new Intent(EuiccManager.ACTION_TRANSFER_EMBEDDED_SUBSCRIPTIONS);
+ Intent euiccUiIntent = mActivity.resolveEuiccUiIntent();
+ assertNotNull(euiccUiIntent);
+ assertEquals(EuiccService.ACTION_TRANSFER_EMBEDDED_SUBSCRIPTIONS,
+ euiccUiIntent.getAction());
+ }
+
+ @Test
+ public void testConvertToEmbeddedSubscriptionAction() {
+ mIntent = new Intent(EuiccManager.ACTION_CONVERT_TO_EMBEDDED_SUBSCRIPTION);
+ Intent euiccUiIntent = mActivity.resolveEuiccUiIntent();
+ assertNotNull(euiccUiIntent);
+ assertEquals(EuiccService.ACTION_CONVERT_TO_EMBEDDED_SUBSCRIPTION,
+ euiccUiIntent.getAction());
+ }
+
class TestEuiccUiDispatcherActivity extends EuiccUiDispatcherActivity {
public TestEuiccUiDispatcherActivity() {
attachBaseContext(mMockContext);
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 61060d9..4826d89 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -18,6 +18,7 @@
import static android.telephony.DisconnectCause.EMERGENCY_PERM_FAILURE;
import static android.telephony.DisconnectCause.EMERGENCY_TEMP_FAILURE;
+import static android.telephony.DisconnectCause.ERROR_UNSPECIFIED;
import static android.telephony.DisconnectCause.NOT_DISCONNECTED;
import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
import static android.telephony.NetworkRegistrationInfo.DOMAIN_CS;
@@ -1952,6 +1953,40 @@
}
@Test
+ public void testOnSelectionTerminatedUnspecified() throws Exception {
+ setupForCallTest();
+
+ doReturn(mEmergencyCallDomainSelectionConnection).when(mDomainSelectionResolver)
+ .getDomainSelectionConnection(any(), anyInt(), eq(true));
+ doReturn(mPhone0).when(mEmergencyCallDomainSelectionConnection).getPhone();
+ doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString());
+
+ doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported();
+ doReturn(mImsPhone).when(mPhone0).getImsPhone();
+
+ mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+ createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
+ TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
+
+ ArgumentCaptor<DomainSelectionConnection.DomainSelectionConnectionCallback> callbackCaptor =
+ ArgumentCaptor.forClass(
+ DomainSelectionConnection.DomainSelectionConnectionCallback.class);
+
+ verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(
+ any(), callbackCaptor.capture());
+
+ DomainSelectionConnection.DomainSelectionConnectionCallback callback =
+ callbackCaptor.getValue();
+
+ assertNotNull(callback);
+
+ callback.onSelectionTerminated(ERROR_UNSPECIFIED);
+
+ verify(mEmergencyCallDomainSelectionConnection).cancelSelection();
+ verify(mEmergencyStateTracker).endCall(eq(TELECOM_CALL_ID1));
+ }
+
+ @Test
public void testDomainSelectionLocalHangupStartEmergencyCall() throws Exception {
setupForCallTest();
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
index 7649f5a..673e586 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
@@ -38,6 +38,8 @@
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_VOWIFI_REQUIRES_CONDITION_INT;
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_MAXIMUM_NUMBER_OF_EMERGENCY_TRIES_OVER_VOWIFI_INT;
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.SCAN_TYPE_FULL_SERVICE;
+import static android.telephony.CarrierConfigManager.ImsEmergency.SCAN_TYPE_FULL_SERVICE_FOLLOWED_BY_LIMITED_SERVICE;
import static android.telephony.CarrierConfigManager.ImsEmergency.SCAN_TYPE_NO_PREFERENCE;
import static android.telephony.CarrierConfigManager.ImsEmergency.VOWIFI_REQUIRES_NONE;
import static android.telephony.CarrierConfigManager.ImsEmergency.VOWIFI_REQUIRES_SETTING_ENABLED;
@@ -1167,6 +1169,67 @@
}
@Test
+ public void testFullService() throws Exception {
+ PersistableBundle bundle = getDefaultPersistableBundle();
+ bundle.putInt(KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT, SCAN_TYPE_FULL_SERVICE);
+ when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+ mResultConsumer = null;
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(true);
+
+ EmergencyRegResult regResult = getEmergencyRegResult(UNKNOWN, REGISTRATION_STATE_UNKNOWN,
+ 0, false, false, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+ processAllMessages();
+
+ verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+ any(), eq(DomainSelectionService.SCAN_TYPE_FULL_SERVICE), any(), any());
+ assertNotNull(mResultConsumer);
+
+ mResultConsumer.accept(regResult);
+ processAllMessages();
+
+ verify(mWwanSelectorCallback, times(2)).onRequestEmergencyNetworkScan(
+ any(), eq(DomainSelectionService.SCAN_TYPE_FULL_SERVICE), any(), any());
+ }
+
+ @Test
+ public void testFullServiceThenLimtedService() throws Exception {
+ PersistableBundle bundle = getDefaultPersistableBundle();
+ bundle.putInt(KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT,
+ SCAN_TYPE_FULL_SERVICE_FOLLOWED_BY_LIMITED_SERVICE);
+ when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+ mResultConsumer = null;
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(true);
+
+ EmergencyRegResult regResult = getEmergencyRegResult(UNKNOWN, REGISTRATION_STATE_UNKNOWN,
+ 0, false, false, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+ processAllMessages();
+
+ verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+ any(), eq(DomainSelectionService.SCAN_TYPE_FULL_SERVICE), any(), any());
+ assertNotNull(mResultConsumer);
+
+ mResultConsumer.accept(regResult);
+ processAllMessages();
+
+ verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+ any(), eq(DomainSelectionService.SCAN_TYPE_LIMITED_SERVICE), any(), any());
+ }
+
+ @Test
public void testCsThenPsPreference() throws Exception {
PersistableBundle bundle = getDefaultPersistableBundle();
int[] domainPreference = new int[] {