Merge "Clean up the rerun script." into main
diff --git a/core/java/android/security/net/config/NetworkSecurityTrustManager.java b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
index d9cc82a..029b674 100644
--- a/core/java/android/security/net/config/NetworkSecurityTrustManager.java
+++ b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
@@ -16,16 +16,17 @@
 
 package android.security.net.config;
 
+import android.util.ArrayMap;
+
 import com.android.org.conscrypt.TrustManagerImpl;
 
-import android.util.ArrayMap;
 import java.io.IOException;
 import java.net.Socket;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
 import java.security.GeneralSecurityException;
 import java.security.KeyStore;
 import java.security.MessageDigest;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -105,7 +106,7 @@
 
     /**
      * Hostname aware version of {@link #checkServerTrusted(X509Certificate[], String)}.
-     * This interface is used by conscrypt and android.net.http.X509TrustManagerExtensions do not
+     * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
      * modify without modifying those callers.
      */
     public List<X509Certificate> checkServerTrusted(X509Certificate[] certs, String authType,
@@ -115,6 +116,19 @@
         return trustedChain;
     }
 
+    /**
+     * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
+     * modify without modifying those callers.
+     */
+    public List<X509Certificate> checkServerTrusted(X509Certificate[] certs,
+            byte[] ocspData, byte[] tlsSctData, String authType,
+            String host) throws CertificateException {
+        List<X509Certificate> trustedChain = mDelegate.checkServerTrusted(
+                certs, ocspData, tlsSctData, authType, host);
+        checkPins(trustedChain);
+        return trustedChain;
+    }
+
     private void checkPins(List<X509Certificate> chain) throws CertificateException {
         PinSet pinSet = mNetworkSecurityConfig.getPins();
         if (pinSet.pins.isEmpty()
diff --git a/core/java/android/security/net/config/OWNERS b/core/java/android/security/net/config/OWNERS
index 85ce3c6..e945ff9 100644
--- a/core/java/android/security/net/config/OWNERS
+++ b/core/java/android/security/net/config/OWNERS
@@ -1,5 +1,6 @@
-# Bug component: 36824
-set noparent
+# Bug component: 1479456
 
-cbrubaker@google.com
+bessiej@google.com
 brambonne@google.com
+sandrom@google.com
+tweek@google.com
diff --git a/core/java/android/security/net/config/RootTrustManager.java b/core/java/android/security/net/config/RootTrustManager.java
index 58dc4ba..a1bdec5 100644
--- a/core/java/android/security/net/config/RootTrustManager.java
+++ b/core/java/android/security/net/config/RootTrustManager.java
@@ -120,7 +120,7 @@
 
     /**
      * Hostname aware version of {@link #checkServerTrusted(X509Certificate[], String)}.
-     * This interface is used by conscrypt and android.net.http.X509TrustManagerExtensions do not
+     * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
      * modify without modifying those callers.
      */
     @UnsupportedAppUsage
@@ -134,6 +134,22 @@
         return config.getTrustManager().checkServerTrusted(certs, authType, hostname);
     }
 
+    /**
+     * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
+     * modify without modifying those callers.
+     */
+    public List<X509Certificate> checkServerTrusted(X509Certificate[] certs,
+            byte[] ocspData, byte[] tlsSctData, String authType,
+            String hostname) throws CertificateException {
+        if (hostname == null && mConfig.hasPerDomainConfigs()) {
+            throw new CertificateException(
+                    "Domain specific configurations require that the hostname be provided");
+        }
+        NetworkSecurityConfig config = mConfig.getConfigForHostname(hostname);
+        return config.getTrustManager().checkServerTrusted(
+                certs, ocspData, tlsSctData, authType, hostname);
+    }
+
     @Override
     public X509Certificate[] getAcceptedIssuers() {
         // getAcceptedIssuers is meant to be used to determine which trust anchors the server will
diff --git a/core/tests/coretests/src/android/net/http/OWNERS b/core/tests/coretests/src/android/net/http/OWNERS
new file mode 100644
index 0000000..c93a419
--- /dev/null
+++ b/core/tests/coretests/src/android/net/http/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/net/http/OWNERS
diff --git a/native/android/OWNERS b/native/android/OWNERS
index 1fde7d2..3ea2d35 100644
--- a/native/android/OWNERS
+++ b/native/android/OWNERS
@@ -29,6 +29,7 @@
 # Input
 per-file input.cpp = file:/INPUT_OWNERS
 
-# PerformanceHint
+# ADPF
 per-file performance_hint.cpp = file:/ADPF_OWNERS
+per-file system_health.cpp = file:/ADPF_OWNERS
 per-file thermal.cpp = file:/ADPF_OWNERS
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index 6bd6072..6e69da1 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -118,7 +118,7 @@
     method public void onNdefRead(@NonNull java.util.function.Consumer<java.lang.Boolean>);
     method public void onReaderOptionChanged(boolean);
     method public void onRfDiscoveryStarted(boolean);
-    method public void onRfFieldActivated(boolean);
+    method public void onRfFieldDetected(boolean);
     method public void onRoutingChanged(@NonNull java.util.function.Consumer<java.lang.Boolean>);
     method public void onRoutingTableFull();
     method public void onStateUpdated(int);
diff --git a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
index e5eac0b..357d322 100644
--- a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
+++ b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
@@ -45,7 +45,7 @@
    void onHceEventReceived(int action);
    void onReaderOptionChanged(boolean enabled);
    void onCardEmulationActivated(boolean isActivated);
-   void onRfFieldActivated(boolean isActivated);
+   void onRfFieldDetected(boolean isActive);
    void onRfDiscoveryStarted(boolean isDiscoveryStarted);
    void onEeListenActivated(boolean isActivated);
    void onEeUpdated();
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index b46e343..1fc0786 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -408,12 +408,12 @@
         void onCardEmulationActivated(boolean isActivated);
 
         /**
-        * Notifies the Remote NFC Endpoint RF Field is activated.
+        * Notifies the Remote NFC Endpoint RF Field is detected.
         * NFC Forum NCI-2.3 ch.5.3 specification
         *
-        * @param isActivated true, if RF Field is ON, else RF Field is OFF.
+        * @param isActive true, if RF Field is ON, else RF Field is OFF.
         */
-        void onRfFieldActivated(boolean isActivated);
+        void onRfFieldDetected(boolean isActive);
 
         /**
         * Notifies the NFC RF discovery is started or in the IDLE state.
@@ -596,7 +596,7 @@
             Log.i(TAG, "updateNfCState");
             executor.execute(() -> {
                 callback.onCardEmulationActivated(mCardEmulationActivated);
-                callback.onRfFieldActivated(mRfFieldActivated);
+                callback.onRfFieldDetected(mRfFieldActivated);
                 callback.onRfDiscoveryStarted(mRfDiscoveryStarted);
                 callback.onEeListenActivated(mEeListenActivated);
             });
@@ -936,10 +936,10 @@
         }
 
         @Override
-        public void onRfFieldActivated(boolean isActivated) throws RemoteException {
-            mRfFieldActivated = isActivated;
+        public void onRfFieldDetected(boolean isActive) throws RemoteException {
+            mRfFieldActivated = isActive;
             mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(isActivated, cb::onRfFieldActivated, ex));
+                    handleVoidCallback(isActive, cb::onRfFieldDetected, ex));
         }
 
         @Override
diff --git a/nfc/tests/src/android/nfc/NfcRoutingTableEntryTest.java b/nfc/tests/src/android/nfc/NfcRoutingTableEntryTest.java
new file mode 100644
index 0000000..a90a716
--- /dev/null
+++ b/nfc/tests/src/android/nfc/NfcRoutingTableEntryTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public final class NfcRoutingTableEntryTest {
+
+    @Test
+    public void testAidEntry_GetAid() {
+        String expectedAid = "A00000061A02";
+        RoutingTableAidEntry entry = new RoutingTableAidEntry(1, expectedAid, 0);
+
+        assertEquals(expectedAid, entry.getAid());
+    }
+
+    @Test
+    public void testProtocolEntry_GetProtocol() {
+        RoutingTableProtocolEntry entry =
+                new RoutingTableProtocolEntry(1, RoutingTableProtocolEntry.PROTOCOL_T1T, 0);
+
+        assertEquals(RoutingTableProtocolEntry.PROTOCOL_T1T, entry.getProtocol());
+    }
+
+    @Test
+    public void testSystemCodeEntry_GetSystemCode() {
+        byte[] expectedSystemCode = {0x01, 0x02, 0x03};
+        RoutingTableSystemCodeEntry entry =
+                new RoutingTableSystemCodeEntry(1, expectedSystemCode, 0);
+
+        assertArrayEquals(expectedSystemCode, entry.getSystemCode());
+    }
+
+    @Test
+    public void testTechnologyEntry_GetTechnology_A() {
+        RoutingTableTechnologyEntry entry =
+                new RoutingTableTechnologyEntry(1, RoutingTableTechnologyEntry.TECHNOLOGY_A, 0);
+
+        assertEquals(RoutingTableTechnologyEntry.TECHNOLOGY_A, entry.getTechnology());
+    }
+}
diff --git a/nfc/tests/src/android/nfc/OemLogItemsTest.java b/nfc/tests/src/android/nfc/OemLogItemsTest.java
new file mode 100644
index 0000000..21ef804
--- /dev/null
+++ b/nfc/tests/src/android/nfc/OemLogItemsTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.time.Instant;
+
+@RunWith(JUnit4.class)
+public final class OemLogItemsTest {
+
+    @Test
+    public void testGetAction() {
+        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_RF_FIELD_STATE_CHANGED)
+                .build();
+        assertEquals(OemLogItems.LOG_ACTION_RF_FIELD_STATE_CHANGED, item.getAction());
+    }
+
+    @Test
+    public void testGetEvent() {
+        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_NFC_TOGGLE)
+                .setCallingEvent(OemLogItems.EVENT_ENABLE)
+                .build();
+        assertEquals(OemLogItems.EVENT_ENABLE, item.getEvent());
+    }
+
+    @Test
+    public void testGetCallingPid() {
+        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_NFC_TOGGLE)
+                .setCallingPid(1234)
+                .build();
+        assertEquals(1234, item.getCallingPid());
+    }
+
+    @Test
+    public void testGetCommandApdu() {
+        byte[] commandApdu = {0x01, 0x02, 0x03};
+        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_HCE_DATA)
+                .setApduCommand(commandApdu)
+                .build();
+        assertArrayEquals(commandApdu, item.getCommandApdu());
+    }
+
+    @Test
+    public void testGetResponseApdu() {
+        byte[] responseApdu = {0x04, 0x05, 0x06};
+        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_HCE_DATA)
+                .setApduResponse(responseApdu)
+                .build();
+        assertArrayEquals(responseApdu, item.getResponseApdu());
+    }
+
+    @Test
+    public void testGetRfFieldEventTimeMillis() {
+        Instant expectedTime = Instant.ofEpochSecond(1688768000, 123456789);
+        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_RF_FIELD_STATE_CHANGED)
+                .setRfFieldOnTime(expectedTime)
+                .build();
+        assertEquals(expectedTime, item.getRfFieldEventTimeMillis());
+    }
+
+    @Test
+    public void testGetTag() {
+        Tag mockTag = mock(Tag.class);
+        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_TAG_DETECTED)
+                .setTag(mockTag)
+                .build();
+        assertEquals(mockTag, item.getTag());
+    }
+}
diff --git a/nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java b/nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java
index 6be95ad..4863206 100644
--- a/nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java
+++ b/nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java
@@ -18,17 +18,25 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.role.RoleManager;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.nfc.Constants;
 import android.nfc.INfcCardEmulation;
 import android.nfc.NfcAdapter;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.provider.Settings;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
@@ -43,6 +51,9 @@
 import org.mockito.MockitoSession;
 import org.mockito.quality.Strictness;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @RunWith(AndroidJUnit4.class)
 public class CardemulationTest {
 
@@ -61,6 +72,7 @@
     public void setUp() {
         mMockitoSession = ExtendedMockito.mockitoSession()
                 .mockStatic(NfcAdapter.class)
+                .mockStatic(Settings.Secure.class)
                 .strictness(Strictness.LENIENT)
                 .startMocking();
         MockitoAnnotations.initMocks(this);
@@ -110,4 +122,163 @@
         verify(mINfcCardEmulation).isDefaultServiceForAid(1, componentName,
                 "payment");
     }
+
+    @Test
+    public void testCategoryAllowsForegroundPreference() throws Settings.SettingNotFoundException {
+        when(mContext.createContextAsUser(any(), anyInt())).thenReturn(mContext);
+        RoleManager roleManager = mock(RoleManager.class);
+        when(roleManager.isRoleAvailable(RoleManager.ROLE_WALLET)).thenReturn(false);
+        when(mContext.getSystemService(RoleManager.class)).thenReturn(roleManager);
+        ContentResolver contentResolver = mock(ContentResolver.class);
+        when(mContext.getContentResolver()).thenReturn(contentResolver);
+        when(Settings.Secure.getInt(contentResolver, Constants
+                .SETTINGS_SECURE_NFC_PAYMENT_FOREGROUND)).thenReturn(1);
+        boolean result = mCardEmulation.categoryAllowsForegroundPreference("payment");
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void testGetSelectionModeForCategory() throws RemoteException {
+        when(mINfcCardEmulation.isDefaultPaymentRegistered()).thenReturn(true);
+        int result = mCardEmulation.getSelectionModeForCategory("payment");
+        assertThat(result).isEqualTo(0);
+    }
+
+    @Test
+    public void testSetShouldDefaultToObserveModeForService() throws RemoteException {
+        UserHandle userHandle = mock(UserHandle.class);
+        when(userHandle.getIdentifier()).thenReturn(1);
+        when(mContext.getUser()).thenReturn(userHandle);
+        ComponentName componentName = mock(ComponentName.class);
+        when(mINfcCardEmulation.setShouldDefaultToObserveModeForService(1, componentName, true))
+                .thenReturn(true);
+        boolean result = mCardEmulation
+                .setShouldDefaultToObserveModeForService(componentName, true);
+        assertThat(result).isTrue();
+        verify(mINfcCardEmulation).setShouldDefaultToObserveModeForService(1, componentName, true);
+    }
+
+    @Test
+    public void testRegisterPollingLoopFilterForService()throws RemoteException {
+        UserHandle userHandle = mock(UserHandle.class);
+        when(userHandle.getIdentifier()).thenReturn(1);
+        when(mContext.getUser()).thenReturn(userHandle);
+        ComponentName componentName = mock(ComponentName.class);
+        when(mINfcCardEmulation.registerPollingLoopFilterForService(anyInt(),
+                any(), anyString(), anyBoolean())).thenReturn(true);
+        boolean result = mCardEmulation.registerPollingLoopFilterForService(componentName,
+                "A0000000041010", true);
+        assertThat(result).isTrue();
+        verify(mINfcCardEmulation)
+                .registerPollingLoopFilterForService(anyInt(), any(), anyString(), anyBoolean());
+    }
+
+    @Test
+    public void testRemovePollingLoopFilterForService() throws RemoteException {
+        UserHandle userHandle = mock(UserHandle.class);
+        when(userHandle.getIdentifier()).thenReturn(1);
+        when(mContext.getUser()).thenReturn(userHandle);
+        ComponentName componentName = mock(ComponentName.class);
+        when(mINfcCardEmulation.removePollingLoopFilterForService(anyInt(), any(), anyString()))
+                .thenReturn(true);
+        boolean result = mCardEmulation
+                .removePollingLoopFilterForService(componentName, "A0000000041010");
+        assertThat(result).isTrue();
+        verify(mINfcCardEmulation).removePollingLoopFilterForService(anyInt(), any(), anyString());
+    }
+
+    @Test
+    public void testRegisterPollingLoopPatternFilterForService() throws RemoteException {
+        UserHandle userHandle = mock(UserHandle.class);
+        when(userHandle.getIdentifier()).thenReturn(1);
+        when(mContext.getUser()).thenReturn(userHandle);
+        ComponentName componentName = mock(ComponentName.class);
+        when(mINfcCardEmulation.registerPollingLoopPatternFilterForService(anyInt(), any(),
+                anyString(), anyBoolean())).thenReturn(true);
+        boolean result = mCardEmulation.registerPollingLoopPatternFilterForService(componentName,
+                "A0000000041010", true);
+        assertThat(result).isTrue();
+        verify(mINfcCardEmulation).registerPollingLoopPatternFilterForService(anyInt(), any(),
+                anyString(), anyBoolean());
+    }
+
+    @Test
+    public void testRemovePollingLoopPatternFilterForService() throws RemoteException {
+        UserHandle userHandle = mock(UserHandle.class);
+        when(userHandle.getIdentifier()).thenReturn(1);
+        when(mContext.getUser()).thenReturn(userHandle);
+        ComponentName componentName = mock(ComponentName.class);
+        when(mINfcCardEmulation.removePollingLoopPatternFilterForService(anyInt(), any(),
+                anyString())).thenReturn(true);
+        boolean result = mCardEmulation.removePollingLoopPatternFilterForService(componentName,
+                "A0000000041010");
+        assertThat(result).isTrue();
+        verify(mINfcCardEmulation).removePollingLoopPatternFilterForService(anyInt(), any(),
+                anyString());
+    }
+
+    @Test
+    public void testRegisterAidsForService() throws RemoteException {
+        UserHandle userHandle = mock(UserHandle.class);
+        when(userHandle.getIdentifier()).thenReturn(1);
+        when(mContext.getUser()).thenReturn(userHandle);
+        ComponentName componentName = mock(ComponentName.class);
+        when(mINfcCardEmulation.registerAidGroupForService(anyInt(), any(),
+                any())).thenReturn(true);
+        List<String> aids = new ArrayList<>();
+        aids.add("A0000000041010");
+        boolean result = mCardEmulation.registerAidsForService(componentName, "payment",
+                aids);
+        assertThat(result).isTrue();
+        verify(mINfcCardEmulation).registerAidGroupForService(anyInt(), any(),
+                any());
+    }
+
+    @Test
+    public void testUnsetOffHostForService() throws RemoteException {
+        UserHandle userHandle = mock(UserHandle.class);
+        when(userHandle.getIdentifier()).thenReturn(1);
+        when(mContext.getUser()).thenReturn(userHandle);
+        ComponentName componentName = mock(ComponentName.class);
+        when(mINfcCardEmulation.unsetOffHostForService(1, componentName)).thenReturn(true);
+        boolean result = mCardEmulation.unsetOffHostForService(componentName);
+        assertThat(result).isTrue();
+        verify(mINfcCardEmulation).unsetOffHostForService(1, componentName);
+    }
+
+    @Test
+    public void testSetOffHostForService() throws RemoteException {
+        UserHandle userHandle = mock(UserHandle.class);
+        when(userHandle.getIdentifier()).thenReturn(1);
+        when(mContext.getUser()).thenReturn(userHandle);
+        when(NfcAdapter.getDefaultAdapter(any())).thenReturn(mNfcAdapter);
+        List<String> elements = new ArrayList<>();
+        elements.add("eSE");
+        when(mNfcAdapter.getSupportedOffHostSecureElements()).thenReturn(elements);
+        ComponentName componentName = mock(ComponentName.class);
+        when(mINfcCardEmulation.setOffHostForService(anyInt(), any(), anyString()))
+                .thenReturn(true);
+        boolean result = mCardEmulation.setOffHostForService(componentName,
+                "eSE");
+        assertThat(result).isTrue();
+        verify(mINfcCardEmulation).setOffHostForService(anyInt(), any(), anyString());
+    }
+
+    @Test
+    public void testGetAidsForService() throws RemoteException {
+        UserHandle userHandle = mock(UserHandle.class);
+        when(userHandle.getIdentifier()).thenReturn(1);
+        when(mContext.getUser()).thenReturn(userHandle);
+        ComponentName componentName = mock(ComponentName.class);
+        List<String> elements = new ArrayList<>();
+        elements.add("eSE");
+        AidGroup aidGroup = mock(AidGroup.class);
+        when(aidGroup.getAids()).thenReturn(elements);
+        when(mINfcCardEmulation.getAidGroupForService(1, componentName, "payment"))
+                .thenReturn(aidGroup);
+        List<String> result = mCardEmulation.getAidsForService(componentName, "payment");
+        assertThat(result).isNotNull();
+        assertThat(result.size()).isGreaterThan(0);
+        verify(mINfcCardEmulation).getAidGroupForService(1, componentName, "payment");
+    }
 }
diff --git a/nfc/tests/src/android/nfc/dta/NfcDtaTest.java b/nfc/tests/src/android/nfc/dta/NfcDtaTest.java
new file mode 100644
index 0000000..38fb7ef
--- /dev/null
+++ b/nfc/tests/src/android/nfc/dta/NfcDtaTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.dta;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.nfc.INfcDta;
+import android.nfc.NfcAdapter;
+import android.os.RemoteException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class NfcDtaTest {
+    private final String mServiceName = "serviceName";
+    private final int mServiceSap = 1;
+    private final int mMiu = 1;
+    private final int mRwSize = 1;
+    private final int mTestCaseId = 1;
+    @Mock
+    private NfcAdapter mMockNfcAdapter;
+    @Mock
+    private INfcDta mMockService;
+    @Mock
+    private Context mMockContext;
+
+    private NfcDta mNfcDta;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        when(mMockNfcAdapter.getContext()).thenReturn(mMockContext);
+        when(mMockNfcAdapter.getNfcDtaInterface()).thenReturn(mMockService);
+
+        mNfcDta = NfcDta.getInstance(mMockNfcAdapter);
+    }
+
+    @Test
+    public void testEnableData() throws RemoteException {
+        assertTrue(mNfcDta.enableDta());
+        verify(mMockService).enableDta();
+    }
+
+    @Test
+    public void testEnableDataWithRemoteException() throws RemoteException {
+        doThrow(new RemoteException()).when(mMockService).enableDta();
+
+        assertFalse(mNfcDta.enableDta());
+        verify(mMockService).enableDta();
+    }
+
+    @Test
+    public void testDisableData() throws RemoteException {
+        assertTrue(mNfcDta.disableDta());
+        verify(mMockService).disableDta();
+    }
+
+    @Test
+    public void testDisableDataWithRemoteException() throws RemoteException {
+        doThrow(new RemoteException()).when(mMockService).disableDta();
+
+        assertFalse(mNfcDta.disableDta());
+        verify(mMockService).disableDta();
+    }
+
+    @Test
+    public void testEnableServer() throws RemoteException {
+        when(mMockService.enableServer(mServiceName, mServiceSap, mMiu, mRwSize,
+                mTestCaseId)).thenReturn(true);
+
+        mNfcDta.enableServer(mServiceName, mServiceSap, mMiu, mRwSize, mTestCaseId);
+        verify(mMockService).enableServer(mServiceName, mServiceSap, mMiu, mRwSize, mTestCaseId);
+    }
+
+    @Test
+    public void testEnableServerWithRemoteException() throws RemoteException {
+        doThrow(new RemoteException()).when(mMockService).enableServer(mServiceName, mServiceSap,
+                mMiu,
+                mRwSize, mTestCaseId);
+
+        mNfcDta.enableServer(mServiceName, mServiceSap, mMiu, mRwSize, mTestCaseId);
+        verify(mMockService).enableServer(mServiceName, mServiceSap, mMiu, mRwSize, mTestCaseId);
+    }
+
+    @Test
+    public void testDisableServer() throws RemoteException {
+        assertTrue(mNfcDta.disableServer());
+        verify(mMockService).disableServer();
+    }
+
+    @Test
+    public void testDisableServerWithRemoteException() throws RemoteException {
+        doThrow(new RemoteException()).when(mMockService).disableServer();
+
+        assertFalse(mNfcDta.disableServer());
+        verify(mMockService).disableServer();
+    }
+
+    @Test
+    public void testEnableClient() throws RemoteException {
+        when(mMockService.enableClient(mServiceName, mMiu, mRwSize, mTestCaseId)).thenReturn(true);
+
+        mNfcDta.enableClient(mServiceName, mMiu, mRwSize, mTestCaseId);
+        verify(mMockService).enableClient(mServiceName, mMiu, mRwSize, mTestCaseId);
+    }
+
+    @Test
+    public void testEnableClientWithRemoteException() throws RemoteException {
+        doThrow(new RemoteException()).when(mMockService).enableClient(mServiceName, mMiu, mRwSize,
+                mTestCaseId);
+
+        mNfcDta.enableClient(mServiceName, mMiu, mRwSize, mTestCaseId);
+        verify(mMockService).enableClient(mServiceName, mMiu, mRwSize, mTestCaseId);
+    }
+
+    @Test
+    public void testDisableClient() throws RemoteException {
+        assertTrue(mNfcDta.disableClient());
+        verify(mMockService).disableClient();
+    }
+
+    @Test
+    public void testDisableClientWithRemoteException() throws RemoteException {
+        doThrow(new RemoteException()).when(mMockService).disableClient();
+
+        assertFalse(mNfcDta.disableClient());
+        verify(mMockService).disableClient();
+    }
+
+    @Test
+    public void testRegisterMessageService() throws RemoteException {
+        String msgServiceName = "sampleServiceName";
+        when(mMockService.registerMessageService(msgServiceName)).thenReturn(true);
+
+        mNfcDta.registerMessageService(msgServiceName);
+        verify(mMockService).registerMessageService(msgServiceName);
+    }
+
+    @Test
+    public void testRegisterMessageServiceWithRemoteException() throws RemoteException {
+        String msgServiceName = "sampleServiceName";
+        doThrow(new RemoteException()).when(mMockService).registerMessageService(msgServiceName);
+
+        assertFalse(mNfcDta.registerMessageService(msgServiceName));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testGetInstanceWithNullPointerException() {
+        NfcDta.getInstance(null);
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testGetInstanceWithUnsupportedOperationExceptionForNfcAdapterContext() {
+        when(mMockNfcAdapter.getContext()).thenReturn(null);
+
+        NfcDta.getInstance(mMockNfcAdapter);
+    }
+}
diff --git a/nfc/tests/src/android/nfc/tech/NfcBarcodeTest.java b/nfc/tests/src/android/nfc/tech/NfcBarcodeTest.java
new file mode 100644
index 0000000..3aa4e2c
--- /dev/null
+++ b/nfc/tests/src/android/nfc/tech/NfcBarcodeTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.tech;
+
+import static android.nfc.tech.NfcBarcode.EXTRA_BARCODE_TYPE;
+import static android.nfc.tech.NfcBarcode.TYPE_KOVIO;
+import static android.nfc.tech.NfcBarcode.TYPE_UNKNOWN;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class NfcBarcodeTest {
+    @Mock
+    private Tag mMockTag;
+    @Mock
+    private Bundle mMockBundle;
+    private NfcBarcode mNfcBarcode;
+
+    @Before
+    public void setUp() throws RemoteException {
+        MockitoAnnotations.initMocks(this);
+        when(mMockBundle.getInt(EXTRA_BARCODE_TYPE)).thenReturn(TYPE_KOVIO);
+        when(mMockTag.getTechExtras(TagTechnology.NFC_BARCODE)).thenReturn(mMockBundle);
+
+        mNfcBarcode = new NfcBarcode(mMockTag);
+    }
+
+    @Test
+    public void testGetNfcBarcodeInstance() {
+        Tag mockTag = mock(Tag.class);
+        when(mockTag.hasTech(TagTechnology.NFC_BARCODE)).thenReturn(true);
+        when(mockTag.getTechExtras(TagTechnology.NFC_BARCODE)).thenReturn(mMockBundle);
+
+        assertNotNull(NfcBarcode.get(mockTag));
+        verify(mockTag).hasTech(TagTechnology.NFC_BARCODE);
+        verify(mockTag).getTechExtras(TagTechnology.NFC_BARCODE);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testGetNfcBarcodeInstanceWithException() {
+        Tag mockTag = mock(Tag.class);
+        when(mockTag.hasTech(TagTechnology.NFC_BARCODE)).thenReturn(true);
+        when(mockTag.getTechExtras(TagTechnology.NFC_BARCODE)).thenReturn(null);
+
+        assertNull(NfcBarcode.get(mockTag));
+        verify(mockTag).hasTech(TagTechnology.NFC_BARCODE);
+        verify(mockTag).getTechExtras(TagTechnology.NFC_BARCODE);
+    }
+
+    @Test
+    public void testGetNfcBarcodeWithoutTech() {
+        when(mMockTag.hasTech(TagTechnology.NFC_BARCODE)).thenReturn(false);
+
+        assertNull(NfcBarcode.get(mMockTag));
+    }
+
+    @Test
+    public void testGetType() {
+        int result = mNfcBarcode.getType();
+        assertEquals(TYPE_KOVIO, result);
+    }
+
+    @Test
+    public void testGetBarcodeWithTypeKovio() {
+        byte[] sampleId = "sampleId".getBytes();
+        when(mMockTag.getId()).thenReturn(sampleId);
+
+        assertEquals(sampleId, mNfcBarcode.getBarcode());
+        verify(mMockTag).getId();
+    }
+
+    @Test
+    public void testGetBarCodeTypeUnknown() throws RemoteException {
+        when(mMockBundle.getInt(EXTRA_BARCODE_TYPE)).thenReturn(TYPE_UNKNOWN);
+        when(mMockTag.getTechExtras(TagTechnology.NFC_BARCODE)).thenReturn(mMockBundle);
+        mNfcBarcode = new NfcBarcode(mMockTag);
+
+        assertNull(mNfcBarcode.getBarcode());
+        verify(mMockTag, never()).getId();
+    }
+}
diff --git a/nfc/tests/src/android/nfc/tech/NfcVTest.java b/nfc/tests/src/android/nfc/tech/NfcVTest.java
new file mode 100644
index 0000000..6a99921
--- /dev/null
+++ b/nfc/tests/src/android/nfc/tech/NfcVTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.tech;
+
+import static android.nfc.tech.NfcV.EXTRA_DSFID;
+import static android.nfc.tech.NfcV.EXTRA_RESP_FLAGS;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.nfc.INfcTag;
+import android.nfc.Tag;
+import android.nfc.TransceiveResult;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.IOException;
+
+public class NfcVTest {
+    private final byte mSampleRespFlags = (byte) 1;
+    private final byte mSampleDsfId = (byte) 2;
+    @Mock
+    private Tag mMockTag;
+    @Mock
+    private INfcTag mMockTagService;
+    @Mock
+    private Bundle mMockBundle;
+    private NfcV mNfcV;
+
+    @Before
+    public void setUp() throws RemoteException {
+        MockitoAnnotations.initMocks(this);
+        when(mMockBundle.getByte(EXTRA_RESP_FLAGS)).thenReturn(mSampleRespFlags);
+        when(mMockBundle.getByte(EXTRA_DSFID)).thenReturn(mSampleDsfId);
+        when(mMockTag.getTechExtras(TagTechnology.NFC_V)).thenReturn(mMockBundle);
+
+        mNfcV = new NfcV(mMockTag);
+    }
+
+    @Test
+    public void testGetResponseFlag() {
+        assertEquals(mSampleRespFlags, mNfcV.getResponseFlags());
+    }
+
+    @Test
+    public void testGetDsfId() {
+        assertEquals(mSampleDsfId, mNfcV.getDsfId());
+    }
+
+    @Test
+    public void testGetNfcVInstance() {
+        Tag tag = mock(Tag.class);
+        when(tag.hasTech(TagTechnology.NFC_V)).thenReturn(true);
+        when(tag.getTechExtras(TagTechnology.NFC_V)).thenReturn(mMockBundle);
+
+        assertNotNull(NfcV.get(tag));
+        verify(tag).getTechExtras(TagTechnology.NFC_V);
+        verify(tag).hasTech(TagTechnology.NFC_V);
+    }
+
+    @Test
+    public void testGetNfcVNullInstance() {
+        Tag tag = mock(Tag.class);
+        when(tag.hasTech(TagTechnology.NFC_V)).thenReturn(false);
+
+        assertNull(NfcV.get(tag));
+        verify(tag, never()).getTechExtras(TagTechnology.NFC_V);
+        verify(tag).hasTech(TagTechnology.NFC_V);
+    }
+
+    @Test
+    public void testTransceive() throws IOException, RemoteException {
+        byte[] sampleData = new byte[] {1, 2, 3, 4, 5};
+        TransceiveResult mockTransceiveResult = mock(TransceiveResult.class);
+        when(mMockTag.getConnectedTechnology()).thenReturn(TagTechnology.NFC_V);
+        when(mMockTag.getTagService()).thenReturn(mMockTagService);
+        when(mMockTag.getServiceHandle()).thenReturn(1);
+        when(mMockTagService.transceive(1, sampleData, true))
+                .thenReturn(mockTransceiveResult);
+        when(mockTransceiveResult.getResponseOrThrow()).thenReturn(sampleData);
+
+        mNfcV.transceive(sampleData);
+        verify(mMockTag).getTagService();
+        verify(mMockTag).getServiceHandle();
+    }
+
+    @Test
+    public void testGetMaxTransceiveLength() throws RemoteException {
+        when(mMockTag.getTagService()).thenReturn(mMockTagService);
+        when(mMockTagService.getMaxTransceiveLength(TagTechnology.NFC_V)).thenReturn(1);
+
+        mNfcV.getMaxTransceiveLength();
+        verify(mMockTag).getTagService();
+    }
+}
diff --git a/services/core/java/com/android/server/powerstats/PowerStatsLogger.java b/services/core/java/com/android/server/powerstats/PowerStatsLogger.java
index e80a86d..4fd026a 100644
--- a/services/core/java/com/android/server/powerstats/PowerStatsLogger.java
+++ b/services/core/java/com/android/server/powerstats/PowerStatsLogger.java
@@ -285,14 +285,20 @@
     }
 
     private void updateCacheFile(String cacheFilename, byte[] data) {
+        AtomicFile atomicCachedFile = null;
+        FileOutputStream fos = null;
         try {
-            final AtomicFile atomicCachedFile =
+            atomicCachedFile =
                     new AtomicFile(new File(mDataStoragePath, cacheFilename));
-            final FileOutputStream fos = atomicCachedFile.startWrite();
+            fos = atomicCachedFile.startWrite();
             fos.write(data);
             atomicCachedFile.finishWrite(fos);
         } catch (IOException e) {
             Slog.e(TAG, "Failed to write current data to cached file", e);
+            if (fos != null) {
+                atomicCachedFile.failWrite(fos);
+            }
+            return;
         }
     }