Handle RADIO_NOT_AVAILABLE in deactivateDataCall
Test: atest DataNetworkTest, DataNetworkControllerTest, DcTrackerTest
Bug: 221174412
Change-Id: I073622fa4cb0ea12bacf5f95354aa38f7a44d1f8
Merged-In: I073622fa4cb0ea12bacf5f95354aa38f7a44d1f8
diff --git a/src/java/com/android/internal/telephony/DataResponse.java b/src/java/com/android/internal/telephony/DataResponse.java
index 061f9f6..e657152 100644
--- a/src/java/com/android/internal/telephony/DataResponse.java
+++ b/src/java/com/android/internal/telephony/DataResponse.java
@@ -71,7 +71,13 @@
* @param responseInfo Response info struct containing response type, serial no. and error
*/
public void deactivateDataCallResponse(RadioResponseInfo responseInfo) {
- RadioResponse.responseVoid(RIL.DATA_SERVICE, mRil, responseInfo);
+ RILRequest rr = mRil.processResponse(RIL.DATA_SERVICE, responseInfo);
+
+ if (rr != null) {
+ int response = responseInfo.error;
+ RadioResponse.sendMessageResponse(rr.mResult, response);
+ mRil.processResponseDone(rr, responseInfo, response);
+ }
}
/**
diff --git a/src/java/com/android/internal/telephony/RadioResponse.java b/src/java/com/android/internal/telephony/RadioResponse.java
index 5265be5..d13f3ca 100644
--- a/src/java/com/android/internal/telephony/RadioResponse.java
+++ b/src/java/com/android/internal/telephony/RadioResponse.java
@@ -740,7 +740,13 @@
* @param responseInfo Response info struct containing response type, serial no. and error
*/
public void deactivateDataCallResponse(RadioResponseInfo responseInfo) {
- responseVoid(responseInfo);
+ RILRequest rr = mRil.processResponse(responseInfo);
+
+ if (rr != null) {
+ int response = responseInfo.error;
+ sendMessageResponse(rr.mResult, response);
+ mRil.processResponseDone(rr, responseInfo, response);
+ }
}
/**
diff --git a/src/java/com/android/internal/telephony/data/CellularDataService.java b/src/java/com/android/internal/telephony/data/CellularDataService.java
index f041d5f..e7cf86f 100644
--- a/src/java/com/android/internal/telephony/data/CellularDataService.java
+++ b/src/java/com/android/internal/telephony/data/CellularDataService.java
@@ -19,6 +19,7 @@
import static android.telephony.data.DataServiceCallback.RESULT_SUCCESS;
import android.annotation.Nullable;
+import android.hardware.radio.RadioError;
import android.net.LinkProperties;
import android.os.AsyncResult;
import android.os.Handler;
@@ -51,7 +52,7 @@
private static final boolean DBG = false;
private static final int SETUP_DATA_CALL_COMPLETE = 1;
- private static final int DEACTIVATE_DATA_ALL_COMPLETE = 2;
+ private static final int DEACTIVATE_DATA_CALL_COMPLETE = 2;
private static final int SET_INITIAL_ATTACH_APN_COMPLETE = 3;
private static final int SET_DATA_PROFILE_COMPLETE = 4;
private static final int REQUEST_DATA_CALL_LIST_COMPLETE = 5;
@@ -87,10 +88,13 @@
: RESULT_SUCCESS,
response);
break;
- case DEACTIVATE_DATA_ALL_COMPLETE:
+ case DEACTIVATE_DATA_CALL_COMPLETE:
+ int error = (int) ar.result;
callback.onDeactivateDataCallComplete(ar.exception != null
? DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE
- : RESULT_SUCCESS);
+ : error == RadioError.RADIO_NOT_AVAILABLE
+ ? DataServiceCallback.RESULT_ERROR_RADIO_NOT_AVAILABLE
+ : RESULT_SUCCESS);
break;
case SET_INITIAL_ATTACH_APN_COMPLETE:
callback.onSetInitialAttachApnComplete(ar.exception != null
@@ -189,7 +193,7 @@
// Only obtain the message when the caller wants a callback. If the caller doesn't care
// the request completed or results, then no need to pass the message down.
if (callback != null) {
- message = Message.obtain(mHandler, DEACTIVATE_DATA_ALL_COMPLETE);
+ message = Message.obtain(mHandler, DEACTIVATE_DATA_CALL_COMPLETE);
mCallbackMap.put(message, callback);
}
diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
index 71da08c..f2f2ddc 100644
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ b/src/java/com/android/internal/telephony/data/DataNetwork.java
@@ -123,9 +123,9 @@
* {@link ConnectedState}. When the data network is about to be disconnected, it first enters
* {@link DisconnectingState} when performing graceful tear down or when sending the data
* deactivation request. At the end, it enters {@link DisconnectedState} when {@link DataService}
- * notifies data disconnected. Note that a unsolicited disconnected event from {@link DataService}
- * can immediately move data network transited from {@link ConnectedState} to
- * {@link DisconnectedState}. {@link DisconnectedState} is the final state of a data network.
+ * notifies data disconnected. Note that an unsolicited disconnected event from {@link DataService}
+ * or a RADIO_NOT_AVAILABLE response can immediately move data network from {@link ConnectedState}
+ * to {@link DisconnectedState}. {@link DisconnectedState} is the final state of a data network.
*
* State machine diagram:
*
@@ -158,7 +158,7 @@
private static final int EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE = 5;
/** Event for setup data network response. */
- private static final int EVENT_SETUP_DATA_CALL_RESPONSE = 6;
+ private static final int EVENT_SETUP_DATA_NETWORK_RESPONSE = 6;
/** Event for tearing down data network. */
private static final int EVENT_TEAR_DOWN_NETWORK = 7;
@@ -196,6 +196,9 @@
/** Event for carrier privileged UIDs changed. */
private static final int EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED = 18;
+ /** Event for deactivate data network response. */
+ private static final int EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE = 19;
+
/** The default MTU for IPv4 network. */
private static final int DEFAULT_MTU_V4 = 1280;
@@ -795,8 +798,7 @@
for (TelephonyNetworkRequest networkRequest : networkRequestList) {
networkRequest.setAttachedNetwork(DataNetwork.this);
- networkRequest.setState(
- TelephonyNetworkRequest.REQUEST_STATE_SATISFIED);
+ networkRequest.setState(TelephonyNetworkRequest.REQUEST_STATE_SATISFIED);
}
addState(mDefaultState);
@@ -1017,7 +1019,7 @@
}
setupData();
break;
- case EVENT_SETUP_DATA_CALL_RESPONSE:
+ case EVENT_SETUP_DATA_NETWORK_RESPONSE:
int resultCode = msg.arg1;
DataCallResponse dataCallResponse =
msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE);
@@ -1128,6 +1130,10 @@
ar = (AsyncResult) msg.obj;
onPcoDataReceived((PcoData) ar.result);
break;
+ case EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE:
+ int resultCode = msg.arg1;
+ onDeactivateResponse(resultCode);
+ break;
default:
return NOT_HANDLED;
}
@@ -1236,7 +1242,15 @@
@Override
public boolean processMessage(Message msg) {
logv("event=" + eventToString(msg.what));
- return NOT_HANDLED;
+ switch (msg.what) {
+ case EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE:
+ int resultCode = msg.arg1;
+ onDeactivateResponse(resultCode);
+ break;
+ default:
+ return NOT_HANDLED;
+ }
+ return HANDLED;
}
}
@@ -1737,7 +1751,7 @@
.setupDataCall(accessNetwork, mDataProfile, isModemRoaming, allowRoaming,
DataService.REQUEST_REASON_NORMAL, null, mPduSessionId, null,
trafficDescriptor, matchAllRuleAllowed,
- obtainMessage(EVENT_SETUP_DATA_CALL_RESPONSE));
+ obtainMessage(EVENT_SETUP_DATA_NETWORK_RESPONSE));
int apnTypeBitmask = mDataProfile.getApnSetting() != null
? mDataProfile.getApnSetting().getApnTypeBitmask() : ApnSetting.TYPE_NONE;
@@ -2013,6 +2027,23 @@
}
/**
+ * Called when receiving deactivate data network response from the data service.
+ *
+ * @param resultCode The result code.
+ */
+ private void onDeactivateResponse(@DataServiceCallback.ResultCode int resultCode) {
+ logl("onDeactivateResponse: resultCode="
+ + DataServiceCallback.resultCodeToString(resultCode));
+ if (resultCode == DataServiceCallback.RESULT_ERROR_RADIO_NOT_AVAILABLE) {
+ log("Remove network since deactivate request returned RADIO_NOT_AVAILABLE.");
+ mDataNetworkCallback.invokeFromExecutor(
+ () -> mDataNetworkCallback.onDisconnected(
+ DataNetwork.this, DataFailCause.RADIO_NOT_AVAILABLE));
+ transitionTo(mDisconnectedState);
+ }
+ }
+
+ /**
* Tear down the data network immediately.
*
* @param reason The reason of tearing down the network.
@@ -2037,7 +2068,8 @@
// TODO: Need to support DataService.REQUEST_REASON_SHUTDOWN
mDataServiceManagers.get(mTransport).deactivateDataCall(mCid.get(mTransport),
- DataService.REQUEST_REASON_NORMAL, null);
+ DataService.REQUEST_REASON_NORMAL,
+ obtainMessage(EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE));
mDataCallSessionStats.setDeactivateDataCallReason(DataService.REQUEST_REASON_NORMAL);
mInvokedDataDeactivation = true;
}
@@ -2606,7 +2638,8 @@
// Clean up on the source transport.
mDataServiceManagers.get(mTransport).deactivateDataCall(mCid.get(mTransport),
- DataService.REQUEST_REASON_HANDOVER, null);
+ DataService.REQUEST_REASON_HANDOVER,
+ obtainMessage(EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE));
// Switch the transport to the target.
mTransport = DataUtils.getTargetTransport(mTransport);
// Update the logging tag
@@ -2778,7 +2811,7 @@
return "EVENT_DETACH_NETWORK_REQUEST";
case EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE:
return "EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE";
- case EVENT_SETUP_DATA_CALL_RESPONSE:
+ case EVENT_SETUP_DATA_NETWORK_RESPONSE:
return "EVENT_SETUP_DATA_NETWORK_RESPONSE";
case EVENT_TEAR_DOWN_NETWORK:
return "EVENT_TEAR_DOWN_NETWORK";
@@ -2804,6 +2837,8 @@
return "EVENT_PCO_DATA_RECEIVED";
case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED:
return "EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED";
+ case EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE:
+ return "EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE";
default:
return "Unknown(" + event + ")";
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
index 91f8d3e..b635192 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
@@ -17,6 +17,7 @@
package com.android.internal.telephony.test;
import android.compat.annotation.UnsupportedAppUsage;
+import android.hardware.radio.RadioError;
import android.hardware.radio.V1_0.DataRegStateResult;
import android.hardware.radio.V1_0.SetupDataCallResult;
import android.hardware.radio.V1_0.VoiceRegStateResult;
@@ -1239,7 +1240,7 @@
@Override
public void deactivateDataCall(int cid, int reason, Message result) {
SimulatedCommandsVerifier.getInstance().deactivateDataCall(cid, reason, result);
- resultSuccess(result, null);
+ resultSuccess(result, RadioError.NONE);
}
@Override
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
index e1f4a3a..5486c12 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -468,7 +468,7 @@
transport).values()), null));
return null;
}).when(mMockedDataServiceManagers.get(transport)).deactivateDataCall(
- anyInt(), anyInt(), eq(null));
+ anyInt(), anyInt(), any(Message.class));
doAnswer(invocation -> {
Handler h = (Handler) invocation.getArguments()[0];
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
index b6e1aa5..2a64729 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
@@ -461,7 +461,7 @@
verify(mSimulatedCommandsVerifier, never()).releasePduSessionId(nullable(Message.class),
anyInt());
verify(mMockedWwanDataServiceManager).deactivateDataCall(eq(123),
- eq(DataService.REQUEST_REASON_NORMAL), eq(null));
+ eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
verify(mDataNetworkCallback).onDisconnected(eq(mDataNetworkUT), eq(
DataFailCause.EMM_DETACHED));
@@ -563,7 +563,7 @@
verify(mSimulatedCommandsVerifier).releasePduSessionId(nullable(Message.class), eq(1));
verify(mMockedWlanDataServiceManager).deactivateDataCall(eq(123),
- eq(DataService.REQUEST_REASON_NORMAL), eq(null));
+ eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
verify(mDataNetworkCallback).onDisconnected(eq(mDataNetworkUT), eq(
DataFailCause.EMM_DETACHED));
@@ -691,4 +691,17 @@
.containsExactly(ADMIN_UID1, ADMIN_UID2);
assertThat(mDataNetworkUT.getNetworkCapabilities().getOwnerUid()).isEqualTo(ADMIN_UID2);
}
+
+ @Test
+ public void testDeactivateDataCallRadioNotAvailable() throws Exception {
+ testCreateDataNetwork();
+ assertThat(mDataNetworkUT.isConnected()).isTrue();
+ mDataNetworkUT.sendMessage(19/*EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE*/,
+ 6/*RESULT_ERROR_RADIO_NOT_AVAILABLE*/);
+ processAllMessages();
+
+ verify(mDataNetworkCallback).onDisconnected(eq(mDataNetworkUT), eq(
+ DataFailCause.RADIO_NOT_AVAILABLE));
+ assertThat(mDataNetworkUT.isConnected()).isFalse();
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
index 5ee093e..ad9fe43 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
@@ -110,7 +110,6 @@
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.lang.reflect.Field;
@@ -739,14 +738,11 @@
doReturn(true).when(mSST).getDesiredPowerState();
doReturn(true).when(mSST).getPowerStateFromCarrier();
doAnswer(
- new Answer<Void>() {
- @Override
- public Void answer(InvocationOnMock invocation) throws Throwable {
- mOnSubscriptionsChangedListener =
- (SubscriptionManager.OnSubscriptionsChangedListener)
- invocation.getArguments()[0];
- return null;
- }
+ (Answer<Void>) invocation -> {
+ mOnSubscriptionsChangedListener =
+ (SubscriptionManager.OnSubscriptionsChangedListener)
+ invocation.getArguments()[0];
+ return null;
}
).when(mSubscriptionManager).addOnSubscriptionsChangedListener(any());
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());