Merge "Test: separate common methods to EthernetTetheringTestBase"
diff --git a/Cronet/tests/cts/src/org/chromium/net/test/CronetApiTest.java b/Cronet/tests/cts/src/org/chromium/net/test/CronetApiTest.java
deleted file mode 100644
index 6465006..0000000
--- a/Cronet/tests/cts/src/org/chromium/net/test/CronetApiTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2019 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 org.chromium.net.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.os.Handler;
-import android.os.Looper;
-
-import androidx.annotation.NonNull;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.chromium.net.CronetEngine;
-import org.chromium.net.CronetException;
-import org.chromium.net.UrlRequest;
-import org.chromium.net.UrlResponseInfo;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.nio.ByteBuffer;
-import java.util.Random;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(AndroidJUnit4.class)
-public class CronetApiTest {
-    private static final String TAG = CronetApiTest.class.getSimpleName();
-    private static final String HTTPS_PREFIX = "https://";
-    private static final int TIMEOUT_MS = 12_000;
-
-    private final String[] mTestDomains = {"www.google.com", "www.android.com"};
-    @NonNull private CronetEngine mCronetEngine;
-    @NonNull private ConnectivityManager mCm;
-    @NonNull private Executor mExecutor;
-
-    @Before
-    public void setUp() throws Exception {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-        CronetEngine.Builder builder = new CronetEngine.Builder(context);
-        builder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024)
-                .enableHttp2(true)
-                // .enableBrotli(true)
-                .enableQuic(true);
-        mCronetEngine = builder.build();
-        mExecutor = new Handler(Looper.getMainLooper())::post;
-    }
-
-    private static void assertGreaterThan(String msg, int first, int second) {
-        assertTrue(msg + " Excepted " + first + " to be greater than " + second, first > second);
-    }
-
-    private void assertHasTestableNetworks() {
-        assertNotNull("This test requires a working Internet connection", mCm.getActiveNetwork());
-    }
-
-    private String getRandomDomain() {
-        int index = (new Random()).nextInt(mTestDomains.length);
-        return mTestDomains[index];
-    }
-
-    private static class TestUrlRequestCallback extends UrlRequest.Callback {
-        private final CountDownLatch mLatch = new CountDownLatch(1);
-        private final String mUrl;
-
-        TestUrlRequestCallback(@NonNull String url) {
-            this.mUrl = url;
-        }
-
-        public boolean waitForAnswer() throws InterruptedException {
-            return mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        }
-
-        @Override
-        public void onRedirectReceived(
-                UrlRequest request, UrlResponseInfo info, String newLocationUrl) {
-            request.followRedirect();
-        }
-
-        @Override
-        public void onResponseStarted(UrlRequest request, UrlResponseInfo info) {
-            request.read(ByteBuffer.allocateDirect(32 * 1024));
-        }
-
-        @Override
-        public void onReadCompleted(
-                UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer) {
-            byteBuffer.clear();
-            request.read(byteBuffer);
-        }
-
-        @Override
-        public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
-            assertEquals(
-                    "Unexpected http status code from " + mUrl + ".",
-                    200,
-                    info.getHttpStatusCode());
-            assertGreaterThan(
-                    "Received byte from " + mUrl + " is 0.", (int) info.getReceivedByteCount(), 0);
-            mLatch.countDown();
-        }
-
-        @Override
-        public void onFailed(UrlRequest request, UrlResponseInfo info, CronetException error) {
-            fail(mUrl + error.getMessage());
-        }
-    }
-
-    @Test
-    public void testUrlRequestGet_CompletesSuccessfully() throws Exception {
-        assertHasTestableNetworks();
-        String url = HTTPS_PREFIX + getRandomDomain();
-        TestUrlRequestCallback callback = new TestUrlRequestCallback(url);
-        UrlRequest.Builder builder = mCronetEngine.newUrlRequestBuilder(url, callback, mExecutor);
-        builder.build().start();
-        assertTrue(url + " but not complete after " + TIMEOUT_MS + "ms.", callback.waitForAnswer());
-    }
-}
diff --git a/Cronet/tests/cts/src/org/chromium/net/test/CronetUrlRequestTest.java b/Cronet/tests/cts/src/org/chromium/net/test/CronetUrlRequestTest.java
new file mode 100644
index 0000000..7dd9a9a
--- /dev/null
+++ b/Cronet/tests/cts/src/org/chromium/net/test/CronetUrlRequestTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2019 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 org.chromium.net.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+
+import androidx.annotation.NonNull;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.chromium.net.CronetEngine;
+import org.chromium.net.UrlRequest;
+import org.chromium.net.UrlResponseInfo;
+import org.chromium.net.test.util.TestUrlRequestCallback;
+import org.chromium.net.test.util.TestUrlRequestCallback.ResponseStep;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Random;
+
+@RunWith(AndroidJUnit4.class)
+public class CronetUrlRequestTest {
+    private static final String TAG = CronetUrlRequestTest.class.getSimpleName();
+    private static final String HTTPS_PREFIX = "https://";
+
+    private final String[] mTestDomains = {"www.google.com", "www.android.com"};
+    @NonNull private CronetEngine mCronetEngine;
+    @NonNull private ConnectivityManager mCm;
+
+    @Before
+    public void setUp() throws Exception {
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        CronetEngine.Builder builder = new CronetEngine.Builder(context);
+        builder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024)
+                .enableHttp2(true)
+                // .enableBrotli(true)
+                .enableQuic(true);
+        mCronetEngine = builder.build();
+    }
+
+    private static void assertGreaterThan(String msg, int first, int second) {
+        assertTrue(msg + " Excepted " + first + " to be greater than " + second, first > second);
+    }
+
+    private void assertHasTestableNetworks() {
+        assertNotNull("This test requires a working Internet connection", mCm.getActiveNetwork());
+    }
+
+    private String getRandomDomain() {
+        int index = (new Random()).nextInt(mTestDomains.length);
+        return mTestDomains[index];
+    }
+
+    @Test
+    public void testUrlRequestGet_CompletesSuccessfully() throws Exception {
+        assertHasTestableNetworks();
+        String url = HTTPS_PREFIX + getRandomDomain();
+        TestUrlRequestCallback callback = new TestUrlRequestCallback();
+        UrlRequest.Builder builder = mCronetEngine.newUrlRequestBuilder(url, callback,
+                callback.getExecutor());
+        builder.build().start();
+
+        callback.expectCallback(ResponseStep.ON_SUCCEEDED);
+
+        UrlResponseInfo info = callback.mResponseInfo;
+        assertEquals("Unexpected http status code from " + url + ".", 200,
+                info.getHttpStatusCode());
+        assertGreaterThan(
+                "Received byte from " + url + " is 0.", (int) info.getReceivedByteCount(), 0);
+    }
+}
diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index b1bee32..829e66a 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -75,7 +75,6 @@
     libs: [
         "framework-tethering.impl",
     ],
-    plugins: ["java_api_finder"],
     manifest: "AndroidManifestBase.xml",
     lint: { strict_updatability_linting: true },
 }
diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index 0a34669..8cf13d3 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -378,6 +378,11 @@
         return Collections.unmodifiableList(mDhcpLeases);
     }
 
+    /** Enable this IpServer. IpServer state machine will be tethered or localHotspot state. */
+    public void enable(final int requestedState, final TetheringRequestParcel request) {
+        sendMessage(CMD_TETHER_REQUESTED, requestedState, 0, request);
+    }
+
     /** Stop this IpServer. After this is called this IpServer should not be used any more. */
     public void stop() {
         sendMessage(CMD_INTERFACE_DOWN);
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index c2cf92c..f0dd030 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -1001,8 +1001,7 @@
         if (request != null) {
             mActiveTetheringRequests.delete(type);
         }
-        tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_REQUESTED, requestedState, 0,
-                request);
+        tetherState.ipServer.enable(requestedState, request);
         return TETHER_ERROR_NO_ERROR;
     }
 
@@ -1026,7 +1025,7 @@
             Log.e(TAG, "Tried to untether an inactive iface :" + iface + ", ignoring");
             return TETHER_ERROR_UNAVAIL_IFACE;
         }
-        tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_UNREQUESTED);
+        tetherState.ipServer.unwanted();
         return TETHER_ERROR_NO_ERROR;
     }
 
@@ -1087,8 +1086,6 @@
         final ArrayList<TetheringInterface> errored = new ArrayList<>();
         final ArrayList<Integer> lastErrors = new ArrayList<>();
 
-        final TetheringConfiguration cfg = mConfig;
-
         int downstreamTypesMask = DOWNSTREAM_NONE;
         for (int i = 0; i < mTetherStates.size(); i++) {
             final TetherState tetherState = mTetherStates.valueAt(i);
diff --git a/framework-t/src/android/net/NetworkIdentity.java b/framework-t/src/android/net/NetworkIdentity.java
index 48e5092..edfd21c 100644
--- a/framework-t/src/android/net/NetworkIdentity.java
+++ b/framework-t/src/android/net/NetworkIdentity.java
@@ -400,10 +400,8 @@
             setSubscriberId(snapshot.getSubscriberId());
             setRoaming(!snapshot.getNetworkCapabilities().hasCapability(
                     NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING));
-            setMetered(!(snapshot.getNetworkCapabilities().hasCapability(
-                    NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
-                    || snapshot.getNetworkCapabilities().hasCapability(
-                    NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)));
+            setMetered(!snapshot.getNetworkCapabilities().hasCapability(
+                    NetworkCapabilities.NET_CAPABILITY_NOT_METERED));
 
             setOemManaged(getOemBitfield(snapshot.getNetworkCapabilities()));
 
diff --git a/nearby/halfsheet/Android.bp b/nearby/halfsheet/Android.bp
index c84caa6..2d0d327 100644
--- a/nearby/halfsheet/Android.bp
+++ b/nearby/halfsheet/Android.bp
@@ -43,7 +43,6 @@
         "com.google.android.material_material",
         "fast-pair-lite-protos",
     ],
-    plugins: ["java_api_finder"],
     manifest: "AndroidManifest.xml",
     jarjar_rules: ":nearby-jarjar-rules",
     apex_available: ["com.android.tethering",],
diff --git a/nearby/halfsheet/res/values-en-rCA/strings.xml b/nearby/halfsheet/res/values-en-rCA/strings.xml
index d4ed675..6094199 100644
--- a/nearby/halfsheet/res/values-en-rCA/strings.xml
+++ b/nearby/halfsheet/res/values-en-rCA/strings.xml
@@ -17,7 +17,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="fast_pair_setup_in_progress" msgid="4158762239172829807">"Starting setup…"</string>
+    <string name="fast_pair_setup_in_progress" msgid="4158762239172829807">"Starting Setup…"</string>
     <string name="fast_pair_title_setup" msgid="2894360355540593246">"Set up device"</string>
     <string name="fast_pair_device_ready" msgid="2903490346082833101">"Device connected"</string>
     <string name="fast_pair_title_fail" msgid="5677174346601290232">"Couldn\'t connect"</string>
diff --git a/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml b/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml
index c490cf8..9827f4e 100644
--- a/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml
+++ b/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml
@@ -17,20 +17,20 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="connectivityResourcesAppLabel" msgid="2476261877900882974">"System connectivity resources"</string>
-    <string name="wifi_available_sign_in" msgid="8041178343789805553">"Sign in to a Wi-Fi network"</string>
+    <string name="connectivityResourcesAppLabel" msgid="2476261877900882974">"System Connectivity Resources"</string>
+    <string name="wifi_available_sign_in" msgid="8041178343789805553">"Sign in to Wi-Fi network"</string>
     <string name="network_available_sign_in" msgid="2622520134876355561">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8439369644697866359) -->
     <skip />
-    <string name="wifi_no_internet" msgid="1326348603404555475">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
+    <string name="wifi_no_internet" msgid="1326348603404555475">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no internet access"</string>
     <string name="wifi_no_internet_detailed" msgid="1746921096565304090">"Tap for options"</string>
-    <string name="mobile_no_internet" msgid="4087718456753201450">"Mobile network has no Internet access"</string>
-    <string name="other_networks_no_internet" msgid="5693932964749676542">"Network has no Internet access"</string>
+    <string name="mobile_no_internet" msgid="4087718456753201450">"Mobile network has no internet access"</string>
+    <string name="other_networks_no_internet" msgid="5693932964749676542">"Network has no internet access"</string>
     <string name="private_dns_broken_detailed" msgid="2677123850463207823">"Private DNS server cannot be accessed"</string>
     <string name="network_partial_connectivity" msgid="5549503845834993258">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
     <string name="network_partial_connectivity_detailed" msgid="4732435946300249845">"Tap to connect anyway"</string>
     <string name="network_switch_metered" msgid="5016937523571166319">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1257300152739542096">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
+    <string name="network_switch_metered_detail" msgid="1257300152739542096">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no internet access. Charges may apply."</string>
     <string name="network_switch_metered_toast" msgid="70691146054130335">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
     <item msgid="3004933964374161223">"mobile data"</item>
diff --git a/service/ServiceConnectivityResources/res/values-eu/strings.xml b/service/ServiceConnectivityResources/res/values-eu/strings.xml
index 2c4e431..9b39fd3 100644
--- a/service/ServiceConnectivityResources/res/values-eu/strings.xml
+++ b/service/ServiceConnectivityResources/res/values-eu/strings.xml
@@ -35,7 +35,7 @@
   <string-array name="network_switch_type_name">
     <item msgid="3004933964374161223">"datu-konexioa"</item>
     <item msgid="5624324321165953608">"Wifia"</item>
-    <item msgid="5667906231066981731">"Bluetooth-a"</item>
+    <item msgid="5667906231066981731">"Bluetootha"</item>
     <item msgid="346574747471703768">"Ethernet-a"</item>
     <item msgid="5734728378097476003">"VPNa"</item>
   </string-array>
diff --git a/service/ServiceConnectivityResources/res/values-nb/strings.xml b/service/ServiceConnectivityResources/res/values-nb/strings.xml
index 4439048..fff6530 100644
--- a/service/ServiceConnectivityResources/res/values-nb/strings.xml
+++ b/service/ServiceConnectivityResources/res/values-nb/strings.xml
@@ -18,7 +18,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="connectivityResourcesAppLabel" msgid="2476261877900882974">"Ressurser for systemtilkobling"</string>
-    <string name="wifi_available_sign_in" msgid="8041178343789805553">"Logg på Wi-Fi-nettverket"</string>
+    <string name="wifi_available_sign_in" msgid="8041178343789805553">"Logg på Wifi-nettverket"</string>
     <string name="network_available_sign_in" msgid="2622520134876355561">"Logg på nettverk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8439369644697866359) -->
     <skip />
diff --git a/service/ServiceConnectivityResources/res/values-ro/strings.xml b/service/ServiceConnectivityResources/res/values-ro/strings.xml
index 4ff5290..bf4479a 100644
--- a/service/ServiceConnectivityResources/res/values-ro/strings.xml
+++ b/service/ServiceConnectivityResources/res/values-ro/strings.xml
@@ -28,7 +28,7 @@
     <string name="other_networks_no_internet" msgid="5693932964749676542">"Rețeaua nu are acces la internet"</string>
     <string name="private_dns_broken_detailed" msgid="2677123850463207823">"Serverul DNS privat nu poate fi accesat"</string>
     <string name="network_partial_connectivity" msgid="5549503845834993258">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> are conectivitate limitată"</string>
-    <string name="network_partial_connectivity_detailed" msgid="4732435946300249845">"Atingeți pentru a vă conecta oricum"</string>
+    <string name="network_partial_connectivity_detailed" msgid="4732435946300249845">"Atinge pentru a te conecta oricum"</string>
     <string name="network_switch_metered" msgid="5016937523571166319">"S-a comutat la <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
     <string name="network_switch_metered_detail" msgid="1257300152739542096">"Dispozitivul folosește <xliff:g id="NEW_NETWORK">%1$s</xliff:g> când <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nu are acces la internet. Se pot aplica taxe."</string>
     <string name="network_switch_metered_toast" msgid="70691146054130335">"S-a comutat de la <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> la <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 9b23395..4c9e3a3 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -75,7 +75,6 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_5;
@@ -251,6 +250,7 @@
 import com.android.modules.utils.BasicShellCommandHandler;
 import com.android.modules.utils.build.SdkLevel;
 import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
+import com.android.net.module.util.BinderUtils;
 import com.android.net.module.util.BitUtils;
 import com.android.net.module.util.CollectionUtils;
 import com.android.net.module.util.DeviceConfigUtils;
@@ -5162,7 +5162,9 @@
             description = settingValue + " (?)";
         }
         pw.println("Avoid bad wifi setting:        " + description);
-        final Boolean configValue = mMultinetworkPolicyTracker.deviceConfigActivelyPreferBadWifi();
+
+        final Boolean configValue = BinderUtils.withCleanCallingIdentity(
+                () -> mMultinetworkPolicyTracker.deviceConfigActivelyPreferBadWifi());
         if (null == configValue) {
             description = "unset";
         } else if (configValue) {
@@ -8062,10 +8064,6 @@
         final boolean oldMetered = prevNc.isMetered();
         final boolean newMetered = newNc.isMetered();
         final boolean meteredChanged = oldMetered != newMetered;
-        final boolean oldTempMetered = prevNc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
-        final boolean newTempMetered = newNc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
-        final boolean tempMeteredChanged = oldTempMetered != newTempMetered;
-
 
         if (meteredChanged) {
             maybeNotifyNetworkBlocked(nai, oldMetered, newMetered,
@@ -8076,7 +8074,7 @@
                 != newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
 
         // Report changes that are interesting for network statistics tracking.
-        if (meteredChanged || roamingChanged || tempMeteredChanged) {
+        if (meteredChanged || roamingChanged) {
             notifyIfacesChangedForNetworkStats();
         }
 
diff --git a/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java b/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
index e2821cb..3c71c90 100644
--- a/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
@@ -155,6 +155,13 @@
         // removing data activity tracking.
         mCtsNetUtils.ensureWifiConnected();
 
+        // There's rate limit to update mobile battery so if ConnectivityService calls
+        // BatteryStatsManager.reportMobileRadioPowerState when default network changed,
+        // the mobile stats might not be updated. But if the mobile update due to other
+        // reasons (plug/unplug, battery level change, etc) will be unaffected. Thus here
+        // dumps the battery stats to trigger a full sync of data.
+        executeShellCommand("dumpsys batterystats");
+
         // Check cellular battery stats are updated.
         runAsShell(UPDATE_DEVICE_STATS,
                 () -> assertStatsEventually(mBsm::getCellularBatteryStats,
diff --git a/tests/unit/java/android/net/NetworkIdentityTest.kt b/tests/unit/java/android/net/NetworkIdentityTest.kt
index d84328c..9667f8f 100644
--- a/tests/unit/java/android/net/NetworkIdentityTest.kt
+++ b/tests/unit/java/android/net/NetworkIdentityTest.kt
@@ -101,15 +101,15 @@
                 false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
         assertFalse(netIdent2.isMetered())
 
-        // Verify network is not metered because it has NET_CAPABILITY_TEMPORARILY_NOT_METERED
-        // capability .
+        // In current design, a network that has NET_CAPABILITY_TEMPORARILY_NOT_METERED
+        // capability will be treated as metered.
         val capsTempNotMetered = NetworkCapabilities().apply {
             setCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED, true)
         }
         val netIdent3 = NetworkIdentity.buildNetworkIdentity(mockContext,
                 buildMobileNetworkStateSnapshot(capsTempNotMetered, TEST_IMSI1),
                 false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
-        assertFalse(netIdent3.isMetered())
+        assertTrue(netIdent3.isMetered())
     }
 
     @Test
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index f80b9bd..67cc7bd 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -7336,10 +7336,11 @@
         expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME);
         reset(mStatsManager);
 
-        // Temp metered change should update ifaces
+        // Temp metered change shouldn't update ifaces
         mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
         waitForIdle();
-        expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME);
+        verify(mStatsManager, never()).notifyNetworkStatus(eq(onlyCell()),
+                any(List.class), eq(MOBILE_IFNAME), any(List.class));
         reset(mStatsManager);
 
         // Congested change shouldn't update ifaces
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
index e8f30d6..d7c90d8 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -995,8 +995,8 @@
         forcePollAndWaitForIdle();
 
         // Verify service recorded history.
-        assertUidTotal(templateMetered5g, UID_RED, 128L, 2L, 128L, 2L, 0);
-        assertUidTotal(templateNonMetered5g, UID_RED, 256, 3L, 128L, 5L, 0);
+        assertUidTotal(templateMetered5g, UID_RED, 384L, 5L, 256L, 7L, 0);
+        assertUidTotal(templateNonMetered5g, UID_RED, 0L, 0L, 0L, 0L, 0);
     }
 
     @Test
diff --git a/tools/gn2bp/Android.bp.swp b/tools/gn2bp/Android.bp.swp
index 990bbbe..f8f2b6a 100644
--- a/tools/gn2bp/Android.bp.swp
+++ b/tools/gn2bp/Android.bp.swp
@@ -2356,31 +2356,10 @@
         "base/metrics/histogram_base.h",
         "base/task/task_traits.h",
         "build/android/gyp/java_cpp_enum.py",
-    ],
-}
-
-// GN: //base:base_java_aidl
-java_genrule {
-    name: "cronet_aml_base_base_java_aidl",
-    cmd: "$(location build/android/gyp/aidl.py) --aidl-path " +
-         "../../third_party/android_sdk/public/build-tools/33.0.0/aidl " +
-         "--imports " +
-         "["../../third_party/android_sdk/public/platforms/android-33/framework.aidl"] " +
-         "--srcjar " +
-         "gen/base/base_java_aidl.srcjar " +
-         "--depfile " +
-         "gen/base/base_java_aidl.d " +
-         "--includes " +
-         "["../../base/android/java/src"] " +
-         "../../base/android/java/src/org/chromium/base/process_launcher/IChildProcessService.aidl " +
-         "../../base/android/java/src/org/chromium/base/process_launcher/IParentProcess.aidl",
-    out: [
-        "base/base_java_aidl.srcjar",
-    ],
-    tool_files: [
-        "base/android/java/src/org/chromium/base/process_launcher/IChildProcessService.aidl",
-        "base/android/java/src/org/chromium/base/process_launcher/IParentProcess.aidl",
-        "build/android/gyp/aidl.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
     ],
 }
 
@@ -4231,18 +4210,22 @@
         "base/task/task_features.cc",
     ],
     cmd: "$(location build/android/gyp/java_cpp_features.py) --srcjar " +
-         "gen/base/java_features_srcjar.srcjar " +
+         "$(out) " +
          "--template " +
-         "../../base/android/java/src/org/chromium/base/BaseFeatures.java.tmpl " +
-         "../../base/android/base_features.cc " +
-         "../../base/features.cc " +
-         "../../base/task/task_features.cc",
+         "$(location base/android/java/src/org/chromium/base/BaseFeatures.java.tmpl) " +
+         "$(location base/android/base_features.cc) " +
+         "$(location base/features.cc) " +
+         "$(location base/task/task_features.cc)",
     out: [
         "base/java_features_srcjar.srcjar",
     ],
     tool_files: [
         "base/android/java/src/org/chromium/base/BaseFeatures.java.tmpl",
         "build/android/gyp/java_cpp_features.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
     ],
 }
 
@@ -4253,16 +4236,20 @@
         "base/base_switches.cc",
     ],
     cmd: "$(location build/android/gyp/java_cpp_strings.py) --srcjar " +
-         "gen/base/java_switches_srcjar.srcjar " +
+         "$(out) " +
          "--template " +
-         "../../base/android/java/src/org/chromium/base/BaseSwitches.java.tmpl " +
-         "../../base/base_switches.cc",
+         "$(location base/android/java/src/org/chromium/base/BaseSwitches.java.tmpl) " +
+         "$(location base/base_switches.cc)",
     out: [
         "base/java_switches_srcjar.srcjar",
     ],
     tool_files: [
         "base/android/java/src/org/chromium/base/BaseSwitches.java.tmpl",
         "build/android/gyp/java_cpp_strings.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
     ],
 }
 
@@ -5687,7 +5674,7 @@
 java_genrule {
     name: "cronet_aml_build_android_build_config_gen",
     cmd: "$(location build/android/gyp/gcc_preprocess.py) --include-dirs " +
-         "["../../", "gen"] " +
+         "[\"../../\", \"gen\"] " +
          "--output " +
          "gen/build/android/build_config_gen.srcjar " +
          "--define " +
@@ -5698,7 +5685,10 @@
     ],
     tool_files: [
         "build/android/gyp/gcc_preprocess.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
         "build/android/java/templates/BuildConfig.template",
+        "build/gn_helpers.py",
     ],
 }
 
@@ -5706,7 +5696,7 @@
 java_genrule {
     name: "cronet_aml_build_android_native_libraries_gen",
     cmd: "$(location build/android/gyp/write_native_libraries_java.py) --output " +
-         "gen/build/android/native_libraries_gen.srcjar " +
+         "$(out) " +
          "--cpu-family " +
          "CPU_FAMILY_ARM",
     out: [
@@ -7373,7 +7363,7 @@
 
 // GN: //components/cronet/android:cronet_jni_registration
 java_genrule {
-    name: "cronet_aml_components_cronet_android_cronet_jni_registration_java",
+    name: "cronet_aml_components_cronet_android_cronet_jni_registration__java",
     srcs: [
         "base/android/java/src/org/chromium/base/ActivityState.java",
         "base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java",
@@ -7674,9 +7664,6 @@
         "build/android/gyp/util/build_utils.py",
         "build/gn_helpers.py",
     ],
-    apex_available: [
-        "com.android.tethering",
-    ],
 }
 
 // GN: //components/cronet/android:cronet_static
@@ -7832,6 +7819,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "components/cronet/url_request_context_config.h",
     ],
 }
@@ -7844,7 +7835,7 @@
          "-f " +
          "$(location build/util/LASTCHANGE) " +
          "-e " +
-         "API_LEVEL='20' " +
+         "'API_LEVEL=20' " +
          "-o " +
          "$(out) " +
          "$(location components/cronet/android/java/src/org/chromium/net/impl/ImplVersion.template)",
@@ -7864,7 +7855,7 @@
 java_genrule {
     name: "cronet_aml_components_cronet_android_integrated_mode_state",
     cmd: "$(location build/android/gyp/gcc_preprocess.py) --include-dirs " +
-         "["../../", "gen"] " +
+         "[\"../../\", \"gen\"] " +
          "--output " +
          "gen/components/cronet/android/integrated_mode_state.srcjar " +
          "../../components/cronet/android/java/src/org/chromium/net/impl/IntegratedModeState.template",
@@ -7873,6 +7864,9 @@
     ],
     tool_files: [
         "build/android/gyp/gcc_preprocess.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/gn_helpers.py",
         "components/cronet/android/java/src/org/chromium/net/impl/IntegratedModeState.template",
     ],
 }
@@ -7885,7 +7879,7 @@
          "-f " +
          "$(location build/util/LASTCHANGE) " +
          "-e " +
-         "API_LEVEL='20' " +
+         "'API_LEVEL=20' " +
          "-o " +
          "$(out) " +
          "$(location components/cronet/android/api/src/org/chromium/net/ApiVersion.template)",
@@ -7905,7 +7899,7 @@
 java_genrule {
     name: "cronet_aml_components_cronet_android_load_states_list",
     cmd: "$(location build/android/gyp/gcc_preprocess.py) --include-dirs " +
-         "["../../", "gen"] " +
+         "[\"../../\", \"gen\"] " +
          "--output " +
          "gen/components/cronet/android/load_states_list.srcjar " +
          "../../components/cronet/android/java/src/org/chromium/net/impl/LoadState.template",
@@ -7914,7 +7908,11 @@
     ],
     tool_files: [
         "build/android/gyp/gcc_preprocess.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/gn_helpers.py",
         "components/cronet/android/java/src/org/chromium/net/impl/LoadState.template",
+        "net/base/load_states_list.h",
     ],
 }
 
@@ -7929,6 +7927,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "net/base/idempotency.h",
     ],
 }
@@ -7944,6 +7946,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "net/base/request_priority.h",
     ],
 }
@@ -7959,6 +7965,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "net/nqe/network_quality_observation_source.h",
     ],
 }
@@ -7974,6 +7984,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "net/nqe/network_quality.h",
     ],
 }
@@ -7989,6 +8003,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "components/cronet/android/url_request_error.h",
     ],
 }
@@ -8264,7 +8282,7 @@
     cmd: "$(location build/util/version.py) -f " +
          "$(location chrome/VERSION) " +
          "-e " +
-         "VERSION_FULL='\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH)' " +
+         "'VERSION_FULL=\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH)' " +
          "-o " +
          "$(out) " +
          "$(location components/cronet/version.h.in)",
@@ -8289,7 +8307,7 @@
     cmd: "$(location build/util/version.py) -f " +
          "$(location chrome/VERSION) " +
          "-e " +
-         "VERSION_FULL='\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH)' " +
+         "'VERSION_FULL=\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH)' " +
          "-o " +
          "$(out) " +
          "$(location components/cronet/version.h.in)",
@@ -8314,7 +8332,7 @@
     cmd: "$(location build/util/version.py) -f " +
          "$(location chrome/VERSION) " +
          "-e " +
-         "VERSION_FULL='\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH)' " +
+         "'VERSION_FULL=\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH)' " +
          "-o " +
          "$(out) " +
          "$(location components/cronet/version.h.in)",
@@ -8339,7 +8357,7 @@
     cmd: "$(location build/util/version.py) -f " +
          "$(location chrome/VERSION) " +
          "-e " +
-         "VERSION_FULL='\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH)' " +
+         "'VERSION_FULL=\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH)' " +
          "-o " +
          "$(out) " +
          "$(location components/cronet/version.h.in)",
@@ -9604,6 +9622,8 @@
         "base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionFactory.java",
         "base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionImpl.java",
         "base/android/java/src/org/chromium/base/process_launcher/FileDescriptorInfo.java",
+        "base/android/java/src/org/chromium/base/process_launcher/IChildProcessService.aidl",
+        "base/android/java/src/org/chromium/base/process_launcher/IParentProcess.aidl",
         "base/android/java/src/org/chromium/base/supplier/BooleanSupplier.java",
         "base/android/java/src/org/chromium/base/supplier/DestroyableObservableSupplier.java",
         "base/android/java/src/org/chromium/base/supplier/ObservableSupplier.java",
@@ -9768,6 +9788,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "net/android/cert_verify_result_android.h",
         "net/android/keystore.h",
         "net/base/network_change_notifier.h",
@@ -9778,7 +9802,7 @@
 java_genrule {
     name: "cronet_aml_net_android_net_errors_java",
     cmd: "$(location build/android/gyp/gcc_preprocess.py) --include-dirs " +
-         "["../../", "gen"] " +
+         "[\"../../\", \"gen\"] " +
          "--output " +
          "gen/net/android/net_errors_java.srcjar " +
          "../../net/android/java/NetError.template",
@@ -9787,7 +9811,11 @@
     ],
     tool_files: [
         "build/android/gyp/gcc_preprocess.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/gn_helpers.py",
         "net/android/java/NetError.template",
+        "net/base/net_error_list.h",
     ],
 }
 
@@ -11093,6 +11121,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "net/nqe/effective_connection_type.h",
     ],
 }
diff --git a/tools/gn2bp/gen_android_bp b/tools/gn2bp/gen_android_bp
index ce71938..233e6f8 100755
--- a/tools/gn2bp/gen_android_bp
+++ b/tools/gn2bp/gen_android_bp
@@ -108,6 +108,9 @@
 # Location of the protobuf src dir in the Android source tree.
 android_protobuf_src = 'external/protobuf/src'
 
+# put all args on a new line for better diffs.
+NEWLINE = ' " +\n         "'
+
 # Compiler flags which are passed through to the blueprint.
 cflag_allowlist = [
   # needed for zlib:zlib
@@ -620,17 +623,30 @@
   def __init__(self, target):
     # Just to be on the safe side, create a deep-copy.
     self.target = copy.deepcopy(target)
+    self.target.args = self._normalize_args()
+
+  def get_name(self):
+    return label_to_module_name(self.target.name)
+
+  def _normalize_args(self):
     # Convert ['--param=value'] to ['--param', 'value'] for consistency.
-    self.target.args = [str for it in self.target.args for str in it.split('=')]
+    # Escape quotations.
+    normalized_args = []
+    for arg in self.target.args:
+      arg = arg.replace('"', r'\"')
+      if arg.startswith('-'):
+        normalized_args.extend(arg.split('='))
+      else:
+        normalized_args.append(arg)
+    return normalized_args
 
   # There are three types of args:
   # - flags (--flag)
   # - value args (--arg value)
   # - list args (--arg value1 --arg value2)
+  # value args have exactly one arg value pair and list args have one or more arg value pairs.
   # Note that the set of list args contains the set of value args.
-  # value args must have exactly one arg value pair but list args could have one arg value pair.
-  # This is because list args with one arg value pair and value args can not be distinguished only
-  # from the desc.json
+  # This is because list and value args are identical when the list args has only one arg value pair
   # Some functions provide special implementations for each type, while others
   # work on all of them.
   def _has_arg(self, arg):
@@ -654,10 +670,7 @@
 
   # Whether an arg value pair appears exactly once
   def _is_value_arg(self, arg):
-    if operator.countOf(self.target.args, arg) != 1:
-      return False
-    i = self.target.args.index(arg)
-    return not self.target.args[i + 1].startswith('--')
+    return operator.countOf(self.target.args, arg) == 1 and self._is_list_arg(arg)
 
   def _get_value_arg(self, arg):
     assert(self._is_value_arg(arg))
@@ -720,19 +733,71 @@
   def _update_all_args(self, func):
     self.target.args = [func(arg) for arg in self.target.args]
 
-  def get_args(self):
-    return self.target.args
+  def get_cmd(self):
+    arg_string = NEWLINE.join(self.target.args)
+    cmd = '$(location %s) %s' % (
+    gn_utils.label_to_path(self.target.script), arg_string)
+
+    if self.use_response_file:
+      # Pipe response file contents into script
+      cmd = 'echo \'%s\' |%s%s' % (self.target.response_file_contents, NEWLINE, cmd)
+    return cmd
+
+  def get_outputs(self):
+    return self.target.outputs
+
+  def get_srcs(self):
+    # gn treats inputs and sources for actions equally.
+    # soong only supports source files inside srcs, non-source files are added as
+    # tool_files dependency.
+    files = self.target.sources.union(self.target.inputs)
+    return {gn_utils.label_to_path(file) for file in files if is_supported_source_file(file)}
+
+  def get_tool_files(self):
+    # gn treats inputs and sources for actions equally.
+    # soong only supports source files inside srcs, non-source files are added as
+    # tool_files dependency.
+    files = self.target.sources.union(self.target.inputs)
+    tool_files = {gn_utils.label_to_path(file)
+                  for file in files if not is_supported_source_file(file)}
+    tool_files.add(gn_utils.label_to_path(self.target.script))
+    return tool_files
+
+  def _sanitize_args(self):
+    # Handle passing parameters via response file by piping them into the script
+    # and reading them from /dev/stdin.
+
+    self.use_response_file = gn_utils.RESPONSE_FILE in self.target.args
+    if self.use_response_file:
+      # Replace {{response_file_contents}} with /dev/stdin
+      self.target.args = ['/dev/stdin' if it == gn_utils.RESPONSE_FILE else it
+                          for it in self.target.args]
+
+  def _sanitize_outputs(self):
+    pass
+
+  def _sanitize_inputs(self):
+    pass
+
+  def sanitize(self):
+    self._sanitize_args()
+    self._sanitize_outputs()
+    self._sanitize_inputs()
+
+  # Whether this target generates header files
+  def is_header_generated(self):
+    return any(os.path.splitext(it)[1] == '.h' for it in self.target.outputs)
 
 class WriteBuildDateHeaderSanitizer(BaseActionSanitizer):
-  def get_args(self):
+  def _sanitize_args(self):
     self._set_arg_at(0, '$(out)')
-    return super().get_args()
+    super()._sanitize_args()
 
 class WriteBuildFlagHeaderSanitizer(BaseActionSanitizer):
-  def get_args(self):
+  def _sanitize_args(self):
     self._set_value_arg('--gen-dir', '.')
     self._set_value_arg('--output', '$(out)')
-    return super().get_args()
+    super()._sanitize_args()
 
 class JniGeneratorSanitizer(BaseActionSanitizer):
   def _add_location_tag_to_filepath(self, arg):
@@ -742,7 +807,7 @@
       arg = self._add_location_tag(arg)
     return arg
 
-  def get_args(self):
+  def _sanitize_args(self):
     self._update_value_arg('--jar_file', self._sanitize_filepath, False)
     self._update_value_arg('--jar_file', self._add_location_tag, False)
     if self._has_arg('--jar_file'):
@@ -752,10 +817,25 @@
     self._delete_value_arg('--prev_output_dir', False)
     self._update_list_arg('--input_file', self._sanitize_filepath)
     self._update_list_arg('--input_file', self._add_location_tag_to_filepath)
-    return super().get_args()
+    super()._sanitize_args()
+
+  def _sanitize_outputs(self):
+    # fix target.output directory to match #include statements.
+    self.target.outputs = {re.sub('^jni_headers/', '', out) for out in self.target.outputs}
+    super()._sanitize_outputs()
+
+  def get_tool_files(self):
+    tool_files = super().get_tool_files()
+    # android_jar.classes should be part of the tools as it list implicit classes
+    # for the script to generate JNI headers.
+    tool_files.add("base/android/jni_generator/android_jar.classes")
+    return tool_files
 
 class JniRegistrationGeneratorSanitizer(BaseActionSanitizer):
-  def get_args(self):
+  def _sanitize_inputs(self):
+    self.target.inputs = [file for file in self.target.inputs if not file.startswith('//out/')]
+
+  def _sanitize_args(self):
     self._update_value_arg('--depfile', self._sanitize_filepath)
     self._update_value_arg('--srcjar-path', self._sanitize_filepath)
     self._update_value_arg('--header-path', self._sanitize_filepath)
@@ -763,34 +843,82 @@
     # update_jni_registration_module removes them from the srcs of the module
     # It might be better to remove sources by '--sources-exclusions'
     self._delete_value_arg('--sources-exclusions')
-    return super().get_args()
+    super()._sanitize_args()
+
+  def get_cmd(self):
+    # jni_registration_generator.py doesn't work with python2
+    cmd = "python3 " + super().get_cmd()
+    # Path in the original sources file does not work in genrule.
+    # So creating sources file in cmd based on the srcs of this target.
+    # Adding ../$(current_dir)/ to the head because jni_registration_generator.py uses the files
+    # whose path startswith(..)
+    commands = ["current_dir=`basename \\\`pwd\\\``;",
+                "for f in $(in);",
+                "do",
+                "echo \\\"../$$current_dir/$$f\\\" >> $(genDir)/java.sources;",
+                "done;",
+                cmd]
+
+    # .h file jni_registration_generator.py generates has #define with directory name.
+    # With the genrule env that contains "." which is invalid. So replace that at the end of cmd.
+    commands.append(";sed -i -e 's/OUT_SOONG_.TEMP_SBOX_.*_OUT/GEN/g' ")
+    commands.append("$(genDir)/components/cronet/android/cronet_jni_registration.h")
+    return NEWLINE.join(commands)
+
+class JavaJniRegistrationGeneratorSanitizer(JniRegistrationGeneratorSanitizer):
+  def get_name(self):
+    return label_to_module_name(self.target.name) + "__java"
+
+  def _sanitize_outputs(self):
+    self.target.outputs = [out for out in self.target.outputs if
+                           out.endswith(".srcjar")]
+    super()._sanitize_outputs()
 
 class VersionSanitizer(BaseActionSanitizer):
-  def _sanitize_eval(self):
-    assert (self._is_value_arg('-e'))
-    # arg for -e EVAL option should be passed in -e PATCH_HI=int(PATCH)//256 format.
-    index = self.target.args.index('-e')
-    value = '%s=\'%s\'' % (self.target.args[index + 1], self.target.args[index + 2])
-    # escape '"' in the value
-    value = value.replace('"', r'\"')
-    self._set_arg_at(index + 1, value)
-    self.target.args.pop(index + 2)
-
-  def get_args(self):
+  def _sanitize_args(self):
     self._set_value_arg('-o', '$(out)')
     # args for the version.py contain file path without leading --arg key. So apply sanitize
     # function for all the args.
     self._update_all_args(self._sanitize_filepath_with_location_tag)
-    self._sanitize_eval()
-    return super().get_args()
+    self._set_value_arg('-e', "'%s'" % self._get_value_arg('-e'))
+    super()._sanitize_args()
+
+  def get_tool_files(self):
+    tool_files = super().get_tool_files()
+    # android_chrome_version.py is not specified in anywhere but version.py imports this file
+    tool_files.add('build/util/android_chrome_version.py')
+    return tool_files
 
 class JavaCppEnumSanitizer(BaseActionSanitizer):
-  def get_args(self):
+  def _sanitize_args(self):
     self._update_all_args(self._sanitize_filepath_with_location_tag)
     self._set_value_arg('--srcjar', '$(out)')
-    return super().get_args()
+    super()._sanitize_args()
 
-def get_action_sanitizer(target):
+class MakeDafsaSanitizer(BaseActionSanitizer):
+  def is_header_generated(self):
+    # This script generates .cc files but they are #included by other sources
+    # (e.g. registry_controlled_domain.cc)
+    return True
+
+class JavaCppFeatureSanitizer(BaseActionSanitizer):
+  def _sanitize_args(self):
+    self._update_all_args(self._sanitize_filepath_with_location_tag)
+    self._set_value_arg('--srcjar', '$(out)')
+    super()._sanitize_args()
+
+class JavaCppStringSanitizer(BaseActionSanitizer):
+  def _sanitize_args(self):
+    self._update_all_args(self._sanitize_filepath_with_location_tag)
+    self._set_value_arg('--srcjar', '$(out)')
+    super()._sanitize_args()
+
+class WriteNativeLibrariesJavaSanitizer(BaseActionSanitizer):
+  def _sanitize_args(self):
+    self._set_value_arg('--output', '$(out)')
+    super()._sanitize_args()
+
+def get_action_sanitizer(target, type):
   if target.script == "//build/write_buildflag_header.py":
     return WriteBuildFlagHeaderSanitizer(target)
   elif target.script == "//build/write_build_date_header.py":
@@ -798,11 +926,22 @@
   elif target.script == '//base/android/jni_generator/jni_generator.py':
     return JniGeneratorSanitizer(target)
   elif target.script == '//base/android/jni_generator/jni_registration_generator.py':
-    return JniRegistrationGeneratorSanitizer(target)
+    if type == 'java_genrule':
+      return JavaJniRegistrationGeneratorSanitizer(target)
+    else:
+      return JniRegistrationGeneratorSanitizer(target)
   elif target.script == "//build/util/version.py":
     return VersionSanitizer(target)
   elif target.script == "//build/android/gyp/java_cpp_enum.py":
     return JavaCppEnumSanitizer(target)
+  elif target.script == "//net/tools/dafsa/make_dafsa.py":
+    return MakeDafsaSanitizer(target)
+  elif target.script == '//build/android/gyp/java_cpp_features.py':
+    return JavaCppFeatureSanitizer(target)
+  elif target.script == '//build/android/gyp/java_cpp_strings.py':
+    return JavaCppStringSanitizer(target)
+  elif target.script == '//build/android/gyp/write_native_libraries_java.py':
+    return WriteNativeLibrariesJavaSanitizer(target)
   else:
     # TODO: throw exception here once all script hacks have been converted.
     return BaseActionSanitizer(target)
@@ -841,93 +980,16 @@
   return create_action_module(blueprint, target, 'cc_genrule')
 
 def create_action_module(blueprint, target, type):
-  bp_module_name = label_to_module_name(target.name)
-  module = Module(type, bp_module_name, target.name)
+  sanitizer = get_action_sanitizer(target, type)
+  sanitizer.sanitize()
 
-  sanitizer = get_action_sanitizer(target)
-  target.args = sanitizer.get_args()
-
-  if target.script == '//base/android/jni_generator/jni_generator.py':
-    # fix target.output directory to match #include statements.
-    target.outputs = [re.sub('^jni_headers/', '', out) for out in target.outputs]
-
-    # android_jar.classes should be part of the tools as it list implicit classes
-    # for the script to generate JNI headers.
-    module.tool_files.add("base/android/jni_generator/android_jar.classes")
-
-  elif target.script == '//base/android/jni_generator/jni_registration_generator.py':
-    # jni_registration_generator.py pulls in some config dependencies that we
-    # do not handle. Remove them.
-    # TODO: find a better way to do this.
-    target.deps.clear()
-
-    target.inputs = [file for file in target.inputs if not file.startswith('//out/')]
-  elif target.script == "//net/tools/dafsa/make_dafsa.py":
-    # This script generates .cc files but source (registry_controlled_domain.cc) in the target that
-    # depends on this target includes .cc file this script generates.
+  module = Module(type, sanitizer.get_name(), target.name)
+  module.cmd = sanitizer.get_cmd()
+  module.out = sanitizer.get_outputs()
+  if sanitizer.is_header_generated():
     module.genrule_headers.add(module.name)
-  elif target.script == "//build/util/version.py":
-    # android_chrome_version.py is not specified in anywhere but version.py imports this file
-    module.tool_files.add('build/util/android_chrome_version.py')
-
-  script = gn_utils.label_to_path(target.script)
-  module.tool_files.add(script)
-
-  # Handle passing parameters via response file by piping them into the script
-  # and reading them from /dev/stdin.
-  response_file = '{{response_file_name}}'
-  use_response_file = response_file in target.args
-  if use_response_file:
-    # Replace {{response_file_contents}} with /dev/stdin
-    target.args = ['/dev/stdin' if it == response_file else it for it in target.args]
-
-  # put all args on a new line for better diffs.
-  NEWLINE = ' " +\n         "'
-  arg_string = NEWLINE.join(target.args)
-  module.cmd = '$(location %s) %s' % (script, arg_string)
-
-  if use_response_file:
-    # Pipe response file contents into script
-    module.cmd = 'echo \'%s\' |%s%s' % (target.response_file_contents, NEWLINE, module.cmd)
-
-  if any(os.path.splitext(it)[1] == '.h' for it in target.outputs):
-    module.genrule_headers.add(bp_module_name)
-
-  # gn treats inputs and sources for actions equally.
-  # soong only supports source files inside srcs, non-source files are added as
-  # tool_files dependency.
-  for it in target.sources or target.inputs:
-    if is_supported_source_file(it):
-      module.srcs.add(gn_utils.label_to_path(it))
-    else:
-      module.tool_files.add(gn_utils.label_to_path(it))
-
-  # Actions using template "action_with_pydeps" also put script inside inputs.
-  # TODO: it might make sense to filter inputs inside GnParser.
-  if script in module.srcs:
-    module.srcs.remove(script)
-
-  module.out.update(target.outputs)
-
-  if target.script == '//base/android/jni_generator/jni_registration_generator.py':
-    # jni_registration_generator.py doesn't work with python2
-    module.cmd = "python3 " + module.cmd
-    # Path in the original sources file does not work in genrule.
-    # So creating sources file in cmd based on the srcs of this target.
-    # Adding ../$(current_dir)/ to the head because jni_registration_generator.py uses the files
-    # whose path startswith(..)
-    commands = ["current_dir=`basename \\\`pwd\\\``;",
-                "for f in $(in);",
-                "do",
-                "echo \\\"../$$current_dir/$$f\\\" >> $(genDir)/java.sources;",
-                "done;",
-                module.cmd]
-
-    # .h file jni_registration_generator.py generates has #define with directory name.
-    # With the genrule env that contains "." which is invalid. So replace that at the end of cmd.
-    commands.append(";sed -i -e 's/OUT_SOONG_.TEMP_SBOX_.*_OUT/GEN/g' ")
-    commands.append("$(genDir)/components/cronet/android/cronet_jni_registration.h")
-    module.cmd = NEWLINE.join(commands)
+  module.srcs = sanitizer.get_srcs()
+  module.tool_files = sanitizer.get_tool_files()
 
   blueprint.add_module(module)
   return module
@@ -1011,15 +1073,7 @@
     if module is None:
       return None
   elif target.type == 'action':
-    if gn_utils.is_java_action(target.script, target.outputs) and \
-        target.name != "//components/cronet/android:cronet_jni_registration":
-      # This is a cc_genrule that generates both a c++ header file and
-      # srcjar for java. Treat it as a cc_genrule for the time being while
-      # making anothe deep copy of the module and append _java to it for
-      # the java_library.
-      module = create_action_module(blueprint, target, 'java_genrule')
-    else:
-      module = create_action_module(blueprint, target, 'cc_genrule')
+    module = create_action_module(blueprint, target, 'cc_genrule')
   elif target.type == 'action_foreach':
     module = create_action_foreach_modules(blueprint, target)
   elif target.type == 'copy':
@@ -1199,13 +1253,7 @@
   module = Module('java_library', bp_module_name, '//gn:java')
   module.srcs.update([gn_utils.label_to_path(source) for source in gn.java_sources])
   for dep in gn.java_actions:
-    dep_module = create_modules_from_target(blueprint, gn, dep)
-    if "cronet_jni_registration" in dep_module.name:
-      dep_module = copy.deepcopy(dep_module)
-      dep_module.name += "_java"
-      dep_module.type = 'java_genrule'
-      dep_module.out = [out for out in dep_module.out if out.endswith(".srcjar")]
-      blueprint.add_module(dep_module)
+    dep_module = create_action_module(blueprint, gn.get_target(dep), 'java_genrule')
   blueprint.add_module(module)
 
 def update_jni_registration_module(module, gn):
@@ -1218,7 +1266,8 @@
 
   # TODO: java_sources might not contain all the required java files
   module.srcs.update([gn_utils.label_to_path(source)
-                      for source in gn.java_sources if source not in deny_list])
+                      for source in gn.java_sources
+                      if source.endswith('.java') and source not in deny_list])
 
 def create_blueprint_for_targets(gn, targets):
   """Generate a blueprint for a list of GN targets."""
diff --git a/tools/gn2bp/gn_utils.py b/tools/gn2bp/gn_utils.py
index 8f33ca2..130f8ff 100644
--- a/tools/gn2bp/gn_utils.py
+++ b/tools/gn2bp/gn_utils.py
@@ -52,6 +52,8 @@
 ARCH_REGEX = r'(android_x86_64|android_x86|android_arm|android_arm64|host)'
 DEX_REGEX = '.*__dex__%s$' % ARCH_REGEX
 COMPILE_JAVA_REGEX = '.*__compile_java__%s$' % ARCH_REGEX
+RESPONSE_FILE = '{{response_file_name}}'
+
 def repo_root():
   """Returns an absolute path to the repository root."""
   return os.path.join(
@@ -427,7 +429,13 @@
           java_srcs = [src for src in dep.inputs if _is_java_source(src)]
           self.java_sources.update(java_srcs)
       if dep.type in ["action"] and target.type == "java_group":
-        self.java_actions.add(dep.name)
+        # //base:base_java_aidl generates srcjar from .aidl files. But java_library in soong can
+        # directly have .aidl files in srcs. So adding .aidl files to the java_sources.
+        # TODO: Find a better way/place to do this.
+        if dep.name == '//base:base_java_aidl':
+          self.java_sources.update(dep.arch[arch].sources)
+        else:
+          self.java_actions.add(dep.name)
     return target
 
   def get_proto_exports(self, proto_desc):