Put controlee info to applet.
Bug: 200678121
Test: atest com.android.server.uwb
Change-Id: I70fed9db0f8381d000f004c49eef011c9c6029ba
diff --git a/service/java/com/android/server/uwb/secure/ControleeResponderSession.java b/service/java/com/android/server/uwb/secure/ControleeResponderSession.java
index 237cab1..f0c9a2e 100644
--- a/service/java/com/android/server/uwb/secure/ControleeResponderSession.java
+++ b/service/java/com/android/server/uwb/secure/ControleeResponderSession.java
@@ -27,7 +27,9 @@
import com.android.server.uwb.secure.csml.CsmlUtil;
import com.android.server.uwb.secure.csml.DispatchResponse;
import com.android.server.uwb.secure.csml.GetDoCommand;
+import com.android.server.uwb.secure.csml.PutDoCommand;
import com.android.server.uwb.secure.csml.SessionData;
+import com.android.server.uwb.secure.iso7816.TlvDatum;
import com.android.server.uwb.secure.iso7816.TlvParser;
import com.android.server.uwb.util.DataTypeConversionUtil;
@@ -48,6 +50,30 @@
}
@Override
+ protected void handleFiRaSecureChannelEstablished() {
+ super.handleFiRaSecureChannelEstablished();
+
+ PutDoCommand putControleeInfoCommand = PutDoCommand.build(
+ CsmlUtil.constructGetOrPutDoTlv(
+ new TlvDatum(CsmlUtil.CONTROLEE_INFO_DO_TAG,
+ mRunningProfileSessionInfo.controleeInfo.get().toBytes())));
+ mFiRaSecureChannel.sendLocalFiRaCommand(putControleeInfoCommand,
+ new FiRaSecureChannel.ExternalRequestCallback() {
+ @Override
+ public void onSuccess(@NonNull byte[] responseData) {
+ logd("controlee info is sent to applet.");
+ }
+
+ @Override
+ public void onFailure() {
+ logw("failed to send controlee info to applet.");
+ terminateSession();
+ mSessionCallback.onSessionAborted();
+ }
+ });
+ }
+
+ @Override
protected boolean onDispatchResponseReceived(@NonNull DispatchResponse dispatchResponse) {
DispatchResponse.RdsAvailableNotification rdsAvailable = null;
for (DispatchResponse.Notification notification : dispatchResponse.notifications) {
diff --git a/service/tests/src/com/android/server/uwb/secure/ControleeResponderSessionTest.java b/service/tests/src/com/android/server/uwb/secure/ControleeResponderSessionTest.java
index 2c77ece..fb55fd8 100644
--- a/service/tests/src/com/android/server/uwb/secure/ControleeResponderSessionTest.java
+++ b/service/tests/src/com/android/server/uwb/secure/ControleeResponderSessionTest.java
@@ -21,14 +21,19 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import android.os.test.TestLooper;
import com.android.server.uwb.pm.RunningProfileSessionInfo;
+import com.android.server.uwb.secure.csml.ControleeInfo;
import com.android.server.uwb.secure.csml.DispatchResponse;
+import com.android.server.uwb.secure.csml.FiRaCommand;
+import com.android.server.uwb.secure.csml.UwbCapability;
import com.android.server.uwb.secure.iso7816.ResponseApdu;
import com.android.server.uwb.util.DataTypeConversionUtil;
+import com.android.server.uwb.util.ObjectIdentifier;
import org.junit.Before;
import org.junit.Test;
@@ -37,6 +42,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.Optional;
+
public class ControleeResponderSessionTest {
@Mock
private FiRaSecureChannel mFiRaSecureChannel;
@@ -55,18 +62,26 @@
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
+ }
+
+ private void doInit(RunningProfileSessionInfo runningProfileSessionInfo) {
mControleeResponderSession = new ControleeResponderSession(
mTestLooper.getLooper(), mFiRaSecureChannel, mSecureSessionCallback,
- mRunningProfileSessionInfo);
+ runningProfileSessionInfo);
mControleeResponderSession.startSession();
verify(mFiRaSecureChannel).init(mSecureChannelCallbackCaptor.capture());
}
+ private void doInit() {
+ doInit(mRunningProfileSessionInfo);
+ }
+
@Test
public void onSetupError() {
+ doInit();
mSecureChannelCallbackCaptor.getValue()
.onSetUpError(FiRaSecureChannel.SetupError.OPEN_SE_CHANNEL);
@@ -75,7 +90,33 @@
}
@Test
+ public void onSessionEstablishedPutControleeInfoFail() {
+ RunningProfileSessionInfo runningProfileSessionInfo =
+ new RunningProfileSessionInfo.Builder(
+ mock(UwbCapability.class), mock(ObjectIdentifier.class))
+ .setControleeInfo(new ControleeInfo.Builder().build())
+ .build();
+ doInit(runningProfileSessionInfo);
+ mSecureChannelCallbackCaptor.getValue().onEstablished(Optional.empty());
+
+ ArgumentCaptor<FiRaCommand> cmdCaptor = ArgumentCaptor.forClass(FiRaCommand.class);
+ ArgumentCaptor<FiRaSecureChannel.ExternalRequestCallback> cbCaptor =
+ ArgumentCaptor.forClass(FiRaSecureChannel.ExternalRequestCallback.class);
+
+ verify(mFiRaSecureChannel).sendLocalFiRaCommand(cmdCaptor.capture(), cbCaptor.capture());
+ assertThat(cmdCaptor.getValue().getCommandApdu().getIns()).isEqualTo((byte) 0xDB);
+ assertThat(cmdCaptor.getValue().getCommandApdu().getP1()).isEqualTo((byte) 0x3F);
+ assertThat(cmdCaptor.getValue().getCommandApdu().getP2()).isEqualTo((byte) 0xFF);
+
+ cbCaptor.getValue().onFailure();
+ mTestLooper.dispatchAll();
+ verify(mFiRaSecureChannel).terminateLocally();
+ verify(mSecureSessionCallback).onSessionAborted();
+ }
+
+ @Test
public void onTerminated() {
+ doInit();
mSecureChannelCallbackCaptor.getValue()
.onTerminated(/*withError=*/ false);
@@ -84,6 +125,7 @@
@Test
public void terminateSession() {
+ doInit();
mControleeResponderSession.terminateSession();
mTestLooper.dispatchAll();
@@ -92,6 +134,7 @@
@Test
public void abortSessionNotification() {
+ doInit();
byte[] data = DataTypeConversionUtil.hexStringToByteArray(
"71038001FF"); // transaction complete with errors
ResponseApdu responseApdu = ResponseApdu.fromDataAndStatusWord(data, 0x9000);
@@ -106,6 +149,7 @@
@Test
public void abortSessionWithWrongDispatchResponseStatusWord() {
+ doInit();
ResponseApdu responseApdu = ResponseApdu.fromDataAndStatusWord(new byte[0], 0x9032);
DispatchResponse dispatchResponse = DispatchResponse.fromResponseApdu(responseApdu);
@@ -118,6 +162,7 @@
@Test
public void rdsAvailableNotificationWithSessionData() {
+ doInit();
byte[] data = DataTypeConversionUtil.hexStringToByteArray(
"711B80018181029000E112800100810102820A010107BF780480020101");
ResponseApdu responseApdu = ResponseApdu.fromDataAndStatusWord(data, 0x9000);
@@ -130,6 +175,7 @@
@Test
public void rdsAvailableNotificationWithSessionDataInApplet() {
+ doInit();
byte[] data = DataTypeConversionUtil.hexStringToByteArray(
"711380018181029000E10A80010081010282020101");
ResponseApdu responseApdu = ResponseApdu.fromDataAndStatusWord(data, 0x9000);
@@ -149,6 +195,7 @@
@Test
public void failedToGetSessionDataFromApplet() {
+ doInit();
byte[] data = DataTypeConversionUtil.hexStringToByteArray(
"711380018181029000E10A80010081010282020101");
ResponseApdu responseApdu = ResponseApdu.fromDataAndStatusWord(data, 0x9000);
@@ -167,6 +214,7 @@
@Test
public void outboundDataToRemote() {
+ doInit();
byte[] data = DataTypeConversionUtil.hexStringToByteArray(
"710780018081029000");
ResponseApdu responseApdu = ResponseApdu.fromDataAndStatusWord(data, 0x9000);