Merge "Update team owners." into main am: 4e7770f770 am: 722cb04bec am: 1a6b133783 am: e03fb103db
Original change: https://android-review.googlesource.com/c/platform/packages/services/Telephony/+/2716016
Change-Id: I7d0273cb96adf671b8f83bf7f1231c246d33ed1a
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/src/com/android/phone/settings/RadioInfo.java b/src/com/android/phone/settings/RadioInfo.java
index 124badf..59ff11d 100644
--- a/src/com/android/phone/settings/RadioInfo.java
+++ b/src/com/android/phone/settings/RadioInfo.java
@@ -207,6 +207,7 @@
private static final int EVENT_QUERY_SMSC_DONE = 1005;
private static final int EVENT_UPDATE_SMSC_DONE = 1006;
private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 1007;
+ private static final int EVENT_UPDATE_NR_STATS = 1008;
private static final int MENU_ITEM_VIEW_ADN = 1;
private static final int MENU_ITEM_VIEW_FDN = 2;
@@ -379,7 +380,14 @@
updateNetworkType();
updateRawRegistrationState(serviceState);
updateImsProvisionedState();
- updateNrStats(serviceState);
+
+ // Since update NR stats includes a ril message to get slicing information, it runs
+ // as blocking during the timeout period of 1 second. if ServiceStateChanged event
+ // fires consecutively, RadioInfo can run for more than 10 seconds. This can cause ANR.
+ // Therefore, send event only when there is no same event being processed.
+ if (!mHandler.hasMessages(EVENT_UPDATE_NR_STATS)) {
+ mHandler.obtainMessage(EVENT_UPDATE_NR_STATS).sendToTarget();
+ }
}
@Override
@@ -465,6 +473,10 @@
}
updatePhysicalChannelConfiguration((List<PhysicalChannelConfig>) ar.result);
break;
+ case EVENT_UPDATE_NR_STATS:
+ log("got EVENT_UPDATE_NR_STATS");
+ updateNrStats();
+ break;
default:
super.handleMessage(msg);
break;
@@ -690,7 +702,7 @@
updateProperties();
updateDnsCheckState();
updateNetworkType();
- updateNrStats(null);
+ updateNrStats();
updateCellInfo(mCellInfoResult);
updateSubscriptionIds();
@@ -1235,15 +1247,12 @@
AccessNetworkConstants.TRANSPORT_TYPE_WLAN));
}
- private void updateNrStats(ServiceState serviceState) {
+ private void updateNrStats() {
if ((mTelephonyManager.getSupportedRadioAccessFamily()
& TelephonyManager.NETWORK_TYPE_BITMASK_NR) == 0) {
return;
}
- ServiceState ss = serviceState;
- if (ss == null && mPhone != null) {
- ss = mPhone.getServiceState();
- }
+ ServiceState ss = (mPhone == null) ? null : mPhone.getServiceState();
if (ss != null) {
NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
@@ -1257,6 +1266,13 @@
}
mNrState.setText(NetworkRegistrationInfo.nrStateToString(ss.getNrState()));
mNrFrequency.setText(ServiceState.frequencyRangeToString(ss.getNrFrequencyRange()));
+ } else {
+ Log.e(TAG, "Clear Nr stats by null service state");
+ mEndcAvailable.setText("");
+ mDcnrRestricted.setText("");
+ mNrAvailable.setText("");
+ mNrState.setText("");
+ mNrFrequency.setText("");
}
CompletableFuture<NetworkSlicingConfig> resultFuture = new CompletableFuture<>();
diff --git a/src/com/android/phone/slice/PremiumNetworkEntitlementApi.java b/src/com/android/phone/slice/PremiumNetworkEntitlementApi.java
index d5ef816..3bfe1a4 100644
--- a/src/com/android/phone/slice/PremiumNetworkEntitlementApi.java
+++ b/src/com/android/phone/slice/PremiumNetworkEntitlementApi.java
@@ -46,6 +46,7 @@
private static final String PROVISION_STATUS_KEY = "ProvStatus";
private static final String SERVICE_FLOW_URL_KEY = "ServiceFlow_URL";
private static final String SERVICE_FLOW_USERDATA_KEY = "ServiceFlow_UserData";
+ private static final String SERVICE_FLOW_CONTENTS_TYPE_KEY = "ServiceFlow_ContentsType";
private static final String DEFAULT_EAP_AKA_RESPONSE = "Default EAP AKA response";
/**
* UUID to report an anomaly if an unexpected error is received during entitlement check.
@@ -120,13 +121,11 @@
}
try {
JSONObject jsonAuthResponse = new JSONObject(response);
- String entitlementStatus = null;
- String provisionStatus = null;
if (jsonAuthResponse.has(ServiceEntitlement.APP_DATA_PLAN_BOOST)) {
JSONObject jsonToken = jsonAuthResponse.getJSONObject(
ServiceEntitlement.APP_DATA_PLAN_BOOST);
if (jsonToken.has(ENTITLEMENT_STATUS_KEY)) {
- entitlementStatus = jsonToken.getString(ENTITLEMENT_STATUS_KEY);
+ String entitlementStatus = jsonToken.getString(ENTITLEMENT_STATUS_KEY);
if (entitlementStatus == null) {
return null;
}
@@ -134,7 +133,7 @@
Integer.parseInt(entitlementStatus);
}
if (jsonToken.has(PROVISION_STATUS_KEY)) {
- provisionStatus = jsonToken.getString(PROVISION_STATUS_KEY);
+ String provisionStatus = jsonToken.getString(PROVISION_STATUS_KEY);
if (provisionStatus != null) {
premiumNetworkEntitlementResponse.mProvisionStatus =
Integer.parseInt(provisionStatus);
@@ -148,6 +147,10 @@
premiumNetworkEntitlementResponse.mServiceFlowUserData =
jsonToken.getString(SERVICE_FLOW_USERDATA_KEY);
}
+ if (jsonToken.has(SERVICE_FLOW_CONTENTS_TYPE_KEY)) {
+ premiumNetworkEntitlementResponse.mServiceFlowContentsType =
+ jsonToken.getString(SERVICE_FLOW_CONTENTS_TYPE_KEY);
+ }
} else {
Log.e(TAG, "queryEntitlementStatus failed with no app");
}
diff --git a/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java b/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java
index ba44581..9126244 100644
--- a/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java
+++ b/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java
@@ -25,19 +25,19 @@
*
* The relationship between entitlement status (left column) and provision status (top row)
* is defined in the table below:
- * +--------------+-----------------+-------------------+-------------------+---------------+
- * | | Not Provisioned | Provisioned | Not Available | In Progress |
- * +--------------+-----------------+-------------------+-------------------+---------------+
- * | Disabled | Check failed | Check failed | Check failed | Check failed |
- * +--------------+-----------------+-------------------+-------------------+---------------+
- * | Enabled | Carrier error | Display webview | Display webview | Carrier error |
- * +--------------+-----------------+-------------------+-------------------+---------------+
- * | Incompatible | Check failed | Check failed | Check failed | Check failed |
- * +--------------+-----------------+-------------------+-------------------+---------------+
- * | Provisioning | Carrier error | Carrier error | In Progress | In Progress |
- * +--------------+-----------------+-------------------+-------------------+---------------+
- * | Included | Carrier error | Already purchased | Already purchased | Carrier error |
- * +--------------+-----------------+-------------------+-------------------+---------------+
+ * +--------------+-----------------+-------------------+-------------------+-----------------+
+ * | | Not Provisioned | Provisioned | Not Available | In Progress |
+ * +--------------+-----------------+-------------------+-------------------+-----------------+
+ * | Disabled | Check failed | Check failed | Check failed | Check failed |
+ * +--------------+-----------------+-------------------+-------------------+-----------------+
+ * | Enabled | Display webview | Already purchased | Already purchased | In progress |
+ * +--------------+-----------------+-------------------+-------------------+-----------------+
+ * | Incompatible | Check failed | Check failed | Check failed | Check failed |
+ * +--------------+-----------------+-------------------+-------------------+-----------------+
+ * | Provisioning | Carrier error | Carrier error | In progress | In progress |
+ * +--------------+-----------------+-------------------+-------------------+-----------------+
+ * | Included | Carrier error | Already purchased | Already purchased | Carrier error |
+ * +--------------+-----------------+-------------------+-------------------+-----------------+
*/
public class PremiumNetworkEntitlementResponse {
public static final int PREMIUM_NETWORK_ENTITLEMENT_STATUS_DISABLED = 0;
@@ -72,13 +72,19 @@
@PremiumNetworkProvisionStatus public int mProvisionStatus;
@NonNull public String mServiceFlowURL;
@NonNull public String mServiceFlowUserData;
+ @NonNull public String mServiceFlowContentsType;
/**
- * @return {@code true} if the premium network is provisioned and {@code false} otherwise.
+ * @return {@code true} if the premium network is already purchased and {@code false} otherwise.
*/
- public boolean isProvisioned() {
- return !isInvalidResponse()
- && mEntitlementStatus == PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCLUDED;
+ public boolean isAlreadyPurchased() {
+ switch (mEntitlementStatus) {
+ case PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED:
+ case PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCLUDED:
+ return mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_PROVISIONED
+ || mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_NOT_AVAILABLE;
+ }
+ return false;
}
/**
@@ -86,8 +92,14 @@
* {@code false} otherwise.
*/
public boolean isProvisioningInProgress() {
- return !isInvalidResponse()
- && mEntitlementStatus == PREMIUM_NETWORK_ENTITLEMENT_STATUS_PROVISIONING;
+ switch (mEntitlementStatus) {
+ case PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED:
+ return mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_IN_PROGRESS;
+ case PREMIUM_NETWORK_ENTITLEMENT_STATUS_PROVISIONING:
+ return mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_IN_PROGRESS
+ || mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_NOT_AVAILABLE;
+ }
+ return false;
}
/**
@@ -108,7 +120,6 @@
*/
public boolean isInvalidResponse() {
switch (mEntitlementStatus) {
- case PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED:
case PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCLUDED:
return mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_NOT_PROVISIONED
|| mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_IN_PROGRESS;
@@ -123,6 +134,7 @@
@NonNull public String toString() {
return "PremiumNetworkEntitlementResponse{mEntitlementStatus=" + mEntitlementStatus
+ ", mProvisionStatus=" + mProvisionStatus + ", mServiceFlowURL=" + mServiceFlowURL
- + ", mServiceFlowUserData" + mServiceFlowUserData + "}";
+ + ", mServiceFlowUserData=" + mServiceFlowUserData + ", mServiceFlowContentsType="
+ + mServiceFlowContentsType + "}";
}
}
diff --git a/src/com/android/phone/slice/SlicePurchaseController.java b/src/com/android/phone/slice/SlicePurchaseController.java
index b1abe56..4984b23 100644
--- a/src/com/android/phone/slice/SlicePurchaseController.java
+++ b/src/com/android/phone/slice/SlicePurchaseController.java
@@ -48,6 +48,9 @@
import android.telephony.TelephonyManager;
import android.telephony.data.NetworkSliceInfo;
import android.telephony.data.NetworkSlicingConfig;
+import android.telephony.data.RouteSelectionDescriptor;
+import android.telephony.data.TrafficDescriptor;
+import android.telephony.data.UrspRule;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.URLUtil;
@@ -92,12 +95,15 @@
public static final int FAILURE_CODE_UNKNOWN = 0;
/** Performance boost purchase failed because the carrier URL is unavailable. */
public static final int FAILURE_CODE_CARRIER_URL_UNAVAILABLE = 1;
- /** Performance boost purchase failed because the server is unreachable. */
- public static final int FAILURE_CODE_SERVER_UNREACHABLE = 2;
/** Performance boost purchase failed because user authentication failed. */
- public static final int FAILURE_CODE_AUTHENTICATION_FAILED = 3;
+ public static final int FAILURE_CODE_AUTHENTICATION_FAILED = 2;
/** Performance boost purchase failed because the payment failed. */
- public static final int FAILURE_CODE_PAYMENT_FAILED = 4;
+ public static final int FAILURE_CODE_PAYMENT_FAILED = 3;
+ /**
+ * Performance boost purchase failed because the content type was specified but
+ * user data does not exist.
+ */
+ public static final int FAILURE_CODE_NO_USER_DATA = 4;
/**
* Failure codes that the carrier website can return when a premium capability purchase fails.
@@ -106,9 +112,9 @@
@IntDef(prefix = { "FAILURE_CODE_" }, value = {
FAILURE_CODE_UNKNOWN,
FAILURE_CODE_CARRIER_URL_UNAVAILABLE,
- FAILURE_CODE_SERVER_UNREACHABLE,
FAILURE_CODE_AUTHENTICATION_FAILED,
- FAILURE_CODE_PAYMENT_FAILED})
+ FAILURE_CODE_PAYMENT_FAILED,
+ FAILURE_CODE_NO_USER_DATA})
public @interface FailureCode {}
/** Value for an invalid premium capability. */
@@ -177,6 +183,12 @@
private static final String ACTION_SLICE_PURCHASE_APP_RESPONSE_NOT_DEFAULT_DATA_SUBSCRIPTION =
"com.android.phone.slice.action."
+ "SLICE_PURCHASE_APP_RESPONSE_NOT_DEFAULT_DATA_SUBSCRIPTION";
+ /**
+ * Action indicating the performance boost notification was not shown because the user
+ * disabled notifications for the application or channel.
+ */
+ private static final String ACTION_SLICE_PURCHASE_APP_RESPONSE_NOTIFICATIONS_DISABLED =
+ "com.android.phone.slice.action.SLICE_PURCHASE_APP_RESPONSE_NOTIFICATIONS_DISABLED";
/** Action indicating the purchase request was successful. */
private static final String ACTION_SLICE_PURCHASE_APP_RESPONSE_SUCCESS =
"com.android.phone.slice.action.SLICE_PURCHASE_APP_RESPONSE_SUCCESS";
@@ -209,6 +221,8 @@
public static final String EXTRA_CARRIER = "com.android.phone.slice.extra.CARRIER";
/** Extra for the user data received from the entitlement service to send to the webapp. */
public static final String EXTRA_USER_DATA = "com.android.phone.slice.extra.USER_DATA";
+ /** Extra for the contents type received from the entitlement service to send to the webapp. */
+ public static final String EXTRA_CONTENTS_TYPE = "com.android.phone.slice.extra.CONTENTS_TYPE";
/**
* Extra for the canceled PendingIntent that the slice purchase application can send as a
* response if the performance boost notification or WebView was canceled by the user.
@@ -242,6 +256,14 @@
public static final String EXTRA_INTENT_NOT_DEFAULT_DATA_SUBSCRIPTION =
"com.android.phone.slice.extra.INTENT_NOT_DEFAULT_DATA_SUBSCRIPTION";
/**
+ * Extra for the notifications disabled PendingIntent that the slice purchase application can
+ * send as a response if the premium capability purchase request failed because the user
+ * disabled notifications for the application or channel.
+ * Sends {@link #ACTION_SLICE_PURCHASE_APP_RESPONSE_NOTIFICATIONS_DISABLED}.
+ */
+ public static final String EXTRA_INTENT_NOTIFICATIONS_DISABLED =
+ "com.android.phone.slice.extra.INTENT_NOTIFICATIONS_DISABLED";
+ /**
* Extra for the success PendingIntent that the slice purchase application can send as a
* response if the premium capability purchase request was successful.
* Sends {@link #ACTION_SLICE_PURCHASE_APP_RESPONSE_SUCCESS}.
@@ -320,7 +342,7 @@
/**
* Create a SlicePurchaseControllerBroadcastReceiver for the given capability
*
- * @param capability The requested capability to listen to response for.
+ * @param capability The requested premium capability to listen to response for.
*/
SlicePurchaseControllerBroadcastReceiver(
@TelephonyManager.PremiumCapability int capability) {
@@ -391,6 +413,16 @@
false);
break;
}
+ case ACTION_SLICE_PURCHASE_APP_RESPONSE_NOTIFICATIONS_DISABLED: {
+ logd("Slice purchase application unable to show notification for capability: "
+ + TelephonyManager.convertPremiumCapabilityToString(capability)
+ + " because the user has disabled notifications.");
+ SlicePurchaseController.getInstance(phoneId)
+ .handlePurchaseResult(capability,
+ TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_DISABLED,
+ true);
+ break;
+ }
case ACTION_SLICE_PURCHASE_APP_RESPONSE_SUCCESS: {
long duration = intent.getLongExtra(EXTRA_PURCHASE_DURATION, 0);
SlicePurchaseController.getInstance(phoneId).onCarrierSuccess(
@@ -475,6 +507,17 @@
mLocalDate = localDate;
}
+ /**
+ * Set the NetworkSlicingConfig to use for determining whether the premium capability was
+ * successfully set up on the carrier network.
+ *
+ * @param slicingConfig The LocalDate instance to use.
+ */
+ @VisibleForTesting
+ public void setSlicingConfig(@NonNull NetworkSlicingConfig slicingConfig) {
+ mSlicingConfig = slicingConfig;
+ }
+
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
@@ -488,7 +531,8 @@
case EVENT_SLICING_CONFIG_CHANGED: {
AsyncResult ar = (AsyncResult) msg.obj;
NetworkSlicingConfig config = (NetworkSlicingConfig) ar.result;
- logd("EVENT_SLICING_CONFIG_CHANGED: from " + mSlicingConfig + " to " + config);
+ logd("EVENT_SLICING_CONFIG_CHANGED: previous= " + mSlicingConfig);
+ logd("EVENT_SLICING_CONFIG_CHANGED: current= " + config);
mSlicingConfig = config;
onSlicingConfigChanged();
break;
@@ -690,6 +734,17 @@
private void onStartSlicePurchaseApplication(
@TelephonyManager.PremiumCapability int capability) {
+ updateNotificationCounts();
+ if (mMonthlyCount >= getCarrierConfigs().getInt(
+ CarrierConfigManager.KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT)
+ || mDailyCount >= getCarrierConfigs().getInt(
+ CarrierConfigManager.KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT)) {
+ logd("Reached maximum number of performance boost notifications.");
+ handlePurchaseResult(capability,
+ TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED, false);
+ return;
+ }
+
final PremiumNetworkEntitlementApi premiumNetworkEntitlementApi =
getPremiumNetworkEntitlementApi();
PremiumNetworkEntitlementResponse premiumNetworkEntitlementResponse =
@@ -711,8 +766,8 @@
return;
}
- if (premiumNetworkEntitlementResponse.isProvisioned()) {
- logd("Entitlement Check: Already provisioned.");
+ if (premiumNetworkEntitlementResponse.isAlreadyPurchased()) {
+ logd("Entitlement Check: Already purchased/provisioned.");
handlePurchaseResult(capability,
PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED, true);
return;
@@ -725,7 +780,6 @@
return;
}
- String userData = premiumNetworkEntitlementResponse.mServiceFlowUserData;
String purchaseUrl = getPurchaseUrl(premiumNetworkEntitlementResponse);
String carrier = getSimOperator();
if (TextUtils.isEmpty(purchaseUrl) || TextUtils.isEmpty(carrier)) {
@@ -734,17 +788,6 @@
return;
}
- updateNotificationCounts();
- if (mMonthlyCount >= getCarrierConfigs().getInt(
- CarrierConfigManager.KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT)
- || mDailyCount >= getCarrierConfigs().getInt(
- CarrierConfigManager.KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT)) {
- logd("Reached maximum number of performance boost notifications.");
- handlePurchaseResult(capability,
- TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED, false);
- return;
- }
-
// Start timeout for purchase completion.
long timeout = getCarrierConfigs().getLong(CarrierConfigManager
.KEY_PREMIUM_CAPABILITY_NOTIFICATION_DISPLAY_TIMEOUT_MILLIS_LONG);
@@ -761,9 +804,9 @@
intent.putExtra(EXTRA_PREMIUM_CAPABILITY, capability);
intent.putExtra(EXTRA_PURCHASE_URL, purchaseUrl);
intent.putExtra(EXTRA_CARRIER, carrier);
- if (!TextUtils.isEmpty(userData)) {
- intent.putExtra(EXTRA_USER_DATA, userData);
- }
+ intent.putExtra(EXTRA_USER_DATA, premiumNetworkEntitlementResponse.mServiceFlowUserData);
+ intent.putExtra(EXTRA_CONTENTS_TYPE,
+ premiumNetworkEntitlementResponse.mServiceFlowContentsType);
intent.putExtra(EXTRA_INTENT_CANCELED, createPendingIntent(
ACTION_SLICE_PURCHASE_APP_RESPONSE_CANCELED, capability, false));
intent.putExtra(EXTRA_INTENT_CARRIER_ERROR, createPendingIntent(
@@ -773,6 +816,8 @@
intent.putExtra(EXTRA_INTENT_NOT_DEFAULT_DATA_SUBSCRIPTION, createPendingIntent(
ACTION_SLICE_PURCHASE_APP_RESPONSE_NOT_DEFAULT_DATA_SUBSCRIPTION, capability,
false));
+ intent.putExtra(EXTRA_INTENT_NOTIFICATIONS_DISABLED, createPendingIntent(
+ ACTION_SLICE_PURCHASE_APP_RESPONSE_NOTIFICATIONS_DISABLED, capability, false));
intent.putExtra(EXTRA_INTENT_SUCCESS, createPendingIntent(
ACTION_SLICE_PURCHASE_APP_RESPONSE_SUCCESS, capability, true));
intent.putExtra(EXTRA_INTENT_NOTIFICATION_SHOWN, createPendingIntent(
@@ -788,6 +833,7 @@
filter.addAction(ACTION_SLICE_PURCHASE_APP_RESPONSE_CARRIER_ERROR);
filter.addAction(ACTION_SLICE_PURCHASE_APP_RESPONSE_REQUEST_FAILED);
filter.addAction(ACTION_SLICE_PURCHASE_APP_RESPONSE_NOT_DEFAULT_DATA_SUBSCRIPTION);
+ filter.addAction(ACTION_SLICE_PURCHASE_APP_RESPONSE_NOTIFICATIONS_DISABLED);
filter.addAction(ACTION_SLICE_PURCHASE_APP_RESPONSE_SUCCESS);
filter.addAction(ACTION_SLICE_PURCHASE_APP_RESPONSE_NOTIFICATION_SHOWN);
mPhone.getContext().registerReceiver(
@@ -977,7 +1023,8 @@
private long getThrottleDuration(@TelephonyManager.PurchasePremiumCapabilityResult int result) {
if (result == TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED
- || result == TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT) {
+ || result == TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT
+ || result == TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_DISABLED) {
return getCarrierConfigs().getLong(CarrierConfigManager
.KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG);
}
@@ -1037,26 +1084,71 @@
return mPhone.getSubId() == SubscriptionManager.getDefaultDataSubscriptionId();
}
- private boolean isSlicingConfigActive(@TelephonyManager.PremiumCapability int capability) {
+ /**
+ * Check whether the current network slicing configuration indicates that the given premium
+ * capability is active and set up on the carrier network.
+ * @param capability The premium capability to check for.
+ * @return {@code true} if the slicing config indicates the capability is active and
+ * {@code false} otherwise.
+ */
+ @VisibleForTesting
+ public boolean isSlicingConfigActive(@TelephonyManager.PremiumCapability int capability) {
if (mSlicingConfig == null) {
return false;
}
- int capabilityServiceType = getSliceServiceType(capability);
- for (NetworkSliceInfo sliceInfo : mSlicingConfig.getSliceInfo()) {
- if (sliceInfo.getSliceServiceType() == capabilityServiceType
- && sliceInfo.getStatus() == NetworkSliceInfo.SLICE_STATUS_ALLOWED) {
- return true;
+ for (UrspRule urspRule : mSlicingConfig.getUrspRules()) {
+ for (TrafficDescriptor trafficDescriptor : urspRule.getTrafficDescriptors()) {
+ TrafficDescriptor.OsAppId osAppId =
+ new TrafficDescriptor.OsAppId(trafficDescriptor.getOsAppId());
+ if (osAppId.getAppId().equals(getAppId(capability))) {
+ for (RouteSelectionDescriptor rsd : urspRule.getRouteSelectionDescriptor()) {
+ for (NetworkSliceInfo sliceInfo : rsd.getSliceInfo()) {
+ if (sliceInfo.getStatus() == NetworkSliceInfo.SLICE_STATUS_ALLOWED
+ && getSliceServiceTypes(capability).contains(
+ sliceInfo.getSliceServiceType())) {
+ return true;
+ }
+ }
+ }
+ }
}
}
return false;
}
- @NetworkSliceInfo.SliceServiceType private int getSliceServiceType(
- @TelephonyManager.PremiumCapability int capability) {
+ /**
+ * Get the application ID associated with the given premium capability.
+ * The app ID is a field in {@link TrafficDescriptor} that helps match URSP rules to determine
+ * whether the premium capability was successfully set up on the carrier network.
+ * @param capability The premium capability to get the app ID for.
+ * @return The application ID associated with the premium capability.
+ */
+ @VisibleForTesting
+ @NonNull public static String getAppId(@TelephonyManager.PremiumCapability int capability) {
if (capability == TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY) {
- return NetworkSliceInfo.SLICE_SERVICE_TYPE_URLLC;
+ return "PRIORITIZE_LATENCY";
}
- return NetworkSliceInfo.SLICE_SERVICE_TYPE_NONE;
+ return "";
+ }
+
+ /**
+ * Get the slice service types associated with the given premium capability.
+ * The slice service type is a field in {@link NetworkSliceInfo} that helps to match determine
+ * whether the premium capability was successfully set up on the carrier network.
+ * @param capability The premium capability to get the associated slice service types for.
+ * @return A set of slice service types associated with the premium capability.
+ */
+ @VisibleForTesting
+ @NonNull @NetworkSliceInfo.SliceServiceType public static Set<Integer> getSliceServiceTypes(
+ @TelephonyManager.PremiumCapability int capability) {
+ Set<Integer> sliceServiceTypes = new HashSet<>();
+ if (capability == TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY) {
+ sliceServiceTypes.add(NetworkSliceInfo.SLICE_SERVICE_TYPE_EMBB);
+ sliceServiceTypes.add(NetworkSliceInfo.SLICE_SERVICE_TYPE_URLLC);
+ } else {
+ sliceServiceTypes.add(NetworkSliceInfo.SLICE_SERVICE_TYPE_NONE);
+ }
+ return sliceServiceTypes;
}
private boolean isNetworkAvailable() {
@@ -1094,9 +1186,9 @@
switch (failureCode) {
case FAILURE_CODE_UNKNOWN: return "UNKNOWN";
case FAILURE_CODE_CARRIER_URL_UNAVAILABLE: return "CARRIER_URL_UNAVAILABLE";
- case FAILURE_CODE_SERVER_UNREACHABLE: return "SERVER_UNREACHABLE";
case FAILURE_CODE_AUTHENTICATION_FAILED: return "AUTHENTICATION_FAILED";
case FAILURE_CODE_PAYMENT_FAILED: return "PAYMENT_FAILED";
+ case FAILURE_CODE_NO_USER_DATA: return "NO_USER_DATA";
default:
return "UNKNOWN(" + failureCode + ")";
}
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 2b69b82..ea29b77 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -16,6 +16,7 @@
package com.android.services.telephony;
+import android.app.ActivityManager;
import android.app.PropertyInvalidatedCache;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -1191,7 +1192,7 @@
private int mSubscriptionListenerState = LISTENER_STATE_UNREGISTERED;
private int mServiceState = ServiceState.STATE_POWER_OFF;
private int mActiveDataSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- private boolean mIsPrimaryUser = true;
+ private boolean mIsPrimaryUser = UserHandle.of(ActivityManager.getCurrentUser()).isSystem();
private ExponentialBackoff mRegisterSubscriptionListenerBackoff;
private final HandlerThread mHandlerThread = new HandlerThread("TelecomAccountRegistry");
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 6d136b0..7aa0e7b 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -149,6 +149,8 @@
private static final int MSG_DTMF_DONE = 22;
private static final int MSG_MEDIA_ATTRIBUTES_CHANGED = 23;
private static final int MSG_ON_RTT_INITIATED = 24;
+ private static final int MSG_HOLD = 25;
+ private static final int MSG_UNHOLD = 26;
private static final String JAPAN_COUNTRY_CODE_WITH_PLUS_SIGN = "+81";
private static final String JAPAN_ISO_COUNTRY_CODE = "JP";
@@ -344,6 +346,12 @@
}
sendRttInitiationSuccess();
break;
+ case MSG_HOLD:
+ performHold();
+ break;
+ case MSG_UNHOLD:
+ performUnhold();
+ break;
}
}
};
@@ -1049,12 +1057,12 @@
@Override
public void onHold() {
- performHold();
+ mHandler.obtainMessage(MSG_HOLD).sendToTarget();
}
@Override
public void onUnhold() {
- performUnhold();
+ mHandler.obtainMessage(MSG_UNHOLD).sendToTarget();
}
@Override
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index bf7ce00..93a38dd 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -1171,7 +1171,8 @@
}
if (!isEmergencyNumber) {
- if (mSatelliteController.isSatelliteEnabled()) {
+ if (mSatelliteController.isSatelliteEnabled()
+ || isCallDisallowedDueToSatellite(phone)) {
Log.d(this, "onCreateOutgoingConnection, cannot make call in satellite mode.");
return Connection.createFailedConnection(
mDisconnectCauseFactory.toTelecomDisconnectCause(
@@ -4067,4 +4068,34 @@
connection.addTelephonyConnectionListener(mEmergencyConnectionSatelliteListener);
mSatelliteSOSMessageRecommender.onEmergencyCallStarted(connection, phone);
}
+
+ /**
+ * Check whether making a call is disallowed while using satellite
+ * @param phone phone object whose supported services needs to be checked
+ * @return {@code true} if network does not support calls while using satellite
+ * else {@code false}.
+ */
+ private boolean isCallDisallowedDueToSatellite(Phone phone) {
+ if (phone == null) {
+ return false;
+ }
+
+ ServiceState serviceState = phone.getServiceState();
+ if (!serviceState.isUsingNonTerrestrialNetwork()) {
+ // Device is not connected to satellite
+ return false;
+ }
+
+ for (NetworkRegistrationInfo nri : serviceState.getNetworkRegistrationInfoList()) {
+ if (nri.isNonTerrestrialNetwork()
+ && nri.getAvailableServices().contains(
+ NetworkRegistrationInfo.SERVICE_TYPE_VOICE)) {
+ // Call is supported while using satellite
+ return false;
+ }
+ }
+
+ // Call is disallowed while using satellite
+ return true;
+ }
}
diff --git a/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java b/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
index b2a4a9f..ca67d63 100644
--- a/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
+++ b/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
@@ -34,6 +34,7 @@
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import android.annotation.NonNull;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -50,6 +51,9 @@
import android.telephony.TelephonyManager;
import android.telephony.data.NetworkSliceInfo;
import android.telephony.data.NetworkSlicingConfig;
+import android.telephony.data.RouteSelectionDescriptor;
+import android.telephony.data.TrafficDescriptor;
+import android.telephony.data.UrspRule;
import android.testing.TestableLooper;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -66,7 +70,9 @@
import org.mockito.Mockito;
import java.time.LocalDate;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
import java.util.Map;
@RunWith(AndroidJUnit4.class)
@@ -578,7 +584,7 @@
intent.putExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY);
intent.putExtra(SlicePurchaseController.EXTRA_FAILURE_CODE,
- SlicePurchaseController.FAILURE_CODE_SERVER_UNREACHABLE);
+ SlicePurchaseController.FAILURE_CODE_CARRIER_URL_UNAVAILABLE);
mContext.getBroadcastReceiver().onReceive(mContext, intent);
mTestableLooper.processAllMessages();
assertEquals(TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_ERROR, mResult);
@@ -619,6 +625,7 @@
public void testPurchasePremiumCapabilityResultNotDefaultDataSubscriptionResponse() {
sendValidPurchaseRequest();
+ // broadcast NOT_DEFAULT_DATA_SUBSCRIPTION response from slice purchase application
Intent intent = new Intent();
intent.setAction("com.android.phone.slice.action."
+ "SLICE_PURCHASE_APP_RESPONSE_NOT_DEFAULT_DATA_SUBSCRIPTION");
@@ -636,6 +643,34 @@
}
@Test
+ public void testPurchasePremiumCapabilityResultNotificationsDisabled() {
+ sendValidPurchaseRequest();
+
+ // broadcast NOTIFICATIONS_DISABLED response from slice purchase application
+ Intent intent = new Intent();
+ intent.setAction("com.android.phone.slice.action."
+ + "SLICE_PURCHASE_APP_RESPONSE_NOTIFICATIONS_DISABLED");
+ intent.putExtra(SlicePurchaseController.EXTRA_PHONE_ID, PHONE_ID);
+ intent.putExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
+ TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY);
+ mContext.getBroadcastReceiver().onReceive(mContext, intent);
+ mTestableLooper.processAllMessages();
+ assertEquals(TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_DISABLED, mResult);
+
+ // retry to verify throttled
+ mSlicePurchaseController.purchasePremiumCapability(
+ TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY, mHandler.obtainMessage());
+ mTestableLooper.processAllMessages();
+ assertEquals(TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED, mResult);
+
+ // retry to verify unthrottled
+ mTestableLooper.moveTimeForward(THROTTLE_TIMEOUT);
+ mTestableLooper.processAllMessages();
+
+ testPurchasePremiumCapabilityResultSuccess();
+ }
+
+ @Test
public void testPurchasePremiumCapabilityResultNotificationThrottled() {
mSlicePurchaseController.setLocalDate(LocalDate.of(YEAR, MONTH, DATE));
mSlicePurchaseController.updateNotificationCounts();
@@ -670,6 +705,69 @@
assertEquals(TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED, mResult);
}
+ @Test
+ public void testIsSlicingConfigActive_emptyUrspRules() {
+ int capability = TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY;
+ NetworkSliceInfo sliceInfo = createNetworkSliceInfo(
+ getRandomSliceServiceType(capability), true);
+ NetworkSlicingConfig slicingConfig = new NetworkSlicingConfig(
+ Collections.emptyList(), Collections.singletonList(sliceInfo));
+ mSlicePurchaseController.setSlicingConfig(slicingConfig);
+
+ assertFalse(mSlicePurchaseController.isSlicingConfigActive(capability));
+ }
+
+ @Test
+ public void testIsSlicingConfigActive_noMatchingTrafficDescriptor() {
+ int capability = TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY;
+ NetworkSliceInfo sliceInfo = createNetworkSliceInfo(
+ getRandomSliceServiceType(capability), true);
+ TrafficDescriptor trafficDescriptor = createTrafficDescriptor("ENTERPRISE");
+ RouteSelectionDescriptor routeSelectionDescriptor = createRouteSelectionDescriptor(
+ Collections.singletonList(sliceInfo));
+ NetworkSlicingConfig slicingConfig = createNetworkSlicingConfig(
+ Collections.singletonList(sliceInfo),
+ Collections.singletonList(trafficDescriptor),
+ Collections.singletonList(routeSelectionDescriptor));
+ mSlicePurchaseController.setSlicingConfig(slicingConfig);
+
+ assertFalse(mSlicePurchaseController.isSlicingConfigActive(capability));
+ }
+
+ @Test
+ public void testIsSlicingConfigActive_multipleElements() {
+ int capability = TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY;
+ NetworkSliceInfo sliceInfo1 = createNetworkSliceInfo(
+ getRandomSliceServiceType(SlicePurchaseController.PREMIUM_CAPABILITY_INVALID),
+ false);
+ NetworkSliceInfo sliceInfo2 = createNetworkSliceInfo(
+ getRandomSliceServiceType(capability), true);
+ List<NetworkSliceInfo> sliceInfos = new ArrayList<>();
+ sliceInfos.add(sliceInfo1);
+ sliceInfos.add(sliceInfo2);
+
+ TrafficDescriptor trafficDescriptor1 = createTrafficDescriptor("ENTERPRISE");
+ TrafficDescriptor trafficDescriptor2 = createTrafficDescriptor(
+ SlicePurchaseController.getAppId(capability));
+ List<TrafficDescriptor> trafficDescriptors = new ArrayList<>();
+ trafficDescriptors.add(trafficDescriptor1);
+ trafficDescriptors.add(trafficDescriptor2);
+
+ RouteSelectionDescriptor routeSelectionDescriptor1 = createRouteSelectionDescriptor(
+ Collections.emptyList());
+ RouteSelectionDescriptor routeSelectionDescriptor2 = createRouteSelectionDescriptor(
+ sliceInfos);
+ List<RouteSelectionDescriptor> routeSelectionDescriptors = new ArrayList<>();
+ routeSelectionDescriptors.add(routeSelectionDescriptor1);
+ routeSelectionDescriptors.add(routeSelectionDescriptor2);
+
+ NetworkSlicingConfig slicingConfig = createNetworkSlicingConfig(
+ sliceInfos, trafficDescriptors, routeSelectionDescriptors);
+ mSlicePurchaseController.setSlicingConfig(slicingConfig);
+
+ assertTrue(mSlicePurchaseController.isSlicingConfigActive(capability));
+ }
+
private void completeSuccessfulPurchase() {
sendValidPurchaseRequest();
@@ -726,7 +824,7 @@
mEntitlementResponse.mEntitlementStatus =
PremiumNetworkEntitlementResponse.PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED;
mEntitlementResponse.mProvisionStatus =
- PremiumNetworkEntitlementResponse.PREMIUM_NETWORK_PROVISION_STATUS_PROVISIONED;
+ PremiumNetworkEntitlementResponse.PREMIUM_NETWORK_PROVISION_STATUS_NOT_PROVISIONED;
// send purchase request
mSlicePurchaseController.purchasePremiumCapability(
@@ -744,18 +842,61 @@
}
private void sendNetworkSlicingConfig(int capability, boolean configActive) {
- int sliceServiceType = capability == TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY
- ? NetworkSliceInfo.SLICE_SERVICE_TYPE_URLLC
- : NetworkSliceInfo.SLICE_SERVICE_TYPE_NONE;
- NetworkSliceInfo sliceInfo = new NetworkSliceInfo.Builder()
- .setStatus(configActive ? NetworkSliceInfo.SLICE_STATUS_ALLOWED
- : NetworkSliceInfo.SLICE_STATUS_UNKNOWN)
- .setSliceServiceType(sliceServiceType)
- .build();
- NetworkSlicingConfig slicingConfig = new NetworkSlicingConfig(Collections.emptyList(),
+ NetworkSliceInfo sliceInfo = createNetworkSliceInfo(
+ getRandomSliceServiceType(capability), configActive);
+ TrafficDescriptor trafficDescriptor = createTrafficDescriptor(
+ SlicePurchaseController.getAppId(capability));
+ RouteSelectionDescriptor routeSelectionDescriptor = createRouteSelectionDescriptor(
Collections.singletonList(sliceInfo));
+ NetworkSlicingConfig slicingConfig = createNetworkSlicingConfig(
+ Collections.singletonList(sliceInfo),
+ Collections.singletonList(trafficDescriptor),
+ Collections.singletonList(routeSelectionDescriptor));
mSlicePurchaseController.obtainMessage(2 /* EVENT_SLICING_CONFIG_CHANGED */,
new AsyncResult(null, slicingConfig, null)).sendToTarget();
mTestableLooper.processAllMessages();
}
+
+ @NetworkSliceInfo.SliceServiceType private int getRandomSliceServiceType(
+ @TelephonyManager.PremiumCapability int capability) {
+ for (int sliceServiceType : SlicePurchaseController.getSliceServiceTypes(capability)) {
+ // Get a random valid sst from the set
+ return sliceServiceType;
+ }
+ return NetworkSliceInfo.SLICE_SERVICE_TYPE_NONE;
+ }
+
+ @NonNull private NetworkSliceInfo createNetworkSliceInfo(
+ @NetworkSliceInfo.SliceServiceType int sliceServiceType, boolean active) {
+ return new NetworkSliceInfo.Builder()
+ .setStatus(active ? NetworkSliceInfo.SLICE_STATUS_ALLOWED
+ : NetworkSliceInfo.SLICE_STATUS_UNKNOWN)
+ .setSliceServiceType(sliceServiceType)
+ .build();
+ }
+
+ @NonNull private TrafficDescriptor createTrafficDescriptor(@NonNull String appId) {
+ TrafficDescriptor.OsAppId osAppId = new TrafficDescriptor.OsAppId(
+ TrafficDescriptor.OsAppId.ANDROID_OS_ID, appId);
+ return new TrafficDescriptor.Builder()
+ .setOsAppId(osAppId.getBytes())
+ .build();
+ }
+
+ @NonNull private RouteSelectionDescriptor createRouteSelectionDescriptor(
+ @NonNull List<NetworkSliceInfo> sliceInfos) {
+ return new RouteSelectionDescriptor(
+ RouteSelectionDescriptor.MIN_ROUTE_PRECEDENCE,
+ RouteSelectionDescriptor.SESSION_TYPE_IPV4,
+ RouteSelectionDescriptor.ROUTE_SSC_MODE_1,
+ sliceInfos, Collections.emptyList());
+ }
+
+ @NonNull private NetworkSlicingConfig createNetworkSlicingConfig(
+ @NonNull List<NetworkSliceInfo> sliceInfos,
+ @NonNull List<TrafficDescriptor> trafficDescriptors,
+ @NonNull List<RouteSelectionDescriptor> routeSelectionDescriptors) {
+ UrspRule urspRule = new UrspRule(0, trafficDescriptors, routeSelectionDescriptors);
+ return new NetworkSlicingConfig(Collections.singletonList(urspRule), sliceInfos);
+ }
}
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 4f9b879..9e1ea24 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -35,6 +35,7 @@
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertNotEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -2899,6 +2900,36 @@
disconnectCause.getTelephonyDisconnectCause());
}
+ @Test
+ public void testNormalCallUsingNonTerrestrialNetwork() {
+ setupForCallTest();
+ // Call is not supported while using satellite
+ NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
+ .setIsNonTerrestrialNetwork(true)
+ .setAvailableServices(List.of(NetworkRegistrationInfo.SERVICE_TYPE_DATA))
+ .build();
+ ServiceState ss = new ServiceState();
+ ss.addNetworkRegistrationInfo(nri);
+ when(mPhone0.getServiceState()).thenReturn(ss);
+ mConnection = mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+ createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", TELECOM_CALL_ID1));
+ DisconnectCause disconnectCause = mConnection.getDisconnectCause();
+ assertEquals(android.telephony.DisconnectCause.SATELLITE_ENABLED,
+ disconnectCause.getTelephonyDisconnectCause());
+
+ // Call is supported while using satellite
+ nri = new NetworkRegistrationInfo.Builder()
+ .setIsNonTerrestrialNetwork(true)
+ .setAvailableServices(List.of(NetworkRegistrationInfo.SERVICE_TYPE_VOICE))
+ .build();
+ ss.addNetworkRegistrationInfo(nri);
+ mConnection = mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+ createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", "TC@2"));
+ disconnectCause = mConnection.getDisconnectCause();
+ assertNotEquals(android.telephony.DisconnectCause.SATELLITE_ENABLED,
+ disconnectCause.getTelephonyDisconnectCause());
+ }
+
private void setupForDialForDomainSelection(Phone mockPhone, int domain, boolean isEmergency) {
if (isEmergency) {
doReturn(mEmergencyCallDomainSelectionConnection).when(mDomainSelectionResolver)