Merge 01b935fb70232704cd0690e9cc6a94519a8317fa on remote branch

Change-Id: I349bb0b5c216cefaa494b715ac289cdd538e6c4d
diff --git a/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java b/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
index 554f84c..d321fbc 100644
--- a/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
+++ b/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
@@ -1668,8 +1668,10 @@
                     if (ikeSaRecord.isRetransmittedRequest(ikePacketBytes)) {
                         logd("Received re-transmitted request. Retransmitting response");
 
-                        for (byte[] packet : ikeSaRecord.getLastSentRespAllPackets()) {
-                            mIkeSocket.sendIkePacket(packet, mRemoteAddress);
+                        if (ikeSaRecord.getLastSentRespAllPackets() != null) {
+                            for (byte[] packet : ikeSaRecord.getLastSentRespAllPackets()) {
+                                mIkeSocket.sendIkePacket(packet, mRemoteAddress);
+                            }
                         }
 
                         // TODO:Support resetting remote rekey delete timer.
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java
index 54ad2d2..929dcf1 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java
+++ b/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java
@@ -548,20 +548,7 @@
         private static final int PROPOSAL_RESERVED_FIELD_LEN = 1;
         private static final int PROPOSAL_HEADER_LEN = 8;
 
-        @VisibleForTesting
-        static TransformDecoder sTransformDecoder =
-                new TransformDecoder() {
-                    @Override
-                    public Transform[] decodeTransforms(int count, ByteBuffer inputBuffer)
-                            throws IkeProtocolException {
-                        Transform[] transformArray = new Transform[count];
-                        for (int i = 0; i < count; i++) {
-                            Transform transform = Transform.readFrom(inputBuffer);
-                                transformArray[i] = transform;
-                        }
-                        return transformArray;
-                    }
-                };
+        private static TransformDecoder sTransformDecoder = new TransformDecoderImpl();
 
         public final byte number;
         /** All supported protocol will fall into {@link ProtocolId} */
@@ -677,6 +664,31 @@
             }
         }
 
+        private static class TransformDecoderImpl implements TransformDecoder {
+            @Override
+            public Transform[] decodeTransforms(int count, ByteBuffer inputBuffer)
+                    throws IkeProtocolException {
+                Transform[] transformArray = new Transform[count];
+                for (int i = 0; i < count; i++) {
+                    Transform transform = Transform.readFrom(inputBuffer);
+                    transformArray[i] = transform;
+                }
+                return transformArray;
+            }
+        }
+
+        /** Package private method to set TransformDecoder for testing purposes */
+        @VisibleForTesting
+        static void setTransformDecoder(TransformDecoder decoder) {
+            sTransformDecoder = decoder;
+        }
+
+        /** Package private method to reset TransformDecoder */
+        @VisibleForTesting
+        static void resetTransformDecoder() {
+            sTransformDecoder = new TransformDecoderImpl();
+        }
+
         /** Package private */
         boolean isNegotiatedFrom(Proposal reqProposal) {
             if (protocolId != reqProposal.protocolId || number != reqProposal.number) {
@@ -962,22 +974,7 @@
 
         // TODO: Add constants for supported algorithms
 
-        @VisibleForTesting
-        static AttributeDecoder sAttributeDecoder =
-                new AttributeDecoder() {
-                    public List<Attribute> decodeAttributes(int length, ByteBuffer inputBuffer)
-                            throws IkeProtocolException {
-                        List<Attribute> list = new LinkedList<>();
-                        int parsedLength = BASIC_TRANSFORM_LEN;
-                        while (parsedLength < length) {
-                            Pair<Attribute, Integer> pair = Attribute.readFrom(inputBuffer);
-                            parsedLength += pair.second;
-                            list.add(pair.first);
-                        }
-                        // TODO: Validate that parsedLength equals to length.
-                        return list;
-                    }
-                };
+        private static AttributeDecoder sAttributeDecoder = new AttributeDecoderImpl();
 
         // Only supported type falls into {@link TransformType}
         public final int type;
@@ -1043,6 +1040,34 @@
             }
         }
 
+        private static class AttributeDecoderImpl implements AttributeDecoder {
+            @Override
+            public List<Attribute> decodeAttributes(int length, ByteBuffer inputBuffer)
+                    throws IkeProtocolException {
+                List<Attribute> list = new LinkedList<>();
+                int parsedLength = BASIC_TRANSFORM_LEN;
+                while (parsedLength < length) {
+                    Pair<Attribute, Integer> pair = Attribute.readFrom(inputBuffer);
+                    parsedLength += pair.second; // Increase parsedLength by the Atrribute length
+                    list.add(pair.first);
+                }
+                // TODO: Validate that parsedLength equals to length.
+                return list;
+            }
+        }
+
+        /** Package private method to set AttributeDecoder for testing purpose */
+        @VisibleForTesting
+        static void setAttributeDecoder(AttributeDecoder decoder) {
+            sAttributeDecoder = decoder;
+        }
+
+        /** Package private method to reset AttributeDecoder */
+        @VisibleForTesting
+        static void resetAttributeDecoder() {
+            sAttributeDecoder = new AttributeDecoderImpl();
+        }
+
         // Throw InvalidSyntaxException if there are multiple Attributes of the same type
         private static void validateAttributeUniqueness(List<Attribute> attributeList)
                 throws IkeProtocolException {
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionTest.java b/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionTest.java
index ad9c96e..28e8e6d 100644
--- a/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionTest.java
+++ b/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionTest.java
@@ -86,6 +86,7 @@
                         mMockIkeSessionCb,
                         mMockChildSessionCb);
         assertNotNull(ikeSession.mIkeSessionStateMachine.getHandler().getLooper());
+        ikeSession.kill();
     }
 
     /**
@@ -128,6 +129,10 @@
         assertEquals(
                 sessions[0].mIkeSessionStateMachine.getHandler().getLooper(),
                 sessions[1].mIkeSessionStateMachine.getHandler().getLooper());
+
+        for (IkeSession s : sessions) {
+            s.kill();
+        }
     }
 
     @Test
@@ -148,6 +153,9 @@
         assertTrue(
                 ikeSession.mIkeSessionStateMachine.getCurrentState()
                         instanceof IkeSessionStateMachine.CreateIkeLocalIkeInit);
+
+        ikeSession.kill();
+        testLooper.dispatchAll();
     }
 
     @Test
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java
index dadb978..f172e11 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java
+++ b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java
@@ -750,7 +750,8 @@
 
     @After
     public void tearDown() throws Exception {
-        mIkeSessionStateMachine.quit();
+        mIkeSessionStateMachine.killSession();
+        mLooper.dispatchAll();
         mIkeSessionStateMachine.setDbg(false);
 
         mSpyCurrentIkeSaRecord.close();
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayloadTest.java
index 3e09d47..4b1d77f 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayloadTest.java
+++ b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayloadTest.java
@@ -66,6 +66,7 @@
 import com.android.internal.net.ipsec.ike.utils.IpSecSpiGenerator;
 import com.android.server.IpSecService;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -174,6 +175,8 @@
     @Before
     public void setUp() throws Exception {
         mMockedAttributeDecoder = mock(AttributeDecoder.class);
+        Transform.setAttributeDecoder(mMockedAttributeDecoder);
+
         mAttributeKeyLength128 = new KeyLengthAttribute(SaProposal.KEY_LEN_AES_128);
         mAttributeListWithKeyLength128 = new LinkedList<>();
         mAttributeListWithKeyLength128.add(mAttributeKeyLength128);
@@ -252,7 +255,11 @@
         mIpSecSpiGenerator = new IpSecSpiGenerator(mIpSecManager, createMockRandomFactory());
     }
 
-    // TODO: Add tearDown() to reset Proposal.sTransformDecoder and Transform.sAttributeDecoder.
+    @After
+    public void tearDown() throws Exception {
+        Proposal.resetTransformDecoder();
+        Transform.resetAttributeDecoder();
+    }
 
     @Test
     public void testDecodeAttribute() throws Exception {
@@ -285,7 +292,6 @@
         doReturn(mAttributeListWithKeyLength128)
                 .when(mMockedAttributeDecoder)
                 .decodeAttributes(anyInt(), any());
-        Transform.sAttributeDecoder = mMockedAttributeDecoder;
 
         Transform transform = Transform.readFrom(inputBuffer);
         assertTrue(transform instanceof EncryptionTransform);
@@ -304,7 +310,6 @@
         attributeList.add(keyLengAttr);
 
         doReturn(attributeList).when(mMockedAttributeDecoder).decodeAttributes(anyInt(), any());
-        Transform.sAttributeDecoder = mMockedAttributeDecoder;
 
         try {
             Transform.readFrom(inputBuffer);
@@ -349,7 +354,6 @@
         doReturn(new LinkedList<Attribute>())
                 .when(mMockedAttributeDecoder)
                 .decodeAttributes(anyInt(), any());
-        Transform.sAttributeDecoder = mMockedAttributeDecoder;
 
         Transform transform = Transform.readFrom(inputBuffer);
         assertTrue(transform instanceof PrfTransform);
@@ -385,7 +389,6 @@
         doReturn(new LinkedList<Attribute>())
                 .when(mMockedAttributeDecoder)
                 .decodeAttributes(anyInt(), any());
-        Transform.sAttributeDecoder = mMockedAttributeDecoder;
 
         Transform transform = Transform.readFrom(inputBuffer);
         assertTrue(transform instanceof IntegrityTransform);
@@ -402,7 +405,6 @@
         doReturn(mAttributeListWithKeyLength128)
                 .when(mMockedAttributeDecoder)
                 .decodeAttributes(anyInt(), any());
-        Transform.sAttributeDecoder = mMockedAttributeDecoder;
 
         Transform transform = Transform.readFrom(inputBuffer);
         assertTrue(transform instanceof IntegrityTransform);
@@ -438,7 +440,6 @@
         doReturn(new LinkedList<Attribute>())
                 .when(mMockedAttributeDecoder)
                 .decodeAttributes(anyInt(), any());
-        Transform.sAttributeDecoder = mMockedAttributeDecoder;
 
         Transform transform = Transform.readFrom(inputBuffer);
         assertTrue(transform instanceof DhGroupTransform);
@@ -474,7 +475,6 @@
         doReturn(new LinkedList<Attribute>())
                 .when(mMockedAttributeDecoder)
                 .decodeAttributes(anyInt(), any());
-        Transform.sAttributeDecoder = mMockedAttributeDecoder;
 
         Transform transform = Transform.readFrom(inputBuffer);
         assertTrue(transform instanceof EsnTransform);
@@ -492,7 +492,6 @@
         doReturn(new LinkedList<Attribute>())
                 .when(mMockedAttributeDecoder)
                 .decodeAttributes(anyInt(), any());
-        Transform.sAttributeDecoder = mMockedAttributeDecoder;
 
         Transform transform = Transform.readFrom(inputBuffer);
         assertTrue(transform instanceof EsnTransform);
@@ -508,7 +507,6 @@
         doReturn(mAttributeListWithKeyLength128)
                 .when(mMockedAttributeDecoder)
                 .decodeAttributes(anyInt(), any());
-        Transform.sAttributeDecoder = mMockedAttributeDecoder;
 
         Transform transform = Transform.readFrom(inputBuffer);
         assertTrue(transform instanceof EsnTransform);
@@ -537,7 +535,6 @@
         doReturn(mAttributeListWithKeyLength128)
                 .when(mMockedAttributeDecoder)
                 .decodeAttributes(anyInt(), any());
-        Transform.sAttributeDecoder = mMockedAttributeDecoder;
 
         Transform transform = Transform.readFrom(inputBuffer);
 
@@ -554,7 +551,6 @@
         attributeList.add(mAttributeKeyLength128);
 
         doReturn(attributeList).when(mMockedAttributeDecoder).decodeAttributes(anyInt(), any());
-        Transform.sAttributeDecoder = mMockedAttributeDecoder;
 
         try {
             Transform.readFrom(inputBuffer);
@@ -572,7 +568,6 @@
         doReturn(mAttributeListWithKeyLength128)
                 .when(mMockedAttributeDecoder)
                 .decodeAttributes(anyInt(), any());
-        Transform.sAttributeDecoder = mMockedAttributeDecoder;
 
         Transform transform = Transform.readFrom(inputBuffer);
 
@@ -590,7 +585,6 @@
         attributeList.add(attributeUnrecognized);
 
         doReturn(attributeList).when(mMockedAttributeDecoder).decodeAttributes(anyInt(), any());
-        Transform.sAttributeDecoder = mMockedAttributeDecoder;
 
         Transform transform = Transform.readFrom(inputBuffer);
 
@@ -618,7 +612,7 @@
         assertEquals(mIntegHmacSha1Transform, mIntegHmacSha1TransformOther);
     }
 
-    private TransformDecoder getDummyTransformDecoder(Transform[] decodedTransforms) {
+    private TransformDecoder createTestTransformDecoder(Transform[] decodedTransforms) {
         return new TransformDecoder() {
             @Override
             public Transform[] decodeTransforms(int count, ByteBuffer inputBuffer)
@@ -639,7 +633,7 @@
     public void testDecodeSingleProposal() throws Exception {
         byte[] inputPacket = TestUtils.hexStringToByteArray(INBOUND_PROPOSAL_RAW_PACKET);
         ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket);
-        Proposal.sTransformDecoder = getDummyTransformDecoder(new Transform[0]);
+        Proposal.setTransformDecoder(createTestTransformDecoder(new Transform[0]));
 
         Proposal proposal = Proposal.readFrom(inputBuffer);
 
@@ -654,7 +648,7 @@
     @Test
     public void testDecodeSaRequestWithMultipleProposal() throws Exception {
         byte[] inputPacket = TestUtils.hexStringToByteArray(INBOUND_TWO_PROPOSAL_RAW_PACKET);
-        Proposal.sTransformDecoder = getDummyTransformDecoder(new Transform[0]);
+        Proposal.setTransformDecoder(createTestTransformDecoder(new Transform[0]));
 
         IkeSaPayload payload = new IkeSaPayload(false, false, inputPacket);
 
@@ -688,7 +682,7 @@
     @Test
     public void testDecodeSaResponseWithMultipleProposal() throws Exception {
         byte[] inputPacket = TestUtils.hexStringToByteArray(INBOUND_TWO_PROPOSAL_RAW_PACKET);
-        Proposal.sTransformDecoder = getDummyTransformDecoder(new Transform[0]);
+        Proposal.setTransformDecoder(createTestTransformDecoder(new Transform[0]));
 
         try {
             new IkeSaPayload(false, true, inputPacket);
@@ -772,7 +766,7 @@
     private void buildAndVerifyIkeSaRespProposal(
             byte[] saResponseBytes, Transform[] decodedTransforms) throws Exception {
         // Build response SA payload from decoding bytes.
-        Proposal.sTransformDecoder = getDummyTransformDecoder(decodedTransforms);
+        Proposal.setTransformDecoder(createTestTransformDecoder(decodedTransforms));
         IkeSaPayload respPayload = new IkeSaPayload(false, true, saResponseBytes);
 
         // Build request SA payload for IKE INIT exchange from SaProposal.
@@ -836,8 +830,8 @@
                         mTwoChildSaProposalsArray, mIpSecSpiGenerator, LOCAL_ADDRESS);
 
         // Build remote response
-        Proposal.sTransformDecoder =
-                getDummyTransformDecoder(mChildSaProposalOne.getAllTransforms());
+        Proposal.setTransformDecoder(
+                createTestTransformDecoder(mChildSaProposalOne.getAllTransforms()));
         IkeSaPayload respPayload =
                 new IkeSaPayload(
                         false /*critical*/,
@@ -858,7 +852,7 @@
                 transformsTwo, 0, decodedTransforms, transformsOne.length, transformsTwo.length);
 
         // Build remote request
-        Proposal.sTransformDecoder = getDummyTransformDecoder(decodedTransforms);
+        Proposal.setTransformDecoder(createTestTransformDecoder(decodedTransforms));
         IkeSaPayload reqPayload =
                 new IkeSaPayload(
                         false /*critical*/,
@@ -948,6 +942,9 @@
 
     @Test
     public void testDecodeSaPayloadWithUnsupportedTransformId() throws Exception {
+        Proposal.resetTransformDecoder();
+        Transform.resetAttributeDecoder();
+
         final String saPayloadBodyHex =
                 "0000002c010100040300000c0100000c800e0080030000080300000c"
                         + "0300000802000005000000080400001f";