Skip ab/7061308 in stage.

Bug: 180401296
Merged-In: I04ef025ed537623511a3d346d4c59d6efb6bef3f
Change-Id: I35760b156d247f33a6512bcbb3e10cf858b4bee3
diff --git a/OWNERS b/OWNERS
index 0e1e65d..22b5561 100644
--- a/OWNERS
+++ b/OWNERS
@@ -2,5 +2,6 @@
 jchalard@google.com
 junyulai@google.com
 lorenzo@google.com
+maze@google.com
 reminv@google.com
 satk@google.com
diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index d8557ad..742fd02 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -14,11 +14,16 @@
 // limitations under the License.
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 java_defaults {
     name: "TetheringAndroidLibraryDefaults",
     sdk_version: "module_current",
     min_sdk_version: "30",
     srcs: [
+        "apishim/**/*.java",
         "src/**/*.java",
         ":framework-tethering-shared-srcs",
         ":tethering-module-utils-srcs",
@@ -26,14 +31,14 @@
     ],
     static_libs: [
         "androidx.annotation_annotation",
-        "netd_aidl_interface-unstable-java",
+        "modules-utils-build",
         "netlink-client",
-        // TODO: use networkstack-client instead of just including the AIDL interface
-        "networkstack-aidl-interfaces-unstable-java",
+        "networkstack-client",
         "android.hardware.tetheroffload.config-V1.0-java",
         "android.hardware.tetheroffload.control-V1.0-java",
         "net-utils-framework-common",
         "net-utils-device-common",
+        "netd-client",
     ],
     libs: [
         "framework-statsd.stubs.module_lib",
@@ -60,8 +65,12 @@
         "com.android.tethering",
     ],
     min_sdk_version: "30",
+    header_libs: [
+        "bpf_syscall_wrappers",
+        "bpf_tethering_headers",
+    ],
     srcs: [
-        "jni/android_net_util_TetheringUtils.cpp",
+        "jni/*.cpp",
     ],
     shared_libs: [
         "liblog",
@@ -139,3 +148,10 @@
     apex_available: ["com.android.tethering"],
     min_sdk_version: "30",
 }
+
+sdk {
+    name: "tethering-module-sdk",
+    java_sdk_libs: [
+        "framework-tethering",
+    ],
+}
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index a1e7fd2..e9deeff 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -14,12 +14,27 @@
 // limitations under the License.
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 apex {
     name: "com.android.tethering",
-    updatable: true,
-    min_sdk_version: "30",
-    java_libs: ["framework-tethering"],
-    bpfs: ["offload.o"],
+    // TODO: make updatable again once this contains only updatable artifacts (in particular, this
+    // cannot build as updatable unless service-connectivity builds against stable API).
+    updatable: false,
+    // min_sdk_version: "30",
+    java_libs: [
+        "framework-tethering",
+        "service-connectivity",
+    ],
+    jni_libs: [
+        "libservice-connectivity",
+    ],
+    bpfs: [
+        "offload.o",
+        "test.o",
+    ],
     apps: ["Tethering"],
     manifest: "manifest.json",
     key: "com.android.tethering.key",
diff --git a/Tethering/apex/manifest.json b/Tethering/apex/manifest.json
index 11e205d..8836c4e 100644
--- a/Tethering/apex/manifest.json
+++ b/Tethering/apex/manifest.json
@@ -1,4 +1,4 @@
 {
   "name": "com.android.tethering",
-  "version": 309999900
+  "version": 300900700
 }
diff --git a/Tethering/apishim/30/com/android/networkstack/tethering/apishim/api30/BpfCoordinatorShimImpl.java b/Tethering/apishim/30/com/android/networkstack/tethering/apishim/api30/BpfCoordinatorShimImpl.java
new file mode 100644
index 0000000..4e615a1
--- /dev/null
+++ b/Tethering/apishim/30/com/android/networkstack/tethering/apishim/api30/BpfCoordinatorShimImpl.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2020 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 com.android.networkstack.tethering.apishim.api30;
+
+import android.net.INetd;
+import android.net.MacAddress;
+import android.net.TetherStatsParcel;
+import android.net.util.SharedLog;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.util.SparseArray;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.networkstack.tethering.BpfCoordinator.Dependencies;
+import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
+import com.android.networkstack.tethering.Tether4Key;
+import com.android.networkstack.tethering.Tether4Value;
+import com.android.networkstack.tethering.TetherStatsValue;
+
+/**
+ * Bpf coordinator class for API shims.
+ */
+public class BpfCoordinatorShimImpl
+        extends com.android.networkstack.tethering.apishim.common.BpfCoordinatorShim {
+    private static final String TAG = "api30.BpfCoordinatorShimImpl";
+
+    @NonNull
+    private final SharedLog mLog;
+    @NonNull
+    private final INetd mNetd;
+
+    public BpfCoordinatorShimImpl(@NonNull final Dependencies deps) {
+        mLog = deps.getSharedLog().forSubComponent(TAG);
+        mNetd = deps.getNetd();
+    }
+
+    @Override
+    public boolean isInitialized() {
+        return true;
+    };
+
+    @Override
+    public boolean tetherOffloadRuleAdd(@NonNull final Ipv6ForwardingRule rule) {
+        try {
+            mNetd.tetherOffloadRuleAdd(rule.toTetherOffloadRuleParcel());
+        } catch (RemoteException | ServiceSpecificException e) {
+            mLog.e("Could not add IPv6 forwarding rule: ", e);
+            return false;
+        }
+
+        return true;
+    };
+
+    @Override
+    public boolean tetherOffloadRuleRemove(@NonNull final Ipv6ForwardingRule rule) {
+        try {
+            mNetd.tetherOffloadRuleRemove(rule.toTetherOffloadRuleParcel());
+        } catch (RemoteException | ServiceSpecificException e) {
+            mLog.e("Could not remove IPv6 forwarding rule: ", e);
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
+            MacAddress srcMac, MacAddress dstMac, int mtu) {
+        return true;
+    }
+
+    @Override
+    public boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex) {
+        return true;
+    }
+
+    @Override
+    @Nullable
+    public SparseArray<TetherStatsValue> tetherOffloadGetStats() {
+        final TetherStatsParcel[] tetherStatsList;
+        try {
+            // The reported tether stats are total data usage for all currently-active upstream
+            // interfaces since tethering start. There will only ever be one entry for a given
+            // interface index.
+            tetherStatsList = mNetd.tetherOffloadGetStats();
+        } catch (RemoteException | ServiceSpecificException e) {
+            mLog.e("Fail to fetch tethering stats from netd: " + e);
+            return null;
+        }
+
+        return toTetherStatsValueSparseArray(tetherStatsList);
+    }
+
+    @Override
+    public boolean tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes) {
+        try {
+            mNetd.tetherOffloadSetInterfaceQuota(ifIndex, quotaBytes);
+        } catch (RemoteException | ServiceSpecificException e) {
+            mLog.e("Exception when updating quota " + quotaBytes + ": ", e);
+            return false;
+        }
+        return true;
+    }
+
+    @NonNull
+    private SparseArray<TetherStatsValue> toTetherStatsValueSparseArray(
+            @NonNull final TetherStatsParcel[] parcels) {
+        final SparseArray<TetherStatsValue> tetherStatsList = new SparseArray<TetherStatsValue>();
+
+        for (TetherStatsParcel p : parcels) {
+            tetherStatsList.put(p.ifIndex, new TetherStatsValue(p.rxPackets, p.rxBytes,
+                    0 /* rxErrors */, p.txPackets, p.txBytes, 0 /* txErrors */));
+        }
+
+        return tetherStatsList;
+    }
+
+    @Override
+    @Nullable
+    public TetherStatsValue tetherOffloadGetAndClearStats(int ifIndex) {
+        try {
+            final TetherStatsParcel stats =
+                    mNetd.tetherOffloadGetAndClearStats(ifIndex);
+            return new TetherStatsValue(stats.rxPackets, stats.rxBytes, 0 /* rxErrors */,
+                    stats.txPackets, stats.txBytes, 0 /* txErrors */);
+        } catch (RemoteException | ServiceSpecificException e) {
+            mLog.e("Exception when cleanup tether stats for upstream index "
+                    + ifIndex + ": ", e);
+            return null;
+        }
+    }
+
+    @Override
+    public boolean tetherOffloadRuleAdd(boolean downstream, @NonNull Tether4Key key,
+            @NonNull Tether4Value value) {
+        /* no op */
+        return true;
+    }
+
+    @Override
+    public boolean tetherOffloadRuleRemove(boolean downstream, @NonNull Tether4Key key) {
+        /* no op */
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "Netd used";
+    }
+}
diff --git a/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java b/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
new file mode 100644
index 0000000..4dc1c51
--- /dev/null
+++ b/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2020 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 com.android.networkstack.tethering.apishim.api31;
+
+import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
+
+import android.net.MacAddress;
+import android.net.util.SharedLog;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.util.SparseArray;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.networkstack.tethering.BpfCoordinator.Dependencies;
+import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
+import com.android.networkstack.tethering.BpfMap;
+import com.android.networkstack.tethering.Tether4Key;
+import com.android.networkstack.tethering.Tether4Value;
+import com.android.networkstack.tethering.Tether6Value;
+import com.android.networkstack.tethering.TetherDownstream6Key;
+import com.android.networkstack.tethering.TetherLimitKey;
+import com.android.networkstack.tethering.TetherLimitValue;
+import com.android.networkstack.tethering.TetherStatsKey;
+import com.android.networkstack.tethering.TetherStatsValue;
+import com.android.networkstack.tethering.TetherUpstream6Key;
+
+import java.io.FileDescriptor;
+
+/**
+ * Bpf coordinator class for API shims.
+ */
+public class BpfCoordinatorShimImpl
+        extends com.android.networkstack.tethering.apishim.common.BpfCoordinatorShim {
+    private static final String TAG = "api31.BpfCoordinatorShimImpl";
+
+    // AF_KEY socket type. See include/linux/socket.h.
+    private static final int AF_KEY = 15;
+    // PFKEYv2 constants. See include/uapi/linux/pfkeyv2.h.
+    private static final int PF_KEY_V2 = 2;
+
+    @NonNull
+    private final SharedLog mLog;
+
+    // BPF map for downstream IPv4 forwarding.
+    @Nullable
+    private final BpfMap<Tether4Key, Tether4Value> mBpfDownstream4Map;
+
+    // BPF map for upstream IPv4 forwarding.
+    @Nullable
+    private final BpfMap<Tether4Key, Tether4Value> mBpfUpstream4Map;
+
+    // BPF map for downstream IPv6 forwarding.
+    @Nullable
+    private final BpfMap<TetherDownstream6Key, Tether6Value> mBpfDownstream6Map;
+
+    // BPF map for upstream IPv6 forwarding.
+    @Nullable
+    private final BpfMap<TetherUpstream6Key, Tether6Value> mBpfUpstream6Map;
+
+    // BPF map of tethering statistics of the upstream interface since tethering startup.
+    @Nullable
+    private final BpfMap<TetherStatsKey, TetherStatsValue> mBpfStatsMap;
+
+    // BPF map of per-interface quota for tethering offload.
+    @Nullable
+    private final BpfMap<TetherLimitKey, TetherLimitValue> mBpfLimitMap;
+
+    public BpfCoordinatorShimImpl(@NonNull final Dependencies deps) {
+        mLog = deps.getSharedLog().forSubComponent(TAG);
+        mBpfDownstream4Map = deps.getBpfDownstream4Map();
+        mBpfUpstream4Map = deps.getBpfUpstream4Map();
+        mBpfDownstream6Map = deps.getBpfDownstream6Map();
+        mBpfUpstream6Map = deps.getBpfUpstream6Map();
+        mBpfStatsMap = deps.getBpfStatsMap();
+        mBpfLimitMap = deps.getBpfLimitMap();
+    }
+
+    @Override
+    public boolean isInitialized() {
+        return mBpfDownstream4Map != null && mBpfUpstream4Map != null && mBpfDownstream6Map != null
+                && mBpfUpstream6Map != null && mBpfStatsMap != null && mBpfLimitMap != null;
+    }
+
+    @Override
+    public boolean tetherOffloadRuleAdd(@NonNull final Ipv6ForwardingRule rule) {
+        if (!isInitialized()) return false;
+
+        final TetherDownstream6Key key = rule.makeTetherDownstream6Key();
+        final Tether6Value value = rule.makeTether6Value();
+
+        try {
+            mBpfDownstream6Map.updateEntry(key, value);
+        } catch (ErrnoException e) {
+            mLog.e("Could not update entry: ", e);
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean tetherOffloadRuleRemove(@NonNull final Ipv6ForwardingRule rule) {
+        if (!isInitialized()) return false;
+
+        try {
+            mBpfDownstream6Map.deleteEntry(rule.makeTetherDownstream6Key());
+        } catch (ErrnoException e) {
+            // Silent if the rule did not exist.
+            if (e.errno != OsConstants.ENOENT) {
+                mLog.e("Could not update entry: ", e);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
+            MacAddress srcMac, MacAddress dstMac, int mtu) {
+        if (!isInitialized()) return false;
+
+        final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfindex);
+        final Tether6Value value = new Tether6Value(upstreamIfindex, srcMac,
+                dstMac, OsConstants.ETH_P_IPV6, mtu);
+        try {
+            mBpfUpstream6Map.insertEntry(key, value);
+        } catch (ErrnoException | IllegalStateException e) {
+            mLog.e("Could not insert upstream6 entry: " + e);
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex) {
+        if (!isInitialized()) return false;
+
+        final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfindex);
+        try {
+            mBpfUpstream6Map.deleteEntry(key);
+        } catch (ErrnoException e) {
+            mLog.e("Could not delete upstream IPv6 entry: " + e);
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    @Nullable
+    public SparseArray<TetherStatsValue> tetherOffloadGetStats() {
+        if (!isInitialized()) return null;
+
+        final SparseArray<TetherStatsValue> tetherStatsList = new SparseArray<TetherStatsValue>();
+        try {
+            // The reported tether stats are total data usage for all currently-active upstream
+            // interfaces since tethering start.
+            mBpfStatsMap.forEach((key, value) -> tetherStatsList.put((int) key.ifindex, value));
+        } catch (ErrnoException e) {
+            mLog.e("Fail to fetch tethering stats from BPF map: ", e);
+            return null;
+        }
+        return tetherStatsList;
+    }
+
+    @Override
+    public boolean tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes) {
+        if (!isInitialized()) return false;
+
+        // The common case is an update, where the stats already exist,
+        // hence we read first, even though writing with BPF_NOEXIST
+        // first would make the code simpler.
+        long rxBytes, txBytes;
+        TetherStatsValue statsValue = null;
+
+        try {
+            statsValue = mBpfStatsMap.getValue(new TetherStatsKey(ifIndex));
+        } catch (ErrnoException e) {
+            // The BpfMap#getValue doesn't throw an errno ENOENT exception. Catch other error
+            // while trying to get stats entry.
+            mLog.e("Could not get stats entry of interface index " + ifIndex + ": ", e);
+            return false;
+        }
+
+        if (statsValue != null) {
+            // Ok, there was a stats entry.
+            rxBytes = statsValue.rxBytes;
+            txBytes = statsValue.txBytes;
+        } else {
+            // No stats entry - create one with zeroes.
+            try {
+                // This function is the *only* thing that can create entries.
+                // BpfMap#insertEntry use BPF_NOEXIST to create the entry. The entry is created
+                // if and only if it doesn't exist.
+                mBpfStatsMap.insertEntry(new TetherStatsKey(ifIndex), new TetherStatsValue(
+                        0 /* rxPackets */, 0 /* rxBytes */, 0 /* rxErrors */, 0 /* txPackets */,
+                        0 /* txBytes */, 0 /* txErrors */));
+            } catch (ErrnoException | IllegalArgumentException e) {
+                mLog.e("Could not create stats entry: ", e);
+                return false;
+            }
+            rxBytes = 0;
+            txBytes = 0;
+        }
+
+        // rxBytes + txBytes won't overflow even at 5gbps for ~936 years.
+        long newLimit = rxBytes + txBytes + quotaBytes;
+
+        // if adding limit (e.g., if limit is QUOTA_UNLIMITED) caused overflow: clamp to 'infinity'
+        if (newLimit < rxBytes + txBytes) newLimit = QUOTA_UNLIMITED;
+
+        try {
+            mBpfLimitMap.updateEntry(new TetherLimitKey(ifIndex), new TetherLimitValue(newLimit));
+        } catch (ErrnoException e) {
+            mLog.e("Fail to set quota " + quotaBytes + " for interface index " + ifIndex + ": ", e);
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    @Nullable
+    public TetherStatsValue tetherOffloadGetAndClearStats(int ifIndex) {
+        if (!isInitialized()) return null;
+
+        // getAndClearTetherOffloadStats is called after all offload rules have already been
+        // deleted for the given upstream interface. Before starting to do cleanup stuff in this
+        // function, use synchronizeKernelRCU to make sure that all the current running eBPF
+        // programs are finished on all CPUs, especially the unfinished packet processing. After
+        // synchronizeKernelRCU returned, we can safely read or delete on the stats map or the
+        // limit map.
+        final int res = synchronizeKernelRCU();
+        if (res != 0) {
+            // Error log but don't return. Do as much cleanup as possible.
+            mLog.e("synchronize_rcu() failed: " + res);
+        }
+
+        TetherStatsValue statsValue = null;
+        try {
+            statsValue = mBpfStatsMap.getValue(new TetherStatsKey(ifIndex));
+        } catch (ErrnoException e) {
+            mLog.e("Could not get stats entry for interface index " + ifIndex + ": ", e);
+            return null;
+        }
+
+        if (statsValue == null) {
+            mLog.e("Could not get stats entry for interface index " + ifIndex);
+            return null;
+        }
+
+        try {
+            mBpfStatsMap.deleteEntry(new TetherStatsKey(ifIndex));
+        } catch (ErrnoException e) {
+            mLog.e("Could not delete stats entry for interface index " + ifIndex + ": ", e);
+            return null;
+        }
+
+        try {
+            mBpfLimitMap.deleteEntry(new TetherLimitKey(ifIndex));
+        } catch (ErrnoException e) {
+            mLog.e("Could not delete limit for interface index " + ifIndex + ": ", e);
+            return null;
+        }
+
+        return statsValue;
+    }
+
+    @Override
+    public boolean tetherOffloadRuleAdd(boolean downstream, @NonNull Tether4Key key,
+            @NonNull Tether4Value value) {
+        if (!isInitialized()) return false;
+
+        try {
+            // The last used time field of the value is updated by the bpf program. Adding the same
+            // map pair twice causes the unexpected refresh. Must be fixed before starting the
+            // conntrack timeout extension implementation.
+            // TODO: consider using insertEntry.
+            if (downstream) {
+                mBpfDownstream4Map.updateEntry(key, value);
+            } else {
+                mBpfUpstream4Map.updateEntry(key, value);
+            }
+        } catch (ErrnoException e) {
+            mLog.e("Could not update entry: ", e);
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean tetherOffloadRuleRemove(boolean downstream, @NonNull Tether4Key key) {
+        if (!isInitialized()) return false;
+
+        try {
+            if (downstream) {
+                mBpfDownstream4Map.deleteEntry(key);
+            } else {
+                mBpfUpstream4Map.deleteEntry(key);
+            }
+        } catch (ErrnoException e) {
+            // Silent if the rule did not exist.
+            if (e.errno != OsConstants.ENOENT) {
+                mLog.e("Could not delete entry: ", e);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private String mapStatus(BpfMap m, String name) {
+        return name + "{" + (m != null ? "OK" : "ERROR") + "}";
+    }
+
+    @Override
+    public String toString() {
+        return String.join(", ", new String[] {
+                mapStatus(mBpfDownstream6Map, "mBpfDownstream6Map"),
+                mapStatus(mBpfUpstream6Map, "mBpfUpstream6Map"),
+                mapStatus(mBpfDownstream4Map, "mBpfDownstream4Map"),
+                mapStatus(mBpfUpstream4Map, "mBpfUpstream4Map"),
+                mapStatus(mBpfStatsMap, "mBpfStatsMap"),
+                mapStatus(mBpfLimitMap, "mBpfLimitMap")
+        });
+    }
+
+    /**
+     * Call synchronize_rcu() to block until all existing RCU read-side critical sections have
+     * been completed.
+     * Note that BpfCoordinatorTest have no permissions to create or close pf_key socket. It is
+     * okay for now because the caller #bpfGetAndClearStats doesn't care the result of this
+     * function. The tests don't be broken.
+     * TODO: Wrap this function into Dependencies for mocking in tests.
+     */
+    private int synchronizeKernelRCU() {
+        // This is a temporary hack for network stats map swap on devices running
+        // 4.9 kernels. The kernel code of socket release on pf_key socket will
+        // explicitly call synchronize_rcu() which is exactly what we need.
+        FileDescriptor pfSocket;
+        try {
+            pfSocket = Os.socket(AF_KEY, OsConstants.SOCK_RAW | OsConstants.SOCK_CLOEXEC,
+                    PF_KEY_V2);
+        } catch (ErrnoException e) {
+            mLog.e("create PF_KEY socket failed: ", e);
+            return e.errno;
+        }
+
+        // When closing socket, synchronize_rcu() gets called in sock_release().
+        try {
+            Os.close(pfSocket);
+        } catch (ErrnoException e) {
+            mLog.e("failed to close the PF_KEY socket: ", e);
+            return e.errno;
+        }
+
+        return 0;
+    }
+}
diff --git a/Tethering/apishim/common/com/android/networkstack/tethering/apishim/common/BpfCoordinatorShim.java b/Tethering/apishim/common/com/android/networkstack/tethering/apishim/common/BpfCoordinatorShim.java
new file mode 100644
index 0000000..c61c449
--- /dev/null
+++ b/Tethering/apishim/common/com/android/networkstack/tethering/apishim/common/BpfCoordinatorShim.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2020 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 com.android.networkstack.tethering.apishim.common;
+
+import android.net.MacAddress;
+import android.util.SparseArray;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.networkstack.tethering.BpfCoordinator.Dependencies;
+import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
+import com.android.networkstack.tethering.Tether4Key;
+import com.android.networkstack.tethering.Tether4Value;
+import com.android.networkstack.tethering.TetherStatsValue;
+
+/**
+ * Bpf coordinator class for API shims.
+ */
+public abstract class BpfCoordinatorShim {
+    /**
+     * Get BpfCoordinatorShim object by OS build version.
+     */
+    @NonNull
+    public static BpfCoordinatorShim getBpfCoordinatorShim(@NonNull final Dependencies deps) {
+        if (deps.isAtLeastS()) {
+            return new com.android.networkstack.tethering.apishim.api31.BpfCoordinatorShimImpl(
+                    deps);
+        } else {
+            return new com.android.networkstack.tethering.apishim.api30.BpfCoordinatorShimImpl(
+                    deps);
+        }
+    }
+
+    /**
+     * Return true if this class has been initialized, otherwise return false.
+     */
+    public abstract boolean isInitialized();
+
+    /**
+     * Adds a tethering offload rule to BPF map, or updates it if it already exists.
+     *
+     * Currently, only downstream /128 IPv6 entries are supported. An existing rule will be updated
+     * if the input interface and destination prefix match. Otherwise, a new rule will be created.
+     * Note that this can be only called on handler thread.
+     *
+     * @param rule The rule to add or update.
+     */
+    public abstract boolean tetherOffloadRuleAdd(@NonNull Ipv6ForwardingRule rule);
+
+    /**
+     * Deletes a tethering offload rule from the BPF map.
+     *
+     * Currently, only downstream /128 IPv6 entries are supported. An existing rule will be deleted
+     * if the destination IP address and the source interface match. It is not an error if there is
+     * no matching rule to delete.
+     *
+     * @param rule The rule to delete.
+     */
+    public abstract boolean tetherOffloadRuleRemove(@NonNull Ipv6ForwardingRule rule);
+
+    /**
+     * Starts IPv6 forwarding between the specified interfaces.
+
+     * @param downstreamIfindex the downstream interface index
+     * @param upstreamIfindex the upstream interface index
+     * @param srcMac the source MAC address to use for packets
+     * @oaram dstMac the destination MAC address to use for packets
+     * @return true if operation succeeded or was a no-op, false otherwise
+     */
+    public abstract boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
+            MacAddress srcMac, MacAddress dstMac, int mtu);
+
+    /**
+     * Stops IPv6 forwarding between the specified interfaces.
+
+     * @param downstreamIfindex the downstream interface index
+     * @param upstreamIfindex the upstream interface index
+     * @return true if operation succeeded or was a no-op, false otherwise
+     */
+    public abstract boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex);
+
+    /**
+     * Return BPF tethering offload statistics.
+     *
+     * @return an array of TetherStatsValue's, where each entry contains the upstream interface
+     *         index and its tethering statistics since tethering was first started.
+     *         There will only ever be one entry for a given interface index.
+     */
+    @Nullable
+    public abstract SparseArray<TetherStatsValue> tetherOffloadGetStats();
+
+   /**
+    * Set a per-interface quota for tethering offload.
+    *
+    * @param ifIndex Index of upstream interface
+    * @param quotaBytes The quota defined as the number of bytes, starting from zero and counting
+    *       from *now*. A value of QUOTA_UNLIMITED (-1) indicates there is no limit.
+    */
+    @Nullable
+    public abstract boolean tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes);
+
+    /**
+     * Return BPF tethering offload statistics and clear the stats for a given upstream.
+     *
+     * Must only be called once all offload rules have already been deleted for the given upstream
+     * interface. The existing stats will be fetched and returned. The stats and the limit for the
+     * given upstream interface will be deleted as well.
+     *
+     * The stats and limit for a given upstream interface must be initialized (using
+     * tetherOffloadSetInterfaceQuota) before any offload will occur on that interface.
+     *
+     * Note that this can be only called while the BPF maps were initialized.
+     *
+     * @param ifIndex Index of upstream interface.
+     * @return TetherStatsValue, which contains the given upstream interface's tethering statistics
+     *         since tethering was first started on that upstream interface.
+     */
+    @Nullable
+    public abstract TetherStatsValue tetherOffloadGetAndClearStats(int ifIndex);
+
+    /**
+     * Adds a tethering IPv4 offload rule to appropriate BPF map.
+     */
+    public abstract boolean tetherOffloadRuleAdd(boolean downstream, @NonNull Tether4Key key,
+            @NonNull Tether4Value value);
+
+    /**
+     * Deletes a tethering IPv4 offload rule from the appropriate BPF map.
+     */
+    public abstract boolean tetherOffloadRuleRemove(boolean downstream, @NonNull Tether4Key key);
+}
+
diff --git a/Tethering/bpf_progs/Android.bp b/Tethering/bpf_progs/Android.bp
index d54f861..2b10f89 100644
--- a/Tethering/bpf_progs/Android.bp
+++ b/Tethering/bpf_progs/Android.bp
@@ -15,6 +15,30 @@
 //
 
 //
+// struct definitions shared with JNI
+//
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_headers {
+    name: "bpf_tethering_headers",
+    vendor_available: false,
+    host_supported: false,
+    export_include_dirs: ["."],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    sdk_version: "30",
+    min_sdk_version: "30",
+    apex_available: ["com.android.tethering"],
+    visibility: [
+        "//packages/modules/Connectivity/Tethering",
+    ],
+}
+
+//
 // bpf kernel programs
 //
 bpf {
@@ -31,3 +55,18 @@
         "system/netd/libnetdutils/include",  // for UidConstants.h
     ],
 }
+
+bpf {
+    name: "test.o",
+    srcs: ["test.c"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    include_dirs: [
+        // TODO: get rid of system/netd.
+        "system/netd/bpf_progs",             // for bpf_net_helpers.h
+        "system/netd/libnetdbpf/include",    // for bpf_shared.h
+        "system/netd/libnetdutils/include",  // for UidConstants.h
+    ],
+}
diff --git a/Tethering/bpf_progs/bpf_tethering.h b/Tethering/bpf_progs/bpf_tethering.h
new file mode 100644
index 0000000..6591e81
--- /dev/null
+++ b/Tethering/bpf_progs/bpf_tethering.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+// Common definitions for BPF code in the tethering mainline module.
+// These definitions are available to:
+// - The BPF programs in Tethering/bpf_progs/
+// - JNI code that depends on the bpf_tethering_headers library.
+
+#define BPF_TETHER_ERRORS    \
+    ERR(INVALID_IP_VERSION)  \
+    ERR(LOW_TTL)             \
+    ERR(INVALID_TCP_HEADER)  \
+    ERR(TCP_CONTROL_PACKET)  \
+    ERR(NON_GLOBAL_SRC)      \
+    ERR(NON_GLOBAL_DST)      \
+    ERR(LOCAL_SRC_DST)       \
+    ERR(NO_STATS_ENTRY)      \
+    ERR(NO_LIMIT_ENTRY)      \
+    ERR(BELOW_IPV4_MTU)      \
+    ERR(BELOW_IPV6_MTU)      \
+    ERR(LIMIT_REACHED)       \
+    ERR(CHANGE_HEAD_FAILED)  \
+    ERR(TOO_SHORT)           \
+    ERR(HAS_IP_OPTIONS)      \
+    ERR(IS_IP_FRAG)          \
+    ERR(CHECKSUM)            \
+    ERR(NON_TCP_UDP)         \
+    ERR(NON_TCP)             \
+    ERR(SHORT_L4_HEADER)     \
+    ERR(SHORT_TCP_HEADER)    \
+    ERR(SHORT_UDP_HEADER)    \
+    ERR(UDP_CSUM_ZERO)       \
+    ERR(TRUNCATED_IPV4)      \
+    ERR(_MAX)
+
+#define ERR(x) BPF_TETHER_ERR_ ##x,
+enum {
+    BPF_TETHER_ERRORS
+};
+#undef ERR
+
+#define ERR(x) #x,
+static const char *bpf_tether_errors[] = {
+    BPF_TETHER_ERRORS
+};
+#undef ERR
diff --git a/Tethering/bpf_progs/offload.c b/Tethering/bpf_progs/offload.c
index cc5af31..16d6ecf 100644
--- a/Tethering/bpf_progs/offload.c
+++ b/Tethering/bpf_progs/offload.c
@@ -20,27 +20,103 @@
 #include <linux/pkt_cls.h>
 #include <linux/tcp.h>
 
+// bionic kernel uapi linux/udp.h header is munged...
+#define __kernel_udphdr udphdr
+#include <linux/udp.h>
+
 #include "bpf_helpers.h"
 #include "bpf_net_helpers.h"
+#include "bpf_tethering.h"
 #include "netdbpf/bpf_shared.h"
 
-DEFINE_BPF_MAP_GRW(tether_ingress_map, HASH, TetherIngressKey, TetherIngressValue, 64,
+// From kernel:include/net/ip.h
+#define IP_DF 0x4000  // Flag: "Don't Fragment"
+
+// ----- Helper functions for offsets to fields -----
+
+// They all assume simple IP packets:
+//   - no VLAN ethernet tags
+//   - no IPv4 options (see IPV4_HLEN/TCP4_OFFSET/UDP4_OFFSET)
+//   - no IPv6 extension headers
+//   - no TCP options (see TCP_HLEN)
+
+//#define ETH_HLEN sizeof(struct ethhdr)
+#define IP4_HLEN sizeof(struct iphdr)
+#define IP6_HLEN sizeof(struct ipv6hdr)
+#define TCP_HLEN sizeof(struct tcphdr)
+#define UDP_HLEN sizeof(struct udphdr)
+
+// Offsets from beginning of L4 (TCP/UDP) header
+#define TCP_OFFSET(field) offsetof(struct tcphdr, field)
+#define UDP_OFFSET(field) offsetof(struct udphdr, field)
+
+// Offsets from beginning of L3 (IPv4) header
+#define IP4_OFFSET(field) offsetof(struct iphdr, field)
+#define IP4_TCP_OFFSET(field) (IP4_HLEN + TCP_OFFSET(field))
+#define IP4_UDP_OFFSET(field) (IP4_HLEN + UDP_OFFSET(field))
+
+// Offsets from beginning of L3 (IPv6) header
+#define IP6_OFFSET(field) offsetof(struct ipv6hdr, field)
+#define IP6_TCP_OFFSET(field) (IP6_HLEN + TCP_OFFSET(field))
+#define IP6_UDP_OFFSET(field) (IP6_HLEN + UDP_OFFSET(field))
+
+// Offsets from beginning of L2 (ie. Ethernet) header (which must be present)
+#define ETH_IP4_OFFSET(field) (ETH_HLEN + IP4_OFFSET(field))
+#define ETH_IP4_TCP_OFFSET(field) (ETH_HLEN + IP4_TCP_OFFSET(field))
+#define ETH_IP4_UDP_OFFSET(field) (ETH_HLEN + IP4_UDP_OFFSET(field))
+#define ETH_IP6_OFFSET(field) (ETH_HLEN + IP6_OFFSET(field))
+#define ETH_IP6_TCP_OFFSET(field) (ETH_HLEN + IP6_TCP_OFFSET(field))
+#define ETH_IP6_UDP_OFFSET(field) (ETH_HLEN + IP6_UDP_OFFSET(field))
+
+// ----- Tethering Error Counters -----
+
+DEFINE_BPF_MAP_GRW(tether_error_map, ARRAY, uint32_t, uint32_t, BPF_TETHER_ERR__MAX,
                    AID_NETWORK_STACK)
 
+#define COUNT_AND_RETURN(counter, ret) do {                  \
+    uint32_t code = BPF_TETHER_ERR_ ## counter;                 \
+    uint32_t *count = bpf_tether_error_map_lookup_elem(&code);  \
+    if (count) __sync_fetch_and_add(count, 1);               \
+    return ret;                                              \
+} while(0)
+
+#define TC_DROP(counter) COUNT_AND_RETURN(counter, TC_ACT_SHOT)
+#define TC_PUNT(counter) COUNT_AND_RETURN(counter, TC_ACT_OK)
+
+#define XDP_DROP(counter) COUNT_AND_RETURN(counter, XDP_DROP)
+#define XDP_PUNT(counter) COUNT_AND_RETURN(counter, XDP_PASS)
+
+// ----- Tethering Data Stats and Limits -----
+
 // Tethering stats, indexed by upstream interface.
-DEFINE_BPF_MAP_GRW(tether_stats_map, HASH, uint32_t, TetherStatsValue, 16, AID_NETWORK_STACK)
+DEFINE_BPF_MAP_GRW(tether_stats_map, HASH, TetherStatsKey, TetherStatsValue, 16, AID_NETWORK_STACK)
 
 // Tethering data limit, indexed by upstream interface.
 // (tethering allowed when stats[iif].rxBytes + stats[iif].txBytes < limit[iif])
-DEFINE_BPF_MAP_GRW(tether_limit_map, HASH, uint32_t, uint64_t, 16, AID_NETWORK_STACK)
+DEFINE_BPF_MAP_GRW(tether_limit_map, HASH, TetherLimitKey, TetherLimitValue, 16, AID_NETWORK_STACK)
 
-static inline __always_inline int do_forward(struct __sk_buff* skb, bool is_ethernet) {
-    int l2_header_size = is_ethernet ? sizeof(struct ethhdr) : 0;
+// ----- IPv6 Support -----
+
+DEFINE_BPF_MAP_GRW(tether_downstream6_map, HASH, TetherDownstream6Key, Tether6Value, 64,
+                   AID_NETWORK_STACK)
+
+DEFINE_BPF_MAP_GRW(tether_downstream64_map, HASH, TetherDownstream64Key, TetherDownstream64Value,
+                   64, AID_NETWORK_STACK)
+
+DEFINE_BPF_MAP_GRW(tether_upstream6_map, HASH, TetherUpstream6Key, Tether6Value, 64,
+                   AID_NETWORK_STACK)
+
+static inline __always_inline int do_forward6(struct __sk_buff* skb, const bool is_ethernet,
+        const bool downstream) {
+    const int l2_header_size = is_ethernet ? sizeof(struct ethhdr) : 0;
     void* data = (void*)(long)skb->data;
     const void* data_end = (void*)(long)skb->data_end;
     struct ethhdr* eth = is_ethernet ? data : NULL;  // used iff is_ethernet
     struct ipv6hdr* ip6 = is_ethernet ? (void*)(eth + 1) : data;
 
+    // Require ethernet dst mac address to be our unicast address.
+    if (is_ethernet && (skb->pkt_type != PACKET_HOST)) return TC_ACT_OK;
+
     // Must be meta-ethernet IPv6 frame
     if (skb->protocol != htons(ETH_P_IPV6)) return TC_ACT_OK;
 
@@ -51,43 +127,70 @@
     if (is_ethernet && (eth->h_proto != htons(ETH_P_IPV6))) return TC_ACT_OK;
 
     // IP version must be 6
-    if (ip6->version != 6) return TC_ACT_OK;
+    if (ip6->version != 6) TC_PUNT(INVALID_IP_VERSION);
 
     // Cannot decrement during forward if already zero or would be zero,
     // Let the kernel's stack handle these cases and generate appropriate ICMP errors.
-    if (ip6->hop_limit <= 1) return TC_ACT_OK;
+    if (ip6->hop_limit <= 1) TC_PUNT(LOW_TTL);
+
+    // If hardware offload is running and programming flows based on conntrack entries,
+    // try not to interfere with it.
+    if (ip6->nexthdr == IPPROTO_TCP) {
+        struct tcphdr* tcph = (void*)(ip6 + 1);
+
+        // Make sure we can get at the tcp header
+        if (data + l2_header_size + sizeof(*ip6) + sizeof(*tcph) > data_end)
+            TC_PUNT(INVALID_TCP_HEADER);
+
+        // Do not offload TCP packets with any one of the SYN/FIN/RST flags
+        if (tcph->syn || tcph->fin || tcph->rst) TC_PUNT(TCP_CONTROL_PACKET);
+    }
 
     // Protect against forwarding packets sourced from ::1 or fe80::/64 or other weirdness.
     __be32 src32 = ip6->saddr.s6_addr32[0];
     if (src32 != htonl(0x0064ff9b) &&                        // 64:ff9b:/32 incl. XLAT464 WKP
         (src32 & htonl(0xe0000000)) != htonl(0x20000000))    // 2000::/3 Global Unicast
-        return TC_ACT_OK;
+        TC_PUNT(NON_GLOBAL_SRC);
 
-    TetherIngressKey k = {
+    // Protect against forwarding packets destined to ::1 or fe80::/64 or other weirdness.
+    __be32 dst32 = ip6->daddr.s6_addr32[0];
+    if (dst32 != htonl(0x0064ff9b) &&                        // 64:ff9b:/32 incl. XLAT464 WKP
+        (dst32 & htonl(0xe0000000)) != htonl(0x20000000))    // 2000::/3 Global Unicast
+        TC_PUNT(NON_GLOBAL_DST);
+
+    // In the upstream direction do not forward traffic within the same /64 subnet.
+    if (!downstream && (src32 == dst32) && (ip6->saddr.s6_addr32[1] == ip6->daddr.s6_addr32[1]))
+        TC_PUNT(LOCAL_SRC_DST);
+
+    TetherDownstream6Key kd = {
             .iif = skb->ifindex,
             .neigh6 = ip6->daddr,
     };
 
-    TetherIngressValue* v = bpf_tether_ingress_map_lookup_elem(&k);
+    TetherUpstream6Key ku = {
+            .iif = skb->ifindex,
+    };
+
+    Tether6Value* v = downstream ? bpf_tether_downstream6_map_lookup_elem(&kd)
+                                 : bpf_tether_upstream6_map_lookup_elem(&ku);
 
     // If we don't find any offload information then simply let the core stack handle it...
     if (!v) return TC_ACT_OK;
 
-    uint32_t stat_and_limit_k = skb->ifindex;
+    uint32_t stat_and_limit_k = downstream ? skb->ifindex : v->oif;
 
     TetherStatsValue* stat_v = bpf_tether_stats_map_lookup_elem(&stat_and_limit_k);
 
     // If we don't have anywhere to put stats, then abort...
-    if (!stat_v) return TC_ACT_OK;
+    if (!stat_v) TC_PUNT(NO_STATS_ENTRY);
 
     uint64_t* limit_v = bpf_tether_limit_map_lookup_elem(&stat_and_limit_k);
 
     // If we don't have a limit, then abort...
-    if (!limit_v) return TC_ACT_OK;
+    if (!limit_v) TC_PUNT(NO_LIMIT_ENTRY);
 
     // Required IPv6 minimum mtu is 1280, below that not clear what we should do, abort...
-    const int pmtu = v->pmtu;
-    if (pmtu < IPV6_MIN_MTU) return TC_ACT_OK;
+    if (v->pmtu < IPV6_MIN_MTU) TC_PUNT(BELOW_IPV6_MTU);
 
     // Approximate handling of TCP/IPv6 overhead for incoming LRO/GRO packets: default
     // outbound path mtu of 1500 is not necessarily correct, but worst case we simply
@@ -98,9 +201,9 @@
     // (This is also blindly assuming 12 bytes of tcp timestamp option in tcp header)
     uint64_t packets = 1;
     uint64_t bytes = skb->len;
-    if (bytes > pmtu) {
+    if (bytes > v->pmtu) {
         const int tcp_overhead = sizeof(struct ipv6hdr) + sizeof(struct tcphdr) + 12;
-        const int mss = pmtu - tcp_overhead;
+        const int mss = v->pmtu - tcp_overhead;
         const uint64_t payload = bytes - tcp_overhead;
         packets = (payload + mss - 1) / mss;
         bytes = tcp_overhead * packets + payload;
@@ -112,15 +215,15 @@
     // a packet we let the core stack deal with things.
     // (The core stack needs to handle limits correctly anyway,
     // since we don't offload all traffic in both directions)
-    if (stat_v->rxBytes + stat_v->txBytes + bytes > *limit_v) return TC_ACT_OK;
+    if (stat_v->rxBytes + stat_v->txBytes + bytes > *limit_v) TC_PUNT(LIMIT_REACHED);
 
     if (!is_ethernet) {
-        is_ethernet = true;
-        l2_header_size = sizeof(struct ethhdr);
-        // Try to inject an ethernet header, and simply return if we fail
-        if (bpf_skb_change_head(skb, l2_header_size, /*flags*/ 0)) {
-            __sync_fetch_and_add(&stat_v->rxErrors, 1);
-            return TC_ACT_OK;
+        // Try to inject an ethernet header, and simply return if we fail.
+        // We do this even if TX interface is RAWIP and thus does not need an ethernet header,
+        // because this is easier and the kernel will strip extraneous ethernet header.
+        if (bpf_skb_change_head(skb, sizeof(struct ethhdr), /*flags*/ 0)) {
+            __sync_fetch_and_add(downstream ? &stat_v->rxErrors : &stat_v->txErrors, 1);
+            TC_PUNT(CHANGE_HEAD_FAILED);
         }
 
         // bpf_skb_change_head() invalidates all pointers - reload them
@@ -130,12 +233,16 @@
         ip6 = (void*)(eth + 1);
 
         // I do not believe this can ever happen, but keep the verifier happy...
-        if (data + l2_header_size + sizeof(*ip6) > data_end) {
-            __sync_fetch_and_add(&stat_v->rxErrors, 1);
-            return TC_ACT_SHOT;
+        if (data + sizeof(struct ethhdr) + sizeof(*ip6) > data_end) {
+            __sync_fetch_and_add(downstream ? &stat_v->rxErrors : &stat_v->txErrors, 1);
+            TC_DROP(TOO_SHORT);
         }
     };
 
+    // At this point we always have an ethernet header - which will get stripped by the
+    // kernel during transmit through a rawip interface.  ie. 'eth' pointer is valid.
+    // Additionally note that 'is_ethernet' and 'l2_header_size' are no longer correct.
+
     // CHECKSUM_COMPLETE is a 16-bit one's complement sum,
     // thus corrections for it need to be done in 16-byte chunks at even offsets.
     // IPv6 nexthdr is at offset 6, while hop limit is at offset 7
@@ -147,10 +254,11 @@
     // (-ENOTSUPP) if it isn't.
     bpf_csum_update(skb, 0xFFFF - ntohs(old_hl) + ntohs(new_hl));
 
-    __sync_fetch_and_add(&stat_v->rxPackets, packets);
-    __sync_fetch_and_add(&stat_v->rxBytes, bytes);
+    __sync_fetch_and_add(downstream ? &stat_v->rxPackets : &stat_v->txPackets, packets);
+    __sync_fetch_and_add(downstream ? &stat_v->rxBytes : &stat_v->txBytes, bytes);
 
     // Overwrite any mac header with the new one
+    // For a rawip tx interface it will simply be a bunch of zeroes and later stripped.
     *eth = v->macHeader;
 
     // Redirect to forwarded interface.
@@ -162,9 +270,16 @@
     return bpf_redirect(v->oif, 0 /* this is effectively BPF_F_EGRESS */);
 }
 
-SEC("schedcls/ingress/tether_ether")
-int sched_cls_ingress_tether_ether(struct __sk_buff* skb) {
-    return do_forward(skb, true);
+DEFINE_BPF_PROG("schedcls/tether_downstream6_ether", AID_ROOT, AID_NETWORK_STACK,
+                sched_cls_tether_downstream6_ether)
+(struct __sk_buff* skb) {
+    return do_forward6(skb, /* is_ethernet */ true, /* downstream */ true);
+}
+
+DEFINE_BPF_PROG("schedcls/tether_upstream6_ether", AID_ROOT, AID_NETWORK_STACK,
+                sched_cls_tether_upstream6_ether)
+(struct __sk_buff* skb) {
+    return do_forward6(skb, /* is_ethernet */ true, /* downstream */ false);
 }
 
 // Note: section names must be unique to prevent programs from appending to each other,
@@ -179,29 +294,458 @@
 // 5.4 kernel support was only added to Android Common Kernel in R,
 // and thus a 5.4 kernel always supports this.
 //
-// Hence, this mandatory (must load successfully) implementation for 5.4+ kernels:
-DEFINE_BPF_PROG_KVER("schedcls/ingress/tether_rawip$5_4", AID_ROOT, AID_ROOT,
-                     sched_cls_ingress_tether_rawip_5_4, KVER(5, 4, 0))
+// Hence, these mandatory (must load successfully) implementations for 5.4+ kernels:
+DEFINE_BPF_PROG_KVER("schedcls/tether_downstream6_rawip$5_4", AID_ROOT, AID_NETWORK_STACK,
+                     sched_cls_tether_downstream6_rawip_5_4, KVER(5, 4, 0))
 (struct __sk_buff* skb) {
-    return do_forward(skb, false);
+    return do_forward6(skb, /* is_ethernet */ false, /* downstream */ true);
 }
 
-// and this identical optional (may fail to load) implementation for [4.14..5.4) patched kernels:
-DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/ingress/tether_rawip$4_14", AID_ROOT, AID_ROOT,
-                                    sched_cls_ingress_tether_rawip_4_14, KVER(4, 14, 0),
-                                    KVER(5, 4, 0))
+DEFINE_BPF_PROG_KVER("schedcls/tether_upstream6_rawip$5_4", AID_ROOT, AID_NETWORK_STACK,
+                     sched_cls_tether_upstream6_rawip_5_4, KVER(5, 4, 0))
 (struct __sk_buff* skb) {
-    return do_forward(skb, false);
+    return do_forward6(skb, /* is_ethernet */ false, /* downstream */ false);
 }
 
-// and define a no-op stub for [4.9,4.14) and unpatched [4.14,5.4) kernels.
+// and these identical optional (may fail to load) implementations for [4.14..5.4) patched kernels:
+DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_downstream6_rawip$4_14",
+                                    AID_ROOT, AID_NETWORK_STACK,
+                                    sched_cls_tether_downstream6_rawip_4_14,
+                                    KVER(4, 14, 0), KVER(5, 4, 0))
+(struct __sk_buff* skb) {
+    return do_forward6(skb, /* is_ethernet */ false, /* downstream */ true);
+}
+
+DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_upstream6_rawip$4_14",
+                                    AID_ROOT, AID_NETWORK_STACK,
+                                    sched_cls_tether_upstream6_rawip_4_14,
+                                    KVER(4, 14, 0), KVER(5, 4, 0))
+(struct __sk_buff* skb) {
+    return do_forward6(skb, /* is_ethernet */ false, /* downstream */ false);
+}
+
+// and define no-op stubs for [4.9,4.14) and unpatched [4.14,5.4) kernels.
 // (if the above real 4.14+ program loaded successfully, then bpfloader will have already pinned
 // it at the same location this one would be pinned at and will thus skip loading this stub)
-DEFINE_BPF_PROG_KVER_RANGE("schedcls/ingress/tether_rawip$stub", AID_ROOT, AID_ROOT,
-                           sched_cls_ingress_tether_rawip_stub, KVER_NONE, KVER(5, 4, 0))
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream6_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
+                           sched_cls_tether_downstream6_rawip_stub, KVER_NONE, KVER(5, 4, 0))
 (struct __sk_buff* skb) {
     return TC_ACT_OK;
 }
 
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream6_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
+                           sched_cls_tether_upstream6_rawip_stub, KVER_NONE, KVER(5, 4, 0))
+(struct __sk_buff* skb) {
+    return TC_ACT_OK;
+}
+
+// ----- IPv4 Support -----
+
+DEFINE_BPF_MAP_GRW(tether_downstream4_map, HASH, Tether4Key, Tether4Value, 64, AID_NETWORK_STACK)
+
+DEFINE_BPF_MAP_GRW(tether_upstream4_map, HASH, Tether4Key, Tether4Value, 64, AID_NETWORK_STACK)
+
+static inline __always_inline int do_forward4(struct __sk_buff* skb, const bool is_ethernet,
+        const bool downstream, const bool updatetime) {
+    const int l2_header_size = is_ethernet ? sizeof(struct ethhdr) : 0;
+    void* data = (void*)(long)skb->data;
+    const void* data_end = (void*)(long)skb->data_end;
+    struct ethhdr* eth = is_ethernet ? data : NULL;  // used iff is_ethernet
+    struct iphdr* ip = is_ethernet ? (void*)(eth + 1) : data;
+
+    // Require ethernet dst mac address to be our unicast address.
+    if (is_ethernet && (skb->pkt_type != PACKET_HOST)) return TC_ACT_OK;
+
+    // Must be meta-ethernet IPv4 frame
+    if (skb->protocol != htons(ETH_P_IP)) return TC_ACT_OK;
+
+    // Must have (ethernet and) ipv4 header
+    if (data + l2_header_size + sizeof(*ip) > data_end) return TC_ACT_OK;
+
+    // Ethertype - if present - must be IPv4
+    if (is_ethernet && (eth->h_proto != htons(ETH_P_IP))) return TC_ACT_OK;
+
+    // IP version must be 4
+    if (ip->version != 4) TC_PUNT(INVALID_IP_VERSION);
+
+    // We cannot handle IP options, just standard 20 byte == 5 dword minimal IPv4 header
+    if (ip->ihl != 5) TC_PUNT(HAS_IP_OPTIONS);
+
+    // Calculate the IPv4 one's complement checksum of the IPv4 header.
+    __wsum sum4 = 0;
+    for (int i = 0; i < sizeof(*ip) / sizeof(__u16); ++i) {
+        sum4 += ((__u16*)ip)[i];
+    }
+    // Note that sum4 is guaranteed to be non-zero by virtue of ip4->version == 4
+    sum4 = (sum4 & 0xFFFF) + (sum4 >> 16);  // collapse u32 into range 1 .. 0x1FFFE
+    sum4 = (sum4 & 0xFFFF) + (sum4 >> 16);  // collapse any potential carry into u16
+    // for a correct checksum we should get *a* zero, but sum4 must be positive, ie 0xFFFF
+    if (sum4 != 0xFFFF) TC_PUNT(CHECKSUM);
+
+    // Minimum IPv4 total length is the size of the header
+    if (ntohs(ip->tot_len) < sizeof(*ip)) TC_PUNT(TRUNCATED_IPV4);
+
+    // We are incapable of dealing with IPv4 fragments
+    if (ip->frag_off & ~htons(IP_DF)) TC_PUNT(IS_IP_FRAG);
+
+    // Cannot decrement during forward if already zero or would be zero,
+    // Let the kernel's stack handle these cases and generate appropriate ICMP errors.
+    if (ip->ttl <= 1) TC_PUNT(LOW_TTL);
+
+    // If we cannot update the 'last_used' field due to lack of bpf_ktime_get_boot_ns() helper,
+    // then it is not safe to offload UDP due to the small conntrack timeouts, as such,
+    // in such a situation we can only support TCP.  This also has the added nice benefit of
+    // using a separate error counter, and thus making it obvious which version of the program
+    // is loaded.
+    if (!updatetime && ip->protocol != IPPROTO_TCP) TC_PUNT(NON_TCP);
+
+    // We do not support offloading anything besides IPv4 TCP and UDP, due to need for NAT,
+    // but no need to check this if !updatetime due to check immediately above.
+    if (updatetime && (ip->protocol != IPPROTO_TCP) && (ip->protocol != IPPROTO_UDP))
+        TC_PUNT(NON_TCP_UDP);
+
+    // We want to make sure that the compiler will, in the !updatetime case, entirely optimize
+    // out all the non-tcp logic.  Also note that at this point is_udp === !is_tcp.
+    const bool is_tcp = !updatetime || (ip->protocol == IPPROTO_TCP);
+
+    // This is a bit of a hack to make things easier on the bpf verifier.
+    // (In particular I believe the Linux 4.14 kernel's verifier can get confused later on about
+    // what offsets into the packet are valid and can spuriously reject the program, this is
+    // because it fails to realize that is_tcp && !is_tcp is impossible)
+    //
+    // For both TCP & UDP we'll need to read and modify the src/dst ports, which so happen to
+    // always be in the first 4 bytes of the L4 header.  Additionally for UDP we'll need access
+    // to the checksum field which is in bytes 7 and 8.  While for TCP we'll need to read the
+    // TCP flags (at offset 13) and access to the checksum field (2 bytes at offset 16).
+    // As such we *always* need access to at least 8 bytes.
+    if (data + l2_header_size + sizeof(*ip) + 8 > data_end) TC_PUNT(SHORT_L4_HEADER);
+
+    struct tcphdr* tcph = is_tcp ? (void*)(ip + 1) : NULL;
+    struct udphdr* udph = is_tcp ? NULL : (void*)(ip + 1);
+
+    if (is_tcp) {
+        // Make sure we can get at the tcp header
+        if (data + l2_header_size + sizeof(*ip) + sizeof(*tcph) > data_end)
+            TC_PUNT(SHORT_TCP_HEADER);
+
+        // If hardware offload is running and programming flows based on conntrack entries, try not
+        // to interfere with it, so do not offload TCP packets with any one of the SYN/FIN/RST flags
+        if (tcph->syn || tcph->fin || tcph->rst) TC_PUNT(TCP_CONTROL_PACKET);
+    } else { // UDP
+        // Make sure we can get at the udp header
+        if (data + l2_header_size + sizeof(*ip) + sizeof(*udph) > data_end)
+            TC_PUNT(SHORT_UDP_HEADER);
+
+        // Skip handling of CHECKSUM_COMPLETE packets with udp checksum zero due to need for
+        // additional updating of skb->csum (this could be fixed up manually with more effort).
+        //
+        // Note that the in-kernel implementation of 'int64_t bpf_csum_update(skb, u32 csum)' is:
+        //   if (skb->ip_summed == CHECKSUM_COMPLETE)
+        //     return (skb->csum = csum_add(skb->csum, csum));
+        //   else
+        //     return -ENOTSUPP;
+        //
+        // So this will punt any CHECKSUM_COMPLETE packet with a zero UDP checksum,
+        // and leave all other packets unaffected (since it just at most adds zero to skb->csum).
+        //
+        // In practice this should almost never trigger because most nics do not generate
+        // CHECKSUM_COMPLETE packets on receive - especially so for nics/drivers on a phone.
+        //
+        // Additionally since we're forwarding, in most cases the value of the skb->csum field
+        // shouldn't matter (it's not used by physical nic egress).
+        //
+        // It only matters if we're ingressing through a CHECKSUM_COMPLETE capable nic
+        // and egressing through a virtual interface looping back to the kernel itself
+        // (ie. something like veth) where the CHECKSUM_COMPLETE/skb->csum can get reused
+        // on ingress.
+        //
+        // If we were in the kernel we'd simply probably call
+        //   void skb_checksum_complete_unset(struct sk_buff *skb) {
+        //     if (skb->ip_summed == CHECKSUM_COMPLETE) skb->ip_summed = CHECKSUM_NONE;
+        //   }
+        // here instead.  Perhaps there should be a bpf helper for that?
+        if (!udph->check && (bpf_csum_update(skb, 0) >= 0)) TC_PUNT(UDP_CSUM_ZERO);
+    }
+
+    Tether4Key k = {
+            .iif = skb->ifindex,
+            .l4Proto = ip->protocol,
+            .src4.s_addr = ip->saddr,
+            .dst4.s_addr = ip->daddr,
+            .srcPort = is_tcp ? tcph->source : udph->source,
+            .dstPort = is_tcp ? tcph->dest : udph->dest,
+    };
+    if (is_ethernet) for (int i = 0; i < ETH_ALEN; ++i) k.dstMac[i] = eth->h_dest[i];
+
+    Tether4Value* v = downstream ? bpf_tether_downstream4_map_lookup_elem(&k)
+                                 : bpf_tether_upstream4_map_lookup_elem(&k);
+
+    // If we don't find any offload information then simply let the core stack handle it...
+    if (!v) return TC_ACT_OK;
+
+    uint32_t stat_and_limit_k = downstream ? skb->ifindex : v->oif;
+
+    TetherStatsValue* stat_v = bpf_tether_stats_map_lookup_elem(&stat_and_limit_k);
+
+    // If we don't have anywhere to put stats, then abort...
+    if (!stat_v) TC_PUNT(NO_STATS_ENTRY);
+
+    uint64_t* limit_v = bpf_tether_limit_map_lookup_elem(&stat_and_limit_k);
+
+    // If we don't have a limit, then abort...
+    if (!limit_v) TC_PUNT(NO_LIMIT_ENTRY);
+
+    // Required IPv4 minimum mtu is 68, below that not clear what we should do, abort...
+    if (v->pmtu < 68) TC_PUNT(BELOW_IPV4_MTU);
+
+    // Approximate handling of TCP/IPv4 overhead for incoming LRO/GRO packets: default
+    // outbound path mtu of 1500 is not necessarily correct, but worst case we simply
+    // undercount, which is still better then not accounting for this overhead at all.
+    // Note: this really shouldn't be device/path mtu at all, but rather should be
+    // derived from this particular connection's mss (ie. from gro segment size).
+    // This would require a much newer kernel with newer ebpf accessors.
+    // (This is also blindly assuming 12 bytes of tcp timestamp option in tcp header)
+    uint64_t packets = 1;
+    uint64_t bytes = skb->len;
+    if (bytes > v->pmtu) {
+        const int tcp_overhead = sizeof(struct iphdr) + sizeof(struct tcphdr) + 12;
+        const int mss = v->pmtu - tcp_overhead;
+        const uint64_t payload = bytes - tcp_overhead;
+        packets = (payload + mss - 1) / mss;
+        bytes = tcp_overhead * packets + payload;
+    }
+
+    // Are we past the limit?  If so, then abort...
+    // Note: will not overflow since u64 is 936 years even at 5Gbps.
+    // Do not drop here.  Offload is just that, whenever we fail to handle
+    // a packet we let the core stack deal with things.
+    // (The core stack needs to handle limits correctly anyway,
+    // since we don't offload all traffic in both directions)
+    if (stat_v->rxBytes + stat_v->txBytes + bytes > *limit_v) TC_PUNT(LIMIT_REACHED);
+
+    if (!is_ethernet) {
+        // Try to inject an ethernet header, and simply return if we fail.
+        // We do this even if TX interface is RAWIP and thus does not need an ethernet header,
+        // because this is easier and the kernel will strip extraneous ethernet header.
+        if (bpf_skb_change_head(skb, sizeof(struct ethhdr), /*flags*/ 0)) {
+            __sync_fetch_and_add(downstream ? &stat_v->rxErrors : &stat_v->txErrors, 1);
+            TC_PUNT(CHANGE_HEAD_FAILED);
+        }
+
+        // bpf_skb_change_head() invalidates all pointers - reload them
+        data = (void*)(long)skb->data;
+        data_end = (void*)(long)skb->data_end;
+        eth = data;
+        ip = (void*)(eth + 1);
+        tcph = is_tcp ? (void*)(ip + 1) : NULL;
+        udph = is_tcp ? NULL : (void*)(ip + 1);
+
+        // I do not believe this can ever happen, but keep the verifier happy...
+        if (data + sizeof(struct ethhdr) + sizeof(*ip) + (is_tcp ? sizeof(*tcph) : sizeof(*udph)) > data_end) {
+            __sync_fetch_and_add(downstream ? &stat_v->rxErrors : &stat_v->txErrors, 1);
+            TC_DROP(TOO_SHORT);
+        }
+    };
+
+    // At this point we always have an ethernet header - which will get stripped by the
+    // kernel during transmit through a rawip interface.  ie. 'eth' pointer is valid.
+    // Additionally note that 'is_ethernet' and 'l2_header_size' are no longer correct.
+
+    // Overwrite any mac header with the new one
+    // For a rawip tx interface it will simply be a bunch of zeroes and later stripped.
+    *eth = v->macHeader;
+
+    const int l4_offs_csum = is_tcp ? ETH_IP4_TCP_OFFSET(check) : ETH_IP4_UDP_OFFSET(check);
+    const int sz4 = sizeof(__be32);
+    // UDP 0 is special and stored as FFFF (this flag also causes a csum of 0 to be unmodified)
+    const int l4_flags = is_tcp ? 0 : BPF_F_MARK_MANGLED_0;
+    const __be32 old_daddr = k.dst4.s_addr;
+    const __be32 old_saddr = k.src4.s_addr;
+    const __be32 new_daddr = v->dst46.s6_addr32[3];
+    const __be32 new_saddr = v->src46.s6_addr32[3];
+
+    bpf_l4_csum_replace(skb, l4_offs_csum, old_daddr, new_daddr, sz4 | BPF_F_PSEUDO_HDR | l4_flags);
+    bpf_l3_csum_replace(skb, ETH_IP4_OFFSET(check), old_daddr, new_daddr, sz4);
+    bpf_skb_store_bytes(skb, ETH_IP4_OFFSET(daddr), &new_daddr, sz4, 0);
+
+    bpf_l4_csum_replace(skb, l4_offs_csum, old_saddr, new_saddr, sz4 | BPF_F_PSEUDO_HDR | l4_flags);
+    bpf_l3_csum_replace(skb, ETH_IP4_OFFSET(check), old_saddr, new_saddr, sz4);
+    bpf_skb_store_bytes(skb, ETH_IP4_OFFSET(saddr), &new_saddr, sz4, 0);
+
+    const int sz2 = sizeof(__be16);
+    // The offsets for TCP and UDP ports: source (u16 @ L4 offset 0) & dest (u16 @ L4 offset 2) are
+    // actually the same, so the compiler should just optimize them both down to a constant.
+    bpf_l4_csum_replace(skb, l4_offs_csum, k.srcPort, v->srcPort, sz2 | l4_flags);
+    bpf_skb_store_bytes(skb, is_tcp ? ETH_IP4_TCP_OFFSET(source) : ETH_IP4_UDP_OFFSET(source),
+                        &v->srcPort, sz2, 0);
+
+    bpf_l4_csum_replace(skb, l4_offs_csum, k.dstPort, v->dstPort, sz2 | l4_flags);
+    bpf_skb_store_bytes(skb, is_tcp ? ETH_IP4_TCP_OFFSET(dest) : ETH_IP4_UDP_OFFSET(dest),
+                        &v->dstPort, sz2, 0);
+
+    // TEMP HACK: lack of TTL decrement
+
+    // This requires the bpf_ktime_get_boot_ns() helper which was added in 5.8,
+    // and backported to all Android Common Kernel 4.14+ trees.
+    if (updatetime) v->last_used = bpf_ktime_get_boot_ns();
+
+    __sync_fetch_and_add(downstream ? &stat_v->rxPackets : &stat_v->txPackets, packets);
+    __sync_fetch_and_add(downstream ? &stat_v->rxBytes : &stat_v->txBytes, bytes);
+
+    // Redirect to forwarded interface.
+    //
+    // Note that bpf_redirect() cannot fail unless you pass invalid flags.
+    // The redirect actually happens after the ebpf program has already terminated,
+    // and can fail for example for mtu reasons at that point in time, but there's nothing
+    // we can do about it here.
+    return bpf_redirect(v->oif, 0 /* this is effectively BPF_F_EGRESS */);
+}
+
+// Full featured (required) implementations for 5.8+ kernels
+
+DEFINE_BPF_PROG_KVER("schedcls/tether_downstream4_ether$5_8", AID_ROOT, AID_NETWORK_STACK,
+                     sched_cls_tether_downstream4_ether_5_8, KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+    return do_forward4(skb, /* is_ethernet */ true, /* downstream */ true, /* updatetime */ true);
+}
+
+DEFINE_BPF_PROG_KVER("schedcls/tether_downstream4_rawip$5_8", AID_ROOT, AID_NETWORK_STACK,
+                     sched_cls_tether_downstream4_rawip_5_8, KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+    return do_forward4(skb, /* is_ethernet */ false, /* downstream */ true, /* updatetime */ true);
+}
+
+DEFINE_BPF_PROG_KVER("schedcls/tether_upstream4_ether$5_8", AID_ROOT, AID_NETWORK_STACK,
+                     sched_cls_tether_upstream4_ether_5_8, KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+    return do_forward4(skb, /* is_ethernet */ true, /* downstream */ false, /* updatetime */ true);
+}
+
+DEFINE_BPF_PROG_KVER("schedcls/tether_upstream4_rawip$5_8", AID_ROOT, AID_NETWORK_STACK,
+                     sched_cls_tether_upstream4_rawip_5_8, KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+    return do_forward4(skb, /* is_ethernet */ false, /* downstream */ false, /* updatetime */ true);
+}
+
+// Full featured (optional) implementations for [4.14..5.8) kernels
+
+DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_ether$opt",
+                                    AID_ROOT, AID_NETWORK_STACK,
+                                    sched_cls_tether_downstream4_ether_opt,
+                                    KVER(4, 14, 0), KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+    return do_forward4(skb, /* is_ethernet */ true, /* downstream */ true, /* updatetime */ true);
+}
+
+DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_rawip$opt",
+                                    AID_ROOT, AID_NETWORK_STACK,
+                                    sched_cls_tether_downstream4_rawip_opt,
+                                    KVER(4, 14, 0), KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+    return do_forward4(skb, /* is_ethernet */ false, /* downstream */ true, /* updatetime */ true);
+}
+
+DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_ether$opt",
+                                    AID_ROOT, AID_NETWORK_STACK,
+                                    sched_cls_tether_upstream4_ether_opt,
+                                    KVER(4, 14, 0), KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+    return do_forward4(skb, /* is_ethernet */ true, /* downstream */ false, /* updatetime */ true);
+}
+
+DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_rawip$opt",
+                                    AID_ROOT, AID_NETWORK_STACK,
+                                    sched_cls_tether_upstream4_rawip_opt,
+                                    KVER(4, 14, 0), KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+    return do_forward4(skb, /* is_ethernet */ false, /* downstream */ false, /* updatetime */ true);
+}
+
+// Partial (TCP-only: will not update 'last_used' field) implementations for 4.14+ kernels.
+// These will be loaded only if the above optional ones failed (loading of *these* must succeed).
+//
+// [Note: as a result TCP connections will not have their conntrack timeout refreshed, however,
+// since /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established defaults to 432000 (seconds),
+// this in practice means they'll break only after 5 days.  This seems an acceptable trade-off.
+//
+// Additionally kernel/tests change "net-test: add bpf_ktime_get_ns / bpf_ktime_get_boot_ns tests"
+// which enforces and documents the required kernel cherrypicks will make it pretty unlikely that
+// many devices upgrading to S will end up relying on these fallback programs.
+
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_ether$4_14", AID_ROOT, AID_NETWORK_STACK,
+                           sched_cls_tether_downstream4_ether_4_14, KVER(4, 14, 0), KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+    return do_forward4(skb, /* is_ethernet */ true, /* downstream */ true, /* updatetime */ false);
+}
+
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_rawip$4_14", AID_ROOT, AID_NETWORK_STACK,
+                           sched_cls_tether_downstream4_rawip_4_14, KVER(4, 14, 0), KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+    return do_forward4(skb, /* is_ethernet */ false, /* downstream */ true, /* updatetime */ false);
+}
+
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_ether$4_14", AID_ROOT, AID_NETWORK_STACK,
+                           sched_cls_tether_upstream4_ether_4_14, KVER(4, 14, 0), KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+    return do_forward4(skb, /* is_ethernet */ true, /* downstream */ false, /* updatetime */ false);
+}
+
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_rawip$4_14", AID_ROOT, AID_NETWORK_STACK,
+                           sched_cls_tether_upstream4_rawip_4_14, KVER(4, 14, 0), KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+    return do_forward4(skb, /* is_ethernet */ false, /* downstream */ false, /* updatetime */ false);
+}
+
+// Placeholder (no-op) implementations for older pre-4.14 kernels
+
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_ether$stub", AID_ROOT, AID_NETWORK_STACK,
+                           sched_cls_tether_downstream4_ether_stub, KVER_NONE, KVER(4, 14, 0))
+(struct __sk_buff* skb) {
+    return TC_ACT_OK;
+}
+
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
+                           sched_cls_tether_downstream4_rawip_stub, KVER_NONE, KVER(4, 14, 0))
+(struct __sk_buff* skb) {
+    return TC_ACT_OK;
+}
+
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_ether$stub", AID_ROOT, AID_NETWORK_STACK,
+                           sched_cls_tether_upstream4_ether_stub, KVER_NONE, KVER(4, 14, 0))
+(struct __sk_buff* skb) {
+    return TC_ACT_OK;
+}
+
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
+                           sched_cls_tether_upstream4_rawip_stub, KVER_NONE, KVER(4, 14, 0))
+(struct __sk_buff* skb) {
+    return TC_ACT_OK;
+}
+
+// ----- XDP Support -----
+
+#define DEFINE_XDP_PROG(str, func) \
+    DEFINE_BPF_PROG_KVER(str, AID_ROOT, AID_NETWORK_STACK, func, KVER(5, 9, 0))(struct xdp_md *ctx)
+
+DEFINE_XDP_PROG("xdp/tether_downstream_ether",
+                 xdp_tether_downstream_ether) {
+    return XDP_PASS;
+}
+
+DEFINE_XDP_PROG("xdp/tether_downstream_rawip",
+                 xdp_tether_downstream_rawip) {
+    return XDP_PASS;
+}
+
+DEFINE_XDP_PROG("xdp/tether_upstream_ether",
+                 xdp_tether_upstream_ether) {
+    return XDP_PASS;
+}
+
+DEFINE_XDP_PROG("xdp/tether_upstream_rawip",
+                 xdp_tether_upstream_rawip) {
+    return XDP_PASS;
+}
+
 LICENSE("Apache 2.0");
 CRITICAL("netd");
diff --git a/Tethering/bpf_progs/test.c b/Tethering/bpf_progs/test.c
new file mode 100644
index 0000000..c4a8271
--- /dev/null
+++ b/Tethering/bpf_progs/test.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <linux/if_ether.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+
+#include "bpf_helpers.h"
+#include "bpf_net_helpers.h"
+#include "netdbpf/bpf_shared.h"
+
+// Used only by TetheringPrivilegedTests, not by production code.
+DEFINE_BPF_MAP_GRW(tether_downstream6_map, HASH, TetherDownstream6Key, Tether6Value, 16,
+                   AID_NETWORK_STACK)
+
+DEFINE_BPF_PROG_KVER("xdp/drop_ipv4_udp_ether", AID_ROOT, AID_NETWORK_STACK,
+                      xdp_test, KVER(5, 9, 0))
+(struct xdp_md *ctx) {
+    void *data = (void *)(long)ctx->data;
+    void *data_end = (void *)(long)ctx->data_end;
+
+    struct ethhdr *eth = data;
+    int hsize = sizeof(*eth);
+
+    struct iphdr *ip = data + hsize;
+    hsize += sizeof(struct iphdr);
+
+    if (data + hsize > data_end) return XDP_PASS;
+    if (eth->h_proto != htons(ETH_P_IP)) return XDP_PASS;
+    if (ip->protocol == IPPROTO_UDP) return XDP_DROP;
+    return XDP_PASS;
+}
+
+LICENSE("Apache 2.0");
diff --git a/Tethering/common/TetheringLib/Android.bp b/Tethering/common/TetheringLib/Android.bp
index a10729d..2631d08 100644
--- a/Tethering/common/TetheringLib/Android.bp
+++ b/Tethering/common/TetheringLib/Android.bp
@@ -13,6 +13,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 java_sdk_library {
     name: "framework-tethering",
     defaults: ["framework-module-defaults"],
diff --git a/Tethering/jarjar-rules.txt b/Tethering/jarjar-rules.txt
index 591861f..d1ad569 100644
--- a/Tethering/jarjar-rules.txt
+++ b/Tethering/jarjar-rules.txt
@@ -8,4 +8,7 @@
 rule android.net.shared.Inet4AddressUtils* com.android.networkstack.tethering.shared.Inet4AddressUtils@1
 
 # Classes from net-utils-framework-common
-rule com.android.net.module.util.** com.android.networkstack.tethering.util.@1
\ No newline at end of file
+rule com.android.net.module.util.** com.android.networkstack.tethering.util.@1
+
+# Classes from net-utils-device-common
+rule com.android.net.module.util.Struct* com.android.networkstack.tethering.util.Struct@1
diff --git a/Tethering/jni/android_net_util_TetheringUtils.cpp b/Tethering/jni/android_net_util_TetheringUtils.cpp
index 7bfb6da..27c84cf 100644
--- a/Tethering/jni/android_net_util_TetheringUtils.cpp
+++ b/Tethering/jni/android_net_util_TetheringUtils.cpp
@@ -28,9 +28,6 @@
 #include <sys/socket.h>
 #include <stdio.h>
 
-#define LOG_TAG "TetheringUtils"
-#include <android/log.h>
-
 namespace android {
 
 static const uint32_t kIPv6NextHeaderOffset = offsetof(ip6_hdr, ip6_nxt);
@@ -184,18 +181,4 @@
             gMethods, NELEM(gMethods));
 }
 
-extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
-    JNIEnv *env;
-    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
-        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: GetEnv failed");
-        return JNI_ERR;
-    }
-
-    if (register_android_net_util_TetheringUtils(env) < 0) {
-        return JNI_ERR;
-    }
-
-    return JNI_VERSION_1_6;
-}
-
 }; // namespace android
diff --git a/Tethering/jni/com_android_networkstack_tethering_BpfCoordinator.cpp b/Tethering/jni/com_android_networkstack_tethering_BpfCoordinator.cpp
new file mode 100644
index 0000000..27357f8
--- /dev/null
+++ b/Tethering/jni/com_android_networkstack_tethering_BpfCoordinator.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+
+#include "bpf_tethering.h"
+
+namespace android {
+
+static jobjectArray getBpfCounterNames(JNIEnv *env) {
+    size_t size = BPF_TETHER_ERR__MAX;
+    jobjectArray ret = env->NewObjectArray(size, env->FindClass("java/lang/String"), nullptr);
+    for (int i = 0; i < size; i++) {
+        env->SetObjectArrayElement(ret, i, env->NewStringUTF(bpf_tether_errors[i]));
+    }
+    return ret;
+}
+
+/*
+ * JNI registration.
+ */
+static const JNINativeMethod gMethods[] = {
+    /* name, signature, funcPtr */
+    { "getBpfCounterNames", "()[Ljava/lang/String;", (void*) getBpfCounterNames },
+};
+
+int register_com_android_networkstack_tethering_BpfCoordinator(JNIEnv* env) {
+    return jniRegisterNativeMethods(env,
+            "com/android/networkstack/tethering/BpfCoordinator",
+            gMethods, NELEM(gMethods));
+}
+
+}; // namespace android
diff --git a/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp b/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp
new file mode 100644
index 0000000..eadc210
--- /dev/null
+++ b/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include <errno.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+#include "nativehelper/scoped_primitive_array.h"
+#include "nativehelper/scoped_utf_chars.h"
+
+#define BPF_FD_JUST_USE_INT
+#include "BpfSyscallWrappers.h"
+
+namespace android {
+
+static jclass sErrnoExceptionClass;
+static jmethodID sErrnoExceptionCtor2;
+static jmethodID sErrnoExceptionCtor3;
+
+static void throwErrnoException(JNIEnv* env, const char* functionName, int error) {
+    if (sErrnoExceptionClass == nullptr || sErrnoExceptionClass == nullptr) return;
+
+    jthrowable cause = nullptr;
+    if (env->ExceptionCheck()) {
+        cause = env->ExceptionOccurred();
+        env->ExceptionClear();
+    }
+
+    ScopedLocalRef<jstring> msg(env, env->NewStringUTF(functionName));
+
+    // Not really much we can do here if msg is null, let's try to stumble on...
+    if (msg.get() == nullptr) env->ExceptionClear();
+
+    jobject errnoException;
+    if (cause != nullptr) {
+        errnoException = env->NewObject(sErrnoExceptionClass, sErrnoExceptionCtor3, msg.get(),
+                error, cause);
+    } else {
+        errnoException = env->NewObject(sErrnoExceptionClass, sErrnoExceptionCtor2, msg.get(),
+                error);
+    }
+    env->Throw(static_cast<jthrowable>(errnoException));
+}
+
+static jint com_android_networkstack_tethering_BpfMap_closeMap(JNIEnv *env, jobject clazz,
+        jint fd) {
+    int ret = close(fd);
+
+    if (ret) throwErrnoException(env, "closeMap", errno);
+
+    return ret;
+}
+
+static jint com_android_networkstack_tethering_BpfMap_bpfFdGet(JNIEnv *env, jobject clazz,
+        jstring path, jint mode) {
+    ScopedUtfChars pathname(env, path);
+
+    jint fd = bpf::bpfFdGet(pathname.c_str(), static_cast<unsigned>(mode));
+
+    return fd;
+}
+
+static void com_android_networkstack_tethering_BpfMap_writeToMapEntry(JNIEnv *env, jobject clazz,
+        jint fd, jbyteArray key, jbyteArray value, jint flags) {
+    ScopedByteArrayRO keyRO(env, key);
+    ScopedByteArrayRO valueRO(env, value);
+
+    int ret = bpf::writeToMapEntry(static_cast<int>(fd), keyRO.get(), valueRO.get(),
+            static_cast<int>(flags));
+
+    if (ret) throwErrnoException(env, "writeToMapEntry", errno);
+}
+
+static jboolean throwIfNotEnoent(JNIEnv *env, const char* functionName, int ret, int err) {
+    if (ret == 0) return true;
+
+    if (err != ENOENT) throwErrnoException(env, functionName, err);
+    return false;
+}
+
+static jboolean com_android_networkstack_tethering_BpfMap_deleteMapEntry(JNIEnv *env, jobject clazz,
+        jint fd, jbyteArray key) {
+    ScopedByteArrayRO keyRO(env, key);
+
+    // On success, zero is returned.  If the element is not found, -1 is returned and errno is set
+    // to ENOENT.
+    int ret = bpf::deleteMapEntry(static_cast<int>(fd), keyRO.get());
+
+    return throwIfNotEnoent(env, "deleteMapEntry", ret, errno);
+}
+
+static jboolean com_android_networkstack_tethering_BpfMap_getNextMapKey(JNIEnv *env, jobject clazz,
+        jint fd, jbyteArray key, jbyteArray nextKey) {
+    // If key is found, the operation returns zero and sets the next key pointer to the key of the
+    // next element.  If key is not found, the operation returns zero and sets the next key pointer
+    // to the key of the first element.  If key is the last element, -1 is returned and errno is
+    // set to ENOENT.  Other possible errno values are ENOMEM, EFAULT, EPERM, and EINVAL.
+    ScopedByteArrayRW nextKeyRW(env, nextKey);
+    int ret;
+    if (key == nullptr) {
+        // Called by getFirstKey. Find the first key in the map.
+        ret = bpf::getNextMapKey(static_cast<int>(fd), nullptr, nextKeyRW.get());
+    } else {
+        ScopedByteArrayRO keyRO(env, key);
+        ret = bpf::getNextMapKey(static_cast<int>(fd), keyRO.get(), nextKeyRW.get());
+    }
+
+    return throwIfNotEnoent(env, "getNextMapKey", ret, errno);
+}
+
+static jboolean com_android_networkstack_tethering_BpfMap_findMapEntry(JNIEnv *env, jobject clazz,
+        jint fd, jbyteArray key, jbyteArray value) {
+    ScopedByteArrayRO keyRO(env, key);
+    ScopedByteArrayRW valueRW(env, value);
+
+    // If an element is found, the operation returns zero and stores the element's value into
+    // "value".  If no element is found, the operation returns -1 and sets errno to ENOENT.
+    int ret = bpf::findMapEntry(static_cast<int>(fd), keyRO.get(), valueRW.get());
+
+    return throwIfNotEnoent(env, "findMapEntry", ret, errno);
+}
+
+/*
+ * JNI registration.
+ */
+static const JNINativeMethod gMethods[] = {
+    /* name, signature, funcPtr */
+    { "closeMap", "(I)I",
+        (void*) com_android_networkstack_tethering_BpfMap_closeMap },
+    { "bpfFdGet", "(Ljava/lang/String;I)I",
+        (void*) com_android_networkstack_tethering_BpfMap_bpfFdGet },
+    { "writeToMapEntry", "(I[B[BI)V",
+        (void*) com_android_networkstack_tethering_BpfMap_writeToMapEntry },
+    { "deleteMapEntry", "(I[B)Z",
+        (void*) com_android_networkstack_tethering_BpfMap_deleteMapEntry },
+    { "getNextMapKey", "(I[B[B)Z",
+        (void*) com_android_networkstack_tethering_BpfMap_getNextMapKey },
+    { "findMapEntry", "(I[B[B)Z",
+        (void*) com_android_networkstack_tethering_BpfMap_findMapEntry },
+
+};
+
+int register_com_android_networkstack_tethering_BpfMap(JNIEnv* env) {
+    sErrnoExceptionClass = static_cast<jclass>(env->NewGlobalRef(
+            env->FindClass("android/system/ErrnoException")));
+    if (sErrnoExceptionClass == nullptr) return JNI_ERR;
+
+    sErrnoExceptionCtor2 = env->GetMethodID(sErrnoExceptionClass, "<init>",
+            "(Ljava/lang/String;I)V");
+    if (sErrnoExceptionCtor2 == nullptr) return JNI_ERR;
+
+    sErrnoExceptionCtor3 = env->GetMethodID(sErrnoExceptionClass, "<init>",
+            "(Ljava/lang/String;ILjava/lang/Throwable;)V");
+    if (sErrnoExceptionCtor3 == nullptr) return JNI_ERR;
+
+    return jniRegisterNativeMethods(env,
+            "com/android/networkstack/tethering/BpfMap",
+            gMethods, NELEM(gMethods));
+}
+
+}; // namespace android
diff --git a/Tethering/jni/onload.cpp b/Tethering/jni/onload.cpp
new file mode 100644
index 0000000..e31da60
--- /dev/null
+++ b/Tethering/jni/onload.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include <nativehelper/JNIHelp.h>
+#include "jni.h"
+
+#define LOG_TAG "TetheringJni"
+#include <android/log.h>
+
+namespace android {
+
+int register_android_net_util_TetheringUtils(JNIEnv* env);
+int register_com_android_networkstack_tethering_BpfMap(JNIEnv* env);
+int register_com_android_networkstack_tethering_BpfCoordinator(JNIEnv* env);
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
+    JNIEnv *env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "ERROR: GetEnv failed");
+        return JNI_ERR;
+    }
+
+    if (register_android_net_util_TetheringUtils(env) < 0) return JNI_ERR;
+
+    if (register_com_android_networkstack_tethering_BpfMap(env) < 0) return JNI_ERR;
+
+    if (register_com_android_networkstack_tethering_BpfCoordinator(env) < 0) return JNI_ERR;
+
+    return JNI_VERSION_1_6;
+}
+
+}; // namespace android
diff --git a/Tethering/proguard.flags b/Tethering/proguard.flags
index 86b9033..9ab56c2 100644
--- a/Tethering/proguard.flags
+++ b/Tethering/proguard.flags
@@ -4,6 +4,14 @@
     static final int EVENT_*;
 }
 
+-keep class com.android.networkstack.tethering.BpfMap {
+    native <methods>;
+}
+
+-keepclassmembers public class * extends com.android.networkstack.tethering.util.Struct {
+    public <init>(...);
+}
+
 -keepclassmembers class android.net.ip.IpServer {
     static final int CMD_*;
 }
diff --git a/Tethering/res/values-af/strings.xml b/Tethering/res/values-af/strings.xml
index 1258805..056168b 100644
--- a/Tethering/res/values-af/strings.xml
+++ b/Tethering/res/values-af/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Verbinding of Wi-Fi-warmkol aktief"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tik om op te stel."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Verbinding is gedeaktiveer"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontak jou administrateur vir besonderhede"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Verbinding of warmkol is aktief"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tik om op te stel."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Verbinding is gedeaktiveer"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontak jou administrateur vir besonderhede"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Warmkol- en verbindingstatus"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-am/strings.xml b/Tethering/res/values-am/strings.xml
index 9c36192..ac468dd 100644
--- a/Tethering/res/values-am/strings.xml
+++ b/Tethering/res/values-am/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"መሰካት ወይም ገባሪ ድረስ ነጥብ"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"ለማዋቀር መታ ያድርጉ።"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"እንደ ሞደም መሰካት ተሰናክሏል"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ለዝርዝሮች የእርስዎን አስተዳዳሪ ያነጋግሩ"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"እንደ ሞደም መሰካት ወይም መገናኛ ነጥብ ገባሪ"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"ለማዋቀር መታ ያድርጉ።"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"እንደ ሞደም መሰካት ተሰናክሏል"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"ለዝርዝሮች የእርስዎን አስተዳዳሪ ያነጋግሩ"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"መገናኛ ነጥብ እና እንደ ሞደም የመሰካት ሁኔታ"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-ar/strings.xml b/Tethering/res/values-ar/strings.xml
index 9f84ce4..7d5bad3 100644
--- a/Tethering/res/values-ar/strings.xml
+++ b/Tethering/res/values-ar/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"النطاق أو نقطة الاتصال نشطة"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"انقر للإعداد."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"تم إيقاف التوصيل"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"اتصل بالمشرف للحصول على التفاصيل"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"النطاق نشط أو نقطة الاتصال نشطة"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"انقر للإعداد."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"التوصيل متوقف."</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"تواصَل مع المشرف للحصول على التفاصيل."</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"حالة نقطة الاتصال والتوصيل"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-as/strings.xml b/Tethering/res/values-as/strings.xml
index 8855822..0913504 100644
--- a/Tethering/res/values-as/strings.xml
+++ b/Tethering/res/values-as/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"টেডাৰিং বা হটস্প\'ট সক্ৰিয় অৱস্থাত আছে"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"ছেট আপ কৰিবলৈ টিপক।"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"টেডাৰিং অক্ষম কৰি থোৱা হৈছে"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"সবিশেষ জানিবলৈ আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"টে\'ডাৰিং অথবা হ\'টস্প\'ট সক্ৰিয় অৱস্থাত আছে"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"ছেট আপ কৰিবলৈ টিপক।"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"টে\'ডাৰিঙৰ সুবিধাটো অক্ষম কৰি থোৱা হৈছে"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"সবিশেষ জানিবলৈ আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"হ’টস্প\'ট আৰু টে\'ডাৰিঙৰ স্থিতি"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-az/strings.xml b/Tethering/res/values-az/strings.xml
index eba50eb..dce70da 100644
--- a/Tethering/res/values-az/strings.xml
+++ b/Tethering/res/values-az/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tezerinq və ya hotspot aktivdir"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Quraşdırmaq üçün tıklayın."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Birləşmə deaktivdir"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Məlumat üçün adminlə əlaqə saxlayın"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Birləşmə və ya hotspot aktivdir"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Ayarlamaq üçün toxunun."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Birləşmə deaktivdir"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Detallar üçün adminlə əlaqə saxlayın"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot &amp; birləşmə statusu"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-b+sr+Latn/strings.xml b/Tethering/res/values-b+sr+Latn/strings.xml
index 5b0e488..b0774ec 100644
--- a/Tethering/res/values-b+sr+Latn/strings.xml
+++ b/Tethering/res/values-b+sr+Latn/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Aktivno povezivanje sa internetom preko mobilnog uređaja ili hotspot"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite da biste podesili."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Privezivanje je onemogućeno"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Potražite detalje od administratora"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Privezivanje ili hotspot je aktivan"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da biste podesili."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Privezivanje je onemogućeno"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Potražite detalje od administratora"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status hotspota i privezivanja"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-be/strings.xml b/Tethering/res/values-be/strings.xml
index 5966c71..a8acebe 100644
--- a/Tethering/res/values-be/strings.xml
+++ b/Tethering/res/values-be/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"USB-мадэм або хот-спот Wi-Fi актыўныя"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Дакраніцеся, каб наладзіць."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Рэжым мадэма адключаны"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Звярніцеся да адміністратара па падрабязную інфармацыю"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Мадэм або хот-спот актыўныя"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Дакраніцеся, каб наладзіць."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Рэжым мадэма выключаны"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Звярніцеся да адміністратара па падрабязную інфармацыю"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Стан \"Хот-спот і мадэм\""</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-bg/strings.xml b/Tethering/res/values-bg/strings.xml
index ed58d73..94fb2d8 100644
--- a/Tethering/res/values-bg/strings.xml
+++ b/Tethering/res/values-bg/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Има активна споделена връзка или безжична точка за достъп"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Докоснете, за да настроите."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Функцията за тетъринг е деактивирана"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Свържете се с администратора си за подробности"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Има активна споделена връзка или точка за достъп"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Докоснете, за да настроите."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Функцията за тетъринг е деактивирана"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Свържете се с администратора си за подробности"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Състояние на функцията за точка за достъп и тетъринг"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-bn/strings.xml b/Tethering/res/values-bn/strings.xml
index 8d9880a..aea02b9 100644
--- a/Tethering/res/values-bn/strings.xml
+++ b/Tethering/res/values-bn/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"টিথারিং বা হটস্পট সক্রিয় আছে"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"সেট-আপ করার জন্য আলতো চাপুন৷"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"টিথারিং অক্ষম করা আছে"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"বিশদ বিবরণের জন্য প্রশাসকের সাথে যোগাযোগ করুন"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"টিথারিং বা হটস্পট চালু আছে"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"সেট-আপ করতে ট্যাপ করুন।"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"টিথারিং বন্ধ করা আছে"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"বিশদে জানতে অ্যাডমিনের সাথে যোগাযোগ করুন"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"হটস্পট ও টিথারিং স্ট্যাটাস"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-bs/strings.xml b/Tethering/res/values-bs/strings.xml
index 2361b9d..de23272 100644
--- a/Tethering/res/values-bs/strings.xml
+++ b/Tethering/res/values-bs/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Uređaj dijeli vezu ili djeluje kao pristupna tačka"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite za postavke"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Povezivanje putem mobitela je onemogućeno"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontaktirajte svog administratora za dodatne detalje"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Aktivno je povezivanje putem mobitela ili pristupna tačka"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da postavite."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Povezivanje putem mobitela je onemogućeno"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontaktirajte svog administratora za detalje"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status pristupne tačke i povezivanja putem mobitela"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-ca/strings.xml b/Tethering/res/values-ca/strings.xml
index 6752b51..88b795c 100644
--- a/Tethering/res/values-ca/strings.xml
+++ b/Tethering/res/values-ca/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Compartició de xarxa o punt d\'accés Wi-Fi activat"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Toca per configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"La compartició de xarxa està desactivada"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacta amb el teu administrador per obtenir més informació"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Compartició de xarxa o punt d\'accés Wi‑Fi actius"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Toca per configurar."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"La compartició de xarxa està desactivada"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacta amb el teu administrador per obtenir més informació"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estat del punt d\'accés Wi‑Fi i de la compartició de xarxa"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-cs/strings.xml b/Tethering/res/values-cs/strings.xml
index 5fdd53a..8c1b83b 100644
--- a/Tethering/res/values-cs/strings.xml
+++ b/Tethering/res/values-cs/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Sdílené připojení nebo hotspot je aktivní."</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Klepnutím zahájíte nastavení."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering je zakázán"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"O podrobnosti požádejte administrátora"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering nebo hotspot je aktivní"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Klepnutím zahájíte nastavení."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering je zakázán"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"O podrobnosti požádejte administrátora"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stav hotspotu a tetheringu"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-da/strings.xml b/Tethering/res/values-da/strings.xml
index 2775dfa..f413e70 100644
--- a/Tethering/res/values-da/strings.xml
+++ b/Tethering/res/values-da/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Netdeling eller hotspot er aktivt"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tryk for at konfigurere"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Netdeling er deaktiveret"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakt din administrator for at få oplysninger"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Netdeling eller hotspot er aktivt"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tryk for at konfigurere."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Netdeling er deaktiveret"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakt din administrator for at få oplysninger"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status for hotspot og netdeling"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-de/strings.xml b/Tethering/res/values-de/strings.xml
index 9046cd5..f057d78 100644
--- a/Tethering/res/values-de/strings.xml
+++ b/Tethering/res/values-de/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering oder Hotspot aktiv"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Zum Einrichten tippen."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering ist deaktiviert"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Bitte wende dich für weitere Informationen an den Administrator"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering oder Hotspot aktiv"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Zum Einrichten tippen."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering ist deaktiviert"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Bitte wende dich für weitere Informationen an den Administrator"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot- und Tethering-Status"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-el/strings.xml b/Tethering/res/values-el/strings.xml
index 3b9f537..b3c986b 100644
--- a/Tethering/res/values-el/strings.xml
+++ b/Tethering/res/values-el/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Πρόσδεση ή σύνδεση σημείου πρόσβασης ενεργή"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Πατήστε για ρύθμιση."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Η σύνδεση είναι απενεργοποιημένη"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Επικοινωνήστε με τον διαχειριστή σας για λεπτομέρειες"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Πρόσδεση ή σύνδεση σημείου πρόσβασης ενεργή"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Πατήστε για ρύθμιση."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Η σύνδεση είναι απενεργοποιημένη"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Επικοινωνήστε με τον διαχειριστή σας για λεπτομέρειες"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Κατάσταση σημείου πρόσβασης Wi-Fi και σύνδεσης"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-en-rAU/strings.xml b/Tethering/res/values-en-rAU/strings.xml
index 56b88a5..769e012 100644
--- a/Tethering/res/values-en-rAU/strings.xml
+++ b/Tethering/res/values-en-rAU/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-en-rCA/strings.xml b/Tethering/res/values-en-rCA/strings.xml
index 56b88a5..769e012 100644
--- a/Tethering/res/values-en-rCA/strings.xml
+++ b/Tethering/res/values-en-rCA/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-en-rGB/strings.xml b/Tethering/res/values-en-rGB/strings.xml
index 56b88a5..769e012 100644
--- a/Tethering/res/values-en-rGB/strings.xml
+++ b/Tethering/res/values-en-rGB/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-en-rIN/strings.xml b/Tethering/res/values-en-rIN/strings.xml
index 56b88a5..769e012 100644
--- a/Tethering/res/values-en-rIN/strings.xml
+++ b/Tethering/res/values-en-rIN/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-en-rXC/strings.xml b/Tethering/res/values-en-rXC/strings.xml
index 7f47fc8..f1674be 100644
--- a/Tethering/res/values-en-rXC/strings.xml
+++ b/Tethering/res/values-en-rXC/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎‏‎‎‏‎Tethering or hotspot active‎‏‎‎‏‎"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‏‎‎‏‎‏‎‎‎‏‎Tap to set up.‎‏‎‎‏‎"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‏‏‎Tethering is disabled‎‏‎‎‏‎"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‎Contact your admin for details‎‏‎‎‏‎"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎Tethering or hotspot active‎‏‎‎‏‎"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎Tap to set up.‎‏‎‎‏‎"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‏‏‎Tethering is disabled‎‏‎‎‏‎"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎Contact your admin for details‎‏‎‎‏‎"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎Hotspot &amp; tethering status‎‏‎‎‏‎"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-es-rUS/strings.xml b/Tethering/res/values-es-rUS/strings.xml
index e4618b8..63689f4 100644
--- a/Tethering/res/values-es-rUS/strings.xml
+++ b/Tethering/res/values-es-rUS/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Anclaje a red o zona activa conectados"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Presiona para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Se inhabilitó la conexión mediante dispositivo portátil"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Para obtener más información, comunícate con el administrador"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión a red o hotspot conectados"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Presiona para configurar esta opción."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Se inhabilitó la conexión mediante dispositivo portátil"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Para obtener más información, comunícate con el administrador"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado del hotspot y la conexión mediante dispositivo portátil"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-es/strings.xml b/Tethering/res/values-es/strings.xml
index 8dc1575..9a34ed5 100644
--- a/Tethering/res/values-es/strings.xml
+++ b/Tethering/res/values-es/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Compartir conexión/Zona Wi-Fi activada"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Toca para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"La conexión compartida está inhabilitada"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ponte en contacto con el administrador para obtener más información"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión compartida o punto de acceso activos"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Toca para configurar."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"La conexión compartida está inhabilitada"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Solicita más información a tu administrador"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado del punto de acceso y de la conexión compartida"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-et/strings.xml b/Tethering/res/values-et/strings.xml
index 872c8a7..0970341 100644
--- a/Tethering/res/values-et/strings.xml
+++ b/Tethering/res/values-et/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Jagamine või kuumkoht on aktiivne"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Puudutage seadistamiseks."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Jagamine on keelatud"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Lisateabe saamiseks võtke ühendust oma administraatoriga"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Jagamine või kuumkoht on aktiivne"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Puudutage seadistamiseks."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Jagamine on keelatud"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Lisateabe saamiseks võtke ühendust oma administraatoriga"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Kuumkoha ja jagamise olek"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-eu/strings.xml b/Tethering/res/values-eu/strings.xml
index 6c4605e..632019e 100644
--- a/Tethering/res/values-eu/strings.xml
+++ b/Tethering/res/values-eu/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Konexioa partekatzea edo sare publikoa aktibo"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Sakatu konfiguratzeko."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Desgaituta dago konexioa partekatzeko aukera"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Xehetasunak lortzeko, jarri administratzailearekin harremanetan"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Konexioa partekatzea edo wifi-gunea aktibo dago"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Sakatu konfiguratzeko."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Desgaituta dago konexioa partekatzeko aukera"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Xehetasunak lortzeko, jarri administratzailearekin harremanetan"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Wifi-gunearen eta konexioa partekatzeko eginbidearen egoera"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-fa/strings.xml b/Tethering/res/values-fa/strings.xml
index bc2ee23..2e21c85 100644
--- a/Tethering/res/values-fa/strings.xml
+++ b/Tethering/res/values-fa/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"اشتراک‌گذاری اینترنت یا نقطه اتصال فعال"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"برای راه‌اندازی ضربه بزنید."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"اشتراک‌گذاری اینترنت غیرفعال است"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"برای جزئیات، با سرپرستتان تماس بگیرید"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"اشتراک‌گذاری اینترنت یا نقطه اتصال فعال"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"برای راه‌اندازی ضربه بزنید."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"اشتراک‌گذاری اینترنت غیرفعال است"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"برای جزئیات، با سرپرستتان تماس بگیرید"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"وضعیت نقطه اتصال و اشتراک‌گذاری اینترنت"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-fi/strings.xml b/Tethering/res/values-fi/strings.xml
index ff0fca6..413db3f 100644
--- a/Tethering/res/values-fi/strings.xml
+++ b/Tethering/res/values-fi/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Internetin jakaminen tai yhteyspiste käytössä"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Määritä napauttamalla."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Yhteyden jakaminen poistettu käytöstä"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kysy lisätietoja järjestelmänvalvojalta."</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Yhteyden jakaminen tai hotspot käytössä"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Ota käyttöön napauttamalla."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Yhteyden jakaminen on poistettu käytöstä"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Pyydä lisätietoja järjestelmänvalvojalta"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspotin ja yhteyden jakamisen tila"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-fr-rCA/strings.xml b/Tethering/res/values-fr-rCA/strings.xml
index 1f5df0e..eb2e4ba 100644
--- a/Tethering/res/values-fr-rCA/strings.xml
+++ b/Tethering/res/values-fr-rCA/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Partage de connexion ou point d\'accès sans fil activé"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Touchez pour configurer."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Le partage de connexion est désactivé"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Communiquez avec votre administrateur pour obtenir plus de détails"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Partage de connexion ou point d\'accès sans fil activé"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Touchez pour configurer."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Le partage de connexion est désactivé"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Communiquez avec votre administrateur pour obtenir plus de détails"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Point d\'accès et partage de connexion"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-fr/strings.xml b/Tethering/res/values-fr/strings.xml
index daf7c9d..22259c5 100644
--- a/Tethering/res/values-fr/strings.xml
+++ b/Tethering/res/values-fr/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Partage de connexion ou point d\'accès sans fil activé"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Appuyez ici pour configurer."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Le partage de connexion est désactivé"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Pour en savoir plus, contactez votre administrateur"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Partage de connexion ou point d\'accès activé"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Appuyez pour effectuer la configuration."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Le partage de connexion est désactivé"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Pour en savoir plus, contactez votre administrateur"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"État du point d\'accès et du partage de connexion"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-gl/strings.xml b/Tethering/res/values-gl/strings.xml
index 0d16a1d..ded82fc 100644
--- a/Tethering/res/values-gl/strings.xml
+++ b/Tethering/res/values-gl/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Conexión compartida ou zona wifi activada"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tocar para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"A conexión compartida está desactivada"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacta co administrador para obter información"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión compartida ou zona wifi activada"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Toca para configurar."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"A conexión compartida está desactivada"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacta co administrador para obter información"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado da zona wifi e da conexión compartida"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-gu/strings.xml b/Tethering/res/values-gu/strings.xml
index 9d6b02f..7cbbc2d 100644
--- a/Tethering/res/values-gu/strings.xml
+++ b/Tethering/res/values-gu/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ટિથરિંગ અથવા હૉટસ્પૉટ સક્રિય"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"સેટ કરવા માટે ટૅપ કરો."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ટિથરિંગ અક્ષમ કરેલ છે"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"વિગતો માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"ઇન્ટરનેટ શેર કરવાની સુવિધા અથવા હૉટસ્પૉટ સક્રિય છે"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"સેટઅપ કરવા માટે ટૅપ કરો."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ઇન્ટરનેટ શેર કરવાની સુવિધા બંધ કરી છે"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"વિગતો માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"હૉટસ્પૉટ અને ઇન્ટરનેટ શેર કરવાની સુવિધાનું સ્ટેટસ"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-hi/strings.xml b/Tethering/res/values-hi/strings.xml
index 9c29d9a..08af81b 100644
--- a/Tethering/res/values-hi/strings.xml
+++ b/Tethering/res/values-hi/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग या हॉटस्‍पॉट सक्रिय"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करने के लिए टैप करें."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग अक्षम है"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"जानकारी के लिए अपने एडमिन से संपर्क करें"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"टेदरिंग या हॉटस्पॉट चालू है"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"सेट अप करने के लिए टैप करें."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"टेदरिंग बंद है"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"जानकारी के लिए अपने एडमिन से संपर्क करें"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"हॉटस्पॉट और टेदरिंग की स्थिति"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-hr/strings.xml b/Tethering/res/values-hr/strings.xml
index d0d25bb..827c135 100644
--- a/Tethering/res/values-hr/strings.xml
+++ b/Tethering/res/values-hr/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Ograničenje ili aktivan hotspot"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite da biste postavili."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Modemsko je povezivanje onemogućeno"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Obratite se administratoru da biste saznali pojedinosti"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Modemsko povezivanje ili žarišna točka aktivni"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da biste postavili."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Modemsko je povezivanje onemogućeno"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Obratite se administratoru da biste saznali pojedinosti"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status žarišne točke i modemskog povezivanja"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-hu/strings.xml b/Tethering/res/values-hu/strings.xml
index 3129659..eb68d6b 100644
--- a/Tethering/res/values-hu/strings.xml
+++ b/Tethering/res/values-hu/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Megosztás vagy aktív hotspot"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Koppintson a beállításhoz."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Az internetmegosztás le van tiltva"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"A részletekért forduljon rendszergazdájához"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Megosztás vagy aktív hotspot"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Koppintson a beállításhoz."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Az internetmegosztás le van tiltva"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"A részletekért forduljon rendszergazdájához"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot és internetmegosztás állapota"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-hy/strings.xml b/Tethering/res/values-hy/strings.xml
index 8ba6435..912941e 100644
--- a/Tethering/res/values-hy/strings.xml
+++ b/Tethering/res/values-hy/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Մոդեմի ռեժիմը միացված է"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Հպեք՝ կարգավորելու համար:"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Մոդեմի ռեժիմն անջատված է"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Մանրամասների համար դիմեք ձեր ադմինիստրատորին"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Մոդեմի ռեժիմը միացված է"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Հպեք՝ կարգավորելու համար։"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Մոդեմի ռեժիմն անջատված է"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Մանրամասների համար դիմեք ձեր ադմինիստրատորին"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Թեժ կետի և մոդեմի ռեժիմի կարգավիճակը"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-in/strings.xml b/Tethering/res/values-in/strings.xml
index 1e093ab..a4e175a 100644
--- a/Tethering/res/values-in/strings.xml
+++ b/Tethering/res/values-in/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering (Penambatan) atau hotspot aktif"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Ketuk untuk menyiapkan."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering dinonaktifkan"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi admin untuk mengetahui detailnya"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering atau hotspot aktif"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Ketuk untuk menyiapkan."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering dinonaktifkan"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hubungi admin untuk mengetahui detailnya"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status hotspot &amp; tethering"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-is/strings.xml b/Tethering/res/values-is/strings.xml
index f5769d5..e9f6670 100644
--- a/Tethering/res/values-is/strings.xml
+++ b/Tethering/res/values-is/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Kveikt á tjóðrun eða aðgangsstað"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Ýttu til að setja upp."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Slökkt er á tjóðrun"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hafðu samband við kerfisstjórann til að fá upplýsingar"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Kveikt á tjóðrun eða aðgangsstað"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Ýttu til að setja upp."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Slökkt er á tjóðrun"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hafðu samband við kerfisstjórann til að fá upplýsingar"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Staða heits reits og tjóðrunar"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-it/strings.xml b/Tethering/res/values-it/strings.xml
index e0b3724..ffb9196 100644
--- a/Tethering/res/values-it/strings.xml
+++ b/Tethering/res/values-it/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering oppure hotspot attivo"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tocca per impostare."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering disattivato"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contatta il tuo amministratore per avere informazioni dettagliate"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Hotspot o tethering attivo"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tocca per impostare."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering disattivato"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contatta il tuo amministratore per avere informazioni dettagliate"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stato hotspot e tethering"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-iw/strings.xml b/Tethering/res/values-iw/strings.xml
index c002c44..7adcb47 100644
--- a/Tethering/res/values-iw/strings.xml
+++ b/Tethering/res/values-iw/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"שיתוף אינטרנט פעיל"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"הקש כדי להגדיר."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"שיתוף האינטרנט בין ניידים מושבת"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"לפרטים, יש לפנות למנהל המערכת"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"נקודה לשיתוף אינטרנט או שיתוף אינטרנט בין מכשירים: בסטטוס פעיל"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"יש להקיש כדי להגדיר."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"שיתוף האינטרנט בין מכשירים מושבת"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"לפרטים, יש לפנות למנהל המערכת"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"סטטוס של נקודה לשיתוף אינטרנט ושיתוף אינטרנט בין מכשירים"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-ja/strings.xml b/Tethering/res/values-ja/strings.xml
index 314bde0..f68a730 100644
--- a/Tethering/res/values-ja/strings.xml
+++ b/Tethering/res/values-ja/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"テザリングまたはアクセスポイントが有効です"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"タップしてセットアップします。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"テザリングは無効に設定されています"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"詳しくは、管理者にお問い合わせください"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"テザリングまたはアクセス ポイントが有効です"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"タップしてセットアップします。"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"テザリングは無効に設定されています"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"詳しくは、管理者にお問い合わせください"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"アクセス ポイントとテザリングのステータス"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-ka/strings.xml b/Tethering/res/values-ka/strings.xml
index 7bbd81d..7c22e82 100644
--- a/Tethering/res/values-ka/strings.xml
+++ b/Tethering/res/values-ka/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ტეტერინგი ან უსადენო ქსელი აქტიურია"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"შეეხეთ დასაყენებლად."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ტეტერინგი გათიშულია"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"დამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"ტეტერინგი ან უსადენო ქსელი აქტიურია"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"შეეხეთ დასაყენებლად."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ტეტერინგი გათიშულია"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"დამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"უსადენო ქსელის და ტეტერინგის სტატუსი"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-kk/strings.xml b/Tethering/res/values-kk/strings.xml
index 7fd87a1..0857d06 100644
--- a/Tethering/res/values-kk/strings.xml
+++ b/Tethering/res/values-kk/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Тетеринг немесе хотспот қосулы"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Реттеу үшін түртіңіз."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Тетеринг өшірілді"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Мәліметтерді әкімшіден алыңыз"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Тетеринг немесе хотспот қосулы"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Реттеу үшін түртіңіз."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Тетеринг өшірілді."</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Мәліметтерді әкімшіден алыңыз."</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Хотспот және тетеринг күйі"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-km/strings.xml b/Tethering/res/values-km/strings.xml
index 2f85224..536e3d1 100644
--- a/Tethering/res/values-km/strings.xml
+++ b/Tethering/res/values-km/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ភ្ជាប់ ឬ​ហតស្ពត​សកម្ម"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"ប៉ះដើម្បីកំណត់"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ការភ្ជាប់​ត្រូវបានបិទ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ទាក់ទងអ្នកគ្រប់គ្រង​របស់អ្នកសម្រាប់​ព័ត៌មានលម្អិត"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"ការភ្ជាប់ ឬហតស្ប៉ត​កំពុងដំណើរការ"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"ចុច​ដើម្បី​រៀបចំ។"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ការភ្ជាប់​ត្រូវបានបិទ"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"ទាក់ទងអ្នកគ្រប់គ្រង​របស់អ្នក ដើម្បីទទួលបានព័ត៌មានលម្អិត"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ស្ថានភាពនៃការភ្ជាប់ និងហតស្ប៉ត"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-kn/strings.xml b/Tethering/res/values-kn/strings.xml
index f11a83e..32f5492 100644
--- a/Tethering/res/values-kn/strings.xml
+++ b/Tethering/res/values-kn/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ಟೆಥರಿಂಗ್ ಅಥವಾ ಹಾಟ್‌ಸ್ಪಾಟ್ ಸಕ್ರಿಯವಾಗಿದೆ"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ಟೆಥರಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"ಟೆಥರಿಂಗ್ ಅಥವಾ ಹಾಟ್‌ಸ್ಪಾಟ್ ಸಕ್ರಿಯವಾಗಿದೆ"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"ಸೆಟಪ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ಟೆಥರಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ಹಾಟ್‌ಸ್ಪಾಟ್ ಮತ್ತು ಟೆಥರಿಂಗ್‌ ಸ್ಥಿತಿ"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-ko/strings.xml b/Tethering/res/values-ko/strings.xml
index 57f24f5..156b247 100644
--- a/Tethering/res/values-ko/strings.xml
+++ b/Tethering/res/values-ko/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"테더링 또는 핫스팟 사용"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"설정하려면 탭하세요."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"테더링이 사용 중지됨"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"자세한 정보는 관리자에게 문의하세요."</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"테더링 또는 핫스팟 사용"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"설정하려면 탭하세요."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"테더링이 사용 중지됨"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"자세한 정보는 관리자에게 문의하세요."</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"핫스팟 및 테더링 상태"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-ky/strings.xml b/Tethering/res/values-ky/strings.xml
index 7985485..18ee5fd 100644
--- a/Tethering/res/values-ky/strings.xml
+++ b/Tethering/res/values-ky/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Жалгаштыруу же хотспот жандырылган"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Жөндөө үчүн таптап коюңуз."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Жалгаштыруу функциясы өчүрүлгөн"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Кеңири маалымат үчүн администраторуңузга кайрылыңыз"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Модем режими күйүп турат"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Жөндөө үчүн таптап коюңуз."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Телефонду модем катары колдонууга болбойт"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Кеңири маалымат үчүн администраторуңузга кайрылыңыз"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Байланыш түйүнүнүн жана модем режиминин статусу"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-lo/strings.xml b/Tethering/res/values-lo/strings.xml
index 78f1585..b127670 100644
--- a/Tethering/res/values-lo/strings.xml
+++ b/Tethering/res/values-lo/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ເປີດ​ການ​ປ່ອຍ​ສັນຍານ ຫຼື​ຮັອດສະປອດ​ແລ້ວ"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"ແຕະເພື່ອຕັ້ງຄ່າ."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ການປ່ອຍສັນຍານຖືກປິດໄວ້"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບລາຍລະອຽດ"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"ເປີດການປ່ອຍສັນຍານ ຫຼື ຮັອດສະປອດແລ້ວ"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"ແຕະເພື່ອຕັ້ງຄ່າ."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ການປ່ອຍສັນຍານຖືກປິດໄວ້"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບລາຍລະອຽດ"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ສະຖານະຮັອດສະປອດ ແລະ ການປ່ອຍສັນຍານ"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-lt/strings.xml b/Tethering/res/values-lt/strings.xml
index ebff8ac..8427baf 100644
--- a/Tethering/res/values-lt/strings.xml
+++ b/Tethering/res/values-lt/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Susietas ar aktyvus"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Palieskite, kad nustatytumėte."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Įrenginio kaip modemo naudojimas išjungtas"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Jei reikia išsamios informacijos, susisiekite su administratoriumi"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Įrenginys naudojamas kaip modemas arba įjungtas viešosios interneto prieigos taškas"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Palieskite, kad nustatytumėte."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Įrenginio kaip modemo naudojimas išjungtas"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Jei reikia išsamios informacijos, susisiekite su administratoriumi"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Viešosios interneto prieigos taško ir įrenginio kaip modemo naudojimo būsena"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-lv/strings.xml b/Tethering/res/values-lv/strings.xml
index 54d0048..aa2d699 100644
--- a/Tethering/res/values-lv/strings.xml
+++ b/Tethering/res/values-lv/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Piesaiste vai tīklājs ir aktīvs."</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Pieskarieties, lai iestatītu."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Piesaiste ir atspējota"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Lai iegūtu detalizētu informāciju, sazinieties ar savu administratoru."</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Piesaiste vai tīklājs ir aktīvs."</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Pieskarieties, lai to iestatītu."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Piesaiste ir atspējota"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Lai iegūtu detalizētu informāciju, sazinieties ar savu administratoru."</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Tīklāja un piesaistes statuss"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-mcc310-mnc004-af/strings.xml b/Tethering/res/values-mcc310-mnc004-af/strings.xml
new file mode 100644
index 0000000..19d659c
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-af/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Verbinding het nie internet nie"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Toestelle kan nie koppel nie"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Skakel verbinding af"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Warmkol of verbinding is aan"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Bykomende heffings kan geld terwyl jy swerf"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-am/strings.xml b/Tethering/res/values-mcc310-mnc004-am/strings.xml
new file mode 100644
index 0000000..8995430
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-am/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"ማስተሳሰር ምንም በይነመረብ የለውም"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"መሣሪያዎችን ማገናኘት አይቻልም"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ማስተሳሰርን አጥፋ"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"መገናኛ ነጥብ ወይም ማስተሳሰር በርቷል"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"በሚያንዣብብበት ጊዜ ተጨማሪ ክፍያዎች ተፈጻሚ ሊሆኑ ይችላሉ"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-ar/strings.xml b/Tethering/res/values-mcc310-mnc004-ar/strings.xml
new file mode 100644
index 0000000..54f3b53
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-ar/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"ما مِن اتصال بالإنترنت خلال التوصيل"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"تعذّر اتصال الأجهزة"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"إيقاف التوصيل"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"نقطة الاتصال أو التوصيل مفعّلان"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"قد يتم تطبيق رسوم إضافية أثناء التجوال."</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-as/strings.xml b/Tethering/res/values-mcc310-mnc004-as/strings.xml
new file mode 100644
index 0000000..e215141
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-as/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"টে\'ডাৰিঙৰ ইণ্টাৰনেট নাই"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"ডিভাইচসমূহ সংযোগ কৰিব নোৱাৰি"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"টে\'ডাৰিং অফ কৰক"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"হটস্পট অথবা টে\'ডাৰিং অন আছে"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ৰ\'মিঙত থাকিলে অতিৰিক্ত মাচুল প্ৰযোজ্য হ’ব পাৰে"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-az/strings.xml b/Tethering/res/values-mcc310-mnc004-az/strings.xml
new file mode 100644
index 0000000..1fd8e4c
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-az/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Modemin internetə girişi yoxdur"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Cihazları qoşmaq mümkün deyil"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Modemi deaktiv edin"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot və ya modem aktivdir"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Rouminq zamanı əlavə ödənişlər tətbiq edilə bilər"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-b+sr+Latn/strings.xml b/Tethering/res/values-mcc310-mnc004-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..1abe4f3
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-b+sr+Latn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Privezivanje nema pristup internetu"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Povezivanje uređaja nije uspelo"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Isključi privezivanje"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Uključen je hotspot ili privezivanje"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Možda važe dodatni troškovi u romingu"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-be/strings.xml b/Tethering/res/values-mcc310-mnc004-be/strings.xml
new file mode 100644
index 0000000..38dbd1e
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-be/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Рэжым мадэма выкарыстоўваецца без доступу да інтэрнэту"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Не ўдалося падключыць прылады"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Выключыць рэжым мадэма"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Хот-спот або рэжым мадэма ўключаны"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Пры выкарыстанні роўмінгу можа спаганяцца дадатковая плата"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-bg/strings.xml b/Tethering/res/values-mcc310-mnc004-bg/strings.xml
new file mode 100644
index 0000000..04b44db
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-bg/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Тетърингът няма връзка с интернет"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Устройствата не могат да установят връзка"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Изключване на тетъринга"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Точката за достъп или тетърингът са включени"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Възможно е да ви бъдат начислени допълнителни такси при роуминг"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-bn/strings.xml b/Tethering/res/values-mcc310-mnc004-bn/strings.xml
new file mode 100644
index 0000000..579d1be
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-bn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"টিথারিং করার জন্য কোনও ইন্টারনেট কানেকশন নেই"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"ডিভাইস কানেক্ট করতে পারছে না"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"টিথারিং বন্ধ করুন"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"হটস্পট বা টিথারিং চালু আছে"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"রোমিংয়ের সময় অতিরিক্ত চার্জ করা হতে পারে"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-bs/strings.xml b/Tethering/res/values-mcc310-mnc004-bs/strings.xml
new file mode 100644
index 0000000..9ce3efe
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-bs/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Povezivanje putem mobitela nema internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Uređaji se ne mogu povezati"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Isključi povezivanje putem mobitela"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Pristupna tačka ili povezivanje putem mobitela je uključeno"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Mogu nastati dodatni troškovi u romingu"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-ca/strings.xml b/Tethering/res/values-mcc310-mnc004-ca/strings.xml
new file mode 100644
index 0000000..46d4c35
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-ca/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"La compartició de xarxa no té accés a Internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"No es poden connectar els dispositius"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactiva la compartició de xarxa"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"S\'ha activat el punt d\'accés Wi‑Fi o la compartició de xarxa"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"És possible que s\'apliquin costos addicionals en itinerància"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-cs/strings.xml b/Tethering/res/values-mcc310-mnc004-cs/strings.xml
new file mode 100644
index 0000000..cc13860
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-cs/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering nemá připojení k internetu"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Zařízení se nemůžou připojit"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Vypnout tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Je zapnutý hotspot nebo tethering"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Při roamingu mohou být účtovány dodatečné poplatky"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-da/strings.xml b/Tethering/res/values-mcc310-mnc004-da/strings.xml
new file mode 100644
index 0000000..92c3ae1
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-da/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Netdeling har ingen internetforbindelse"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Enheder kan ikke oprette forbindelse"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Deaktiver netdeling"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot eller netdeling er aktiveret"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Der opkræves muligvis yderligere gebyrer ved roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-de/strings.xml b/Tethering/res/values-mcc310-mnc004-de/strings.xml
new file mode 100644
index 0000000..967eb4d
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-de/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering hat keinen Internetzugriff"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Geräte können sich nicht verbinden"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tethering deaktivieren"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot oder Tethering ist aktiviert"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Für das Roaming können zusätzliche Gebühren anfallen"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-el/strings.xml b/Tethering/res/values-mcc310-mnc004-el/strings.xml
new file mode 100644
index 0000000..5fb4974
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-el/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Η σύνδεση δεν έχει πρόσβαση στο διαδίκτυο"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Δεν είναι δυνατή η σύνδεση των συσκευών"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Απενεργοποιήστε τη σύνδεση"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ενεργό σημείο πρόσβασης Wi-Fi ή ενεργή σύνδεση"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ενδέχεται να ισχύουν επιπλέον χρεώσεις κατά την περιαγωγή."</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-en-rAU/strings.xml b/Tethering/res/values-mcc310-mnc004-en-rAU/strings.xml
new file mode 100644
index 0000000..45647f9
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-en-rAU/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-en-rCA/strings.xml b/Tethering/res/values-mcc310-mnc004-en-rCA/strings.xml
new file mode 100644
index 0000000..45647f9
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-en-rCA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-en-rGB/strings.xml b/Tethering/res/values-mcc310-mnc004-en-rGB/strings.xml
new file mode 100644
index 0000000..45647f9
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-en-rGB/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-en-rIN/strings.xml b/Tethering/res/values-mcc310-mnc004-en-rIN/strings.xml
new file mode 100644
index 0000000..45647f9
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-en-rIN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-en-rXC/strings.xml b/Tethering/res/values-mcc310-mnc004-en-rXC/strings.xml
new file mode 100644
index 0000000..7877074
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-en-rXC/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‎‎Tethering has no internet‎‏‎‎‏‎"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎Devices can’t connect‎‏‎‎‏‎"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‎‎‎Turn off tethering‎‏‎‎‏‎"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‎‏‏‎‎‎‎‎‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‏‏‏‎Hotspot or tethering is on‎‏‎‎‏‎"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎Additional charges may apply while roaming‎‏‎‎‏‎"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-es-rUS/strings.xml b/Tethering/res/values-mcc310-mnc004-es-rUS/strings.xml
new file mode 100644
index 0000000..08edd81
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-es-rUS/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"La conexión mediante dispositivo móvil no tiene Internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"No se pueden conectar los dispositivos"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactivar conexión mediante dispositivo móvil"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Se activó el hotspot o la conexión mediante dispositivo móvil"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Es posible que se apliquen cargos adicionales por roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-es/strings.xml b/Tethering/res/values-mcc310-mnc004-es/strings.xml
new file mode 100644
index 0000000..79f51d0
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-es/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"La conexión no se puede compartir, porque no hay acceso a Internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Los dispositivos no se pueden conectar"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactivar conexión compartida"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Punto de acceso o conexión compartida activados"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Puede que se apliquen cargos adicionales en itinerancia"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-et/strings.xml b/Tethering/res/values-mcc310-mnc004-et/strings.xml
new file mode 100644
index 0000000..2da5f8a
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-et/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Jagamisel puudub internetiühendus"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Seadmed ei saa ühendust luua"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Lülita jagamine välja"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Kuumkoht või jagamine on sisse lülitatud"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Rändluse kasutamisega võivad kaasneda lisatasud"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-eu/strings.xml b/Tethering/res/values-mcc310-mnc004-eu/strings.xml
new file mode 100644
index 0000000..2073f28
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-eu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Konexioa partekatzeko aukerak ez du Interneteko konexiorik"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Ezin dira konektatu gailuak"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desaktibatu konexioa partekatzeko aukera"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Wifi-gunea edo konexioa partekatzeko aukera aktibatuta dago"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Baliteke kostu gehigarriak ordaindu behar izatea ibiltaritzan"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-fa/strings.xml b/Tethering/res/values-mcc310-mnc004-fa/strings.xml
new file mode 100644
index 0000000..e21b2a0
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-fa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"«اشتراک‌گذاری اینترنت» به اینترنت دسترسی ندارد"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"دستگاه‌ها متصل نمی‌شوند"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"خاموش کردن «اشتراک‌گذاری اینترنت»"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"«نقطه اتصال» یا «اشتراک‌گذاری اینترنت» روشن است"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ممکن است درحین فراگردی تغییرات دیگر اعمال شود"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-fi/strings.xml b/Tethering/res/values-mcc310-mnc004-fi/strings.xml
new file mode 100644
index 0000000..88b0b13
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-fi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Ei jaettavaa internetyhteyttä"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Laitteet eivät voi muodostaa yhteyttä"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Laita yhteyden jakaminen pois päältä"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot tai yhteyden jakaminen on päällä"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Roaming voi aiheuttaa lisämaksuja"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-fr-rCA/strings.xml b/Tethering/res/values-mcc310-mnc004-fr-rCA/strings.xml
new file mode 100644
index 0000000..3b781bc
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-fr-rCA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Le partage de connexion n\'est pas connecté à Internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Impossible de connecter les appareils"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Désactiver le partage de connexion"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Le point d\'accès ou le partage de connexion est activé"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-fr/strings.xml b/Tethering/res/values-mcc310-mnc004-fr/strings.xml
new file mode 100644
index 0000000..51d7203
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-fr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Aucune connexion à Internet n\'est disponible pour le partage de connexion"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Impossible de connecter les appareils"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Désactiver le partage de connexion"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Le point d\'accès ou le partage de connexion est activé"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-gl/strings.xml b/Tethering/res/values-mcc310-mnc004-gl/strings.xml
new file mode 100644
index 0000000..008ccb4
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-gl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"A conexión compartida non ten Internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Non se puideron conectar os dispositivos"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactivar conexión compartida"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Está activada a zona wifi ou a conexión compartida"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Pódense aplicar cargos adicionais en itinerancia"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-gu/strings.xml b/Tethering/res/values-mcc310-mnc004-gu/strings.xml
new file mode 100644
index 0000000..f2e3b4d
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-gu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"ઇન્ટરનેટ શેર કરવાની સુવિધામાં ઇન્ટરનેટ નથી"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"ડિવાઇસ કનેક્ટ કરી શકાતા નથી"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ઇન્ટરનેટ શેર કરવાની સુવિધા બંધ કરો"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"હૉટસ્પૉટ અથવા ઇન્ટરનેટ શેર કરવાની સુવિધા ચાલુ છે"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"રોમિંગમાં વધારાના શુલ્ક લાગી શકે છે"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-hi/strings.xml b/Tethering/res/values-mcc310-mnc004-hi/strings.xml
new file mode 100644
index 0000000..b11839d
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-hi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"टेदरिंग से इंटरनेट नहीं चल रहा"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"डिवाइस कनेक्ट नहीं हो पा रहे"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"टेदरिंग बंद करें"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"हॉटस्पॉट या टेदरिंग चालू है"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिंग के दौरान अतिरिक्त शुल्क लग सकता है"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-hr/strings.xml b/Tethering/res/values-mcc310-mnc004-hr/strings.xml
new file mode 100644
index 0000000..0a5aca2
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-hr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Modemsko povezivanje nema internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Uređaji se ne mogu povezati"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Isključivanje modemskog povezivanja"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Uključena je žarišna točka ili modemsko povezivanje"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"U roamingu su mogući dodatni troškovi"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-hu/strings.xml b/Tethering/res/values-mcc310-mnc004-hu/strings.xml
new file mode 100644
index 0000000..21c689a
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-hu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Nincs internetkapcsolat az internet megosztásához"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Az eszközök nem tudnak csatlakozni"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Internetmegosztás kikapcsolása"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"A hotspot vagy az internetmegosztás be van kapcsolva"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Roaming során további díjak léphetnek fel"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-hy/strings.xml b/Tethering/res/values-mcc310-mnc004-hy/strings.xml
new file mode 100644
index 0000000..689d928
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-hy/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Մոդեմի ռեժիմի կապը բացակայում է"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Չհաջողվեց միացնել սարքը"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Անջատել մոդեմի ռեժիմը"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Թեժ կետը կամ մոդեմի ռեժիմը միացված է"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ռոումինգում կարող են լրացուցիչ վճարներ գանձվել"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-in/strings.xml b/Tethering/res/values-mcc310-mnc004-in/strings.xml
new file mode 100644
index 0000000..a5f4d19
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-in/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tidak ada koneksi internet di tethering"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Perangkat tidak dapat terhubung"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Nonaktifkan tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot atau tethering aktif"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Biaya tambahan mungkin berlaku saat roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-is/strings.xml b/Tethering/res/values-mcc310-mnc004-is/strings.xml
new file mode 100644
index 0000000..fc7e8aa
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-is/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tjóðrun er ekki með internettengingu"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Tæki geta ekki tengst"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Slökkva á tjóðrun"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Kveikt er á heitum reit eða tjóðrun"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Viðbótargjöld kunna að eiga við í reiki"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-it/strings.xml b/Tethering/res/values-mcc310-mnc004-it/strings.xml
new file mode 100644
index 0000000..6456dd1
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-it/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Nessuna connessione a Internet per il tethering"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Impossibile connettere i dispositivi"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Disattiva il tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot o tethering attivi"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Potrebbero essere applicati costi aggiuntivi durante il roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-iw/strings.xml b/Tethering/res/values-mcc310-mnc004-iw/strings.xml
new file mode 100644
index 0000000..46b24bd
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-iw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"אי אפשר להפעיל את תכונת שיתוף האינטרנט בין מכשירים כי אין חיבור לאינטרנט"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"למכשירים אין אפשרות להתחבר"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"השבתה של שיתוף האינטרנט בין מכשירים"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"תכונת הנקודה לשיתוף אינטרנט או תכונת שיתוף האינטרנט בין מכשירים פועלת"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ייתכנו חיובים נוספים בעת נדידה"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-ja/strings.xml b/Tethering/res/values-mcc310-mnc004-ja/strings.xml
new file mode 100644
index 0000000..e6eb277
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-ja/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"テザリングがインターネットに接続されていません"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"デバイスを接続できません"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"テザリングを OFF にする"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"アクセス ポイントまたはテザリングが ON です"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ローミング時に追加料金が発生することがあります"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-ka/strings.xml b/Tethering/res/values-mcc310-mnc004-ka/strings.xml
new file mode 100644
index 0000000..aeddd71
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-ka/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"ტეტერინგს არ აქვს ინტერნეტზე წვდომა"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"მოწყობილობები ვერ ახერხებენ დაკავშირებას"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ტეტერინგის გამორთვა"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ჩართულია უსადენო ქსელი ან ტეტერინგი"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"როუმინგის გამოყენებისას შეიძლება ჩამოგეჭრათ დამატებითი საფასური"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-kk/strings.xml b/Tethering/res/values-mcc310-mnc004-kk/strings.xml
new file mode 100644
index 0000000..255f0a2
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-kk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Тетеринг режимі интернет байланысынсыз пайдаланылуда"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Құрылғыларды байланыстыру мүмкін емес"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Тетерингіні өшіру"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Хотспот немесе тетеринг қосулы"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Роуминг кезінде қосымша ақы алынуы мүмкін."</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-km/strings.xml b/Tethering/res/values-mcc310-mnc004-km/strings.xml
new file mode 100644
index 0000000..2bceb1c
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-km/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"ការភ្ជាប់​មិនមានអ៊ីនធឺណិត​ទេ"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"មិនអាច​ភ្ជាប់ឧបករណ៍​បានទេ"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"បិទការភ្ជាប់"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ហតស្ប៉ត ឬការភ្ជាប់​ត្រូវបានបើក"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"អាចមាន​ការគិតថ្លៃ​បន្ថែម នៅពេល​រ៉ូមីង"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-kn/strings.xml b/Tethering/res/values-mcc310-mnc004-kn/strings.xml
new file mode 100644
index 0000000..ed76930
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-kn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"ಟೆಥರಿಂಗ್‌ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಕನೆಕ್ಷನ್ ಹೊಂದಿಲ್ಲ"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"ಸಾಧನಗಳನ್ನು ಕನೆಕ್ಟ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ಟೆಥರಿಂಗ್‌ ಆಫ್ ಮಾಡಿ"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ಹಾಟ್‌ಸ್ಪಾಟ್ ಅಥವಾ ಟೆಥರಿಂಗ್‌ ಆನ್ ಆಗಿದೆ"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ರೋಮಿಂಗ್‌ನಲ್ಲಿರುವಾಗ ಹೆಚ್ಚುವರಿ ಶುಲ್ಕಗಳು ಅನ್ವಯವಾಗಬಹುದು"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-ko/strings.xml b/Tethering/res/values-mcc310-mnc004-ko/strings.xml
new file mode 100644
index 0000000..6e50494
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-ko/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"테더링으로 인터넷을 사용할 수 없음"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"기기에서 연결할 수 없음"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"테더링 사용 중지"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"핫스팟 또는 테더링 켜짐"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"로밍 중에는 추가 요금이 발생할 수 있습니다."</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-ky/strings.xml b/Tethering/res/values-mcc310-mnc004-ky/strings.xml
new file mode 100644
index 0000000..d68128b
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-ky/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Модем режими Интернети жок колдонулууда"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Түзмөктөр туташпай жатат"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Модем режимин өчүрүү"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Байланыш түйүнү же модем режими күйүк"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Роумингде кошумча акы алынышы мүмкүн"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-lo/strings.xml b/Tethering/res/values-mcc310-mnc004-lo/strings.xml
new file mode 100644
index 0000000..03e134a
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-lo/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"ການປ່ອຍສັນຍານບໍ່ມີອິນເຕີເນັດ"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"ອຸປະກອນບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ປິດການປ່ອຍສັນຍານ"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ເປີດໃຊ້ຮັອດສະປອດ ຫຼື ການປ່ອຍສັນຍານຢູ່"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ອາດມີຄ່າໃຊ້ຈ່າຍເພີ່ມເຕີມໃນລະຫວ່າງການໂຣມມິງ"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-lt/strings.xml b/Tethering/res/values-mcc310-mnc004-lt/strings.xml
new file mode 100644
index 0000000..652cedc
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-lt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Nėra įrenginio kaip modemo naudojimo interneto ryšio"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Nepavyko susieti įrenginių"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Išjungti įrenginio kaip modemo naudojimą"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Įjungtas viešosios interneto prieigos taškas arba įrenginio kaip modemo naudojimas"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Veikiant tarptinkliniam ryšiui gali būti taikomi papildomi mokesčiai"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-lv/strings.xml b/Tethering/res/values-mcc310-mnc004-lv/strings.xml
new file mode 100644
index 0000000..2219722
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-lv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Piesaistei nav interneta savienojuma"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Nevar savienot ierīces"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Izslēgt piesaisti"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ir ieslēgts tīklājs vai piesaiste"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Viesabonēšanas laikā var tikt piemērota papildu samaksa"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-mk/strings.xml b/Tethering/res/values-mcc310-mnc004-mk/strings.xml
new file mode 100644
index 0000000..227f9e3
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-mk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Нема интернет преку мобилен"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Уредите не може да се поврзат"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Исклучи интернет преку мобилен"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Точката на пристап или интернетот преку мобилен е вклучен"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"При роаминг може да се наплатат дополнителни трошоци"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-ml/strings.xml b/Tethering/res/values-mcc310-mnc004-ml/strings.xml
new file mode 100644
index 0000000..ec43885
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-ml/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"ടെതറിംഗിന് ഇന്റർനെറ്റ് ഇല്ല"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"ഉപകരണങ്ങൾ കണക്റ്റ് ചെയ്യാനാവില്ല"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ടെതറിംഗ് ഓഫാക്കുക"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ഹോട്ട്‌സ്‌പോട്ട് അല്ലെങ്കിൽ ടെതറിംഗ് ഓണാണ്"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"റോമിംഗ് ചെയ്യുമ്പോൾ അധിക നിരക്കുകൾ ബാധകമായേക്കാം"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-mn/strings.xml b/Tethering/res/values-mcc310-mnc004-mn/strings.xml
new file mode 100644
index 0000000..e263573
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-mn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Модемд интернэт алга байна"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Төхөөрөмжүүд холбогдох боломжгүй байна"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Модем болгохыг унтраах"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Сүлжээний цэг эсвэл модем болгох асаалттай байна"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Роумингийн үеэр нэмэлт төлбөр нэхэмжилж болзошгүй"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-mr/strings.xml b/Tethering/res/values-mcc310-mnc004-mr/strings.xml
new file mode 100644
index 0000000..adf845d
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-mr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"टेदरिंगला इंटरनेट नाही"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"डिव्हाइस कनेक्ट होऊ शकत नाहीत"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"टेदरिंग बंद करा"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"हॉटस्पॉट किंवा टेदरिंग सुरू आहे"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिंगदरम्यान अतिरिक्त शुल्क लागू होऊ शकतात"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-ms/strings.xml b/Tethering/res/values-mcc310-mnc004-ms/strings.xml
new file mode 100644
index 0000000..f65c451
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-ms/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Penambatan tiada Internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Peranti tidak dapat disambungkan"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Matikan penambatan"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Tempat liputan atau penambatan dihidupkan"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Caj tambahan mungkin digunakan semasa perayauan"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-my/strings.xml b/Tethering/res/values-mcc310-mnc004-my/strings.xml
new file mode 100644
index 0000000..4118e77
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-my/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်းတွင် အင်တာနက် မရှိပါ"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"စက်များ ချိတ်ဆက်၍ မရပါ"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ပိတ်ရန်"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ဟော့စပေါ့ (သို့) မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ဖွင့်ထားသည်"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ပြင်ပကွန်ရက်နှင့် ချိတ်ဆက်သည့်အခါ နောက်ထပ်ကျသင့်မှုများ ရှိနိုင်သည်"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-nb/strings.xml b/Tethering/res/values-mcc310-mnc004-nb/strings.xml
new file mode 100644
index 0000000..3685358
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-nb/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Internettdeling har ikke internettilgang"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Enhetene kan ikke koble til"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Slå av internettdeling"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Wi-Fi-sone eller internettdeling er på"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ytterligere kostnader kan påløpe under roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-ne/strings.xml b/Tethering/res/values-mcc310-mnc004-ne/strings.xml
new file mode 100644
index 0000000..d074f15
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-ne/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"टेदरिङमार्फत इन्टरनेट कनेक्सन प्राप्त हुन सकेन"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"यन्त्रहरू कनेक्ट गर्न सकिएन"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"टेदरिङ निष्क्रिय पार्नुहोस्"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"हटस्पट वा टेदरिङ सक्रिय छ"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-nl/strings.xml b/Tethering/res/values-mcc310-mnc004-nl/strings.xml
new file mode 100644
index 0000000..1d88894
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-nl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering heeft geen internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Apparaten kunnen niet worden verbonden"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tethering uitschakelen"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot of tethering is ingeschakeld"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Er kunnen extra kosten voor roaming in rekening worden gebracht."</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-or/strings.xml b/Tethering/res/values-mcc310-mnc004-or/strings.xml
new file mode 100644
index 0000000..8038815
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-or/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"ଟିଥରିଂ ପାଇଁ କୌଣସି ଇଣ୍ଟର୍ନେଟ୍ ସଂଯୋଗ ନାହିଁ"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"ଡିଭାଇସଗୁଡ଼ିକ ସଂଯୋଗ କରାଯାଇପାରିବ ନାହିଁ"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ଟିଥରିଂ ବନ୍ଦ କରନ୍ତୁ"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ହଟସ୍ପଟ୍ କିମ୍ବା ଟିଥରିଂ ଚାଲୁ ଅଛି"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ରୋମିଂରେ ଥିବା ସମୟରେ ଅତିରିକ୍ତ ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-pa/strings.xml b/Tethering/res/values-mcc310-mnc004-pa/strings.xml
new file mode 100644
index 0000000..819833e
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-pa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"ਟੈਦਰਿੰਗ ਕੋਲ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"ਡੀਵਾਈਸ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ਟੈਦਰਿੰਗ ਬੰਦ ਕਰੋ"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ਹੌਟਸਪੌਟ ਜਾਂ ਟੈਦਰਿੰਗ ਚਾਲੂ ਹੈ"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ਰੋਮਿੰਗ ਦੌਰਾਨ ਵਧੀਕ ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-pl/strings.xml b/Tethering/res/values-mcc310-mnc004-pl/strings.xml
new file mode 100644
index 0000000..65e4380
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-pl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering nie ma internetu"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Urządzenia nie mogą się połączyć"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Wyłącz tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot lub tethering jest włączony"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Podczas korzystania z roamingu mogą zostać naliczone dodatkowe opłaty"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-pt-rBR/strings.xml b/Tethering/res/values-mcc310-mnc004-pt-rBR/strings.xml
new file mode 100644
index 0000000..d886617
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-pt-rBR/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"O tethering não tem Internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Não é possível conectar os dispositivos"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desativar o tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ponto de acesso ou tethering ativado"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Pode haver cobranças extras durante o roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-pt-rPT/strings.xml b/Tethering/res/values-mcc310-mnc004-pt-rPT/strings.xml
new file mode 100644
index 0000000..bfd45ca
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-pt-rPT/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"A ligação (à Internet) via telemóvel não tem Internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Não é possível ligar os dispositivos"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desativar ligação (à Internet) via telemóvel"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"A zona Wi-Fi ou a ligação (à Internet) via telemóvel está ativada"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Podem aplicar-se custos adicionais em roaming."</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-pt/strings.xml b/Tethering/res/values-mcc310-mnc004-pt/strings.xml
new file mode 100644
index 0000000..d886617
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-pt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"O tethering não tem Internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Não é possível conectar os dispositivos"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desativar o tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ponto de acesso ou tethering ativado"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Pode haver cobranças extras durante o roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-ro/strings.xml b/Tethering/res/values-mcc310-mnc004-ro/strings.xml
new file mode 100644
index 0000000..8d87a9e
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-ro/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Procesul de tethering nu are internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Dispozitivele nu se pot conecta"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Dezactivați procesul de tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"S-a activat hotspotul sau tethering"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Se pot aplica taxe suplimentare pentru roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-ru/strings.xml b/Tethering/res/values-mcc310-mnc004-ru/strings.xml
new file mode 100644
index 0000000..dbdb9eb
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-ru/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Режим модема используется без доступа к Интернету"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Невозможно подключить устройства."</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Отключить режим модема"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Включены точка доступа или режим модема"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"За использование услуг связи в роуминге может взиматься дополнительная плата."</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-si/strings.xml b/Tethering/res/values-mcc310-mnc004-si/strings.xml
new file mode 100644
index 0000000..d8301e4
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-si/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"ටෙදරින් හට අන්තර්ජාලය නැත"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"උපාංගවලට සම්බන්ධ විය නොහැකිය"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ටෙදරින් ක්‍රියාවිරහිත කරන්න"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"හොට්ස්පොට් හෝ ටෙදරින් ක්‍රියාත්මකයි"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"රෝමිං අතරතුර අමතර ගාස්තු අදාළ විය හැකිය"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-sk/strings.xml b/Tethering/res/values-mcc310-mnc004-sk/strings.xml
new file mode 100644
index 0000000..bef7136
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-sk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering nemá internetové pripojenie"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Zariadenia sa nemôžu pripojiť"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Vypnúť tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Je zapnutý hotspot alebo tethering"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Počas roamingu vám môžu byť účtované ďalšie poplatky"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-sl/strings.xml b/Tethering/res/values-mcc310-mnc004-sl/strings.xml
new file mode 100644
index 0000000..3202c62
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-sl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Internetna povezava prek mobilnega telefona ni vzpostavljena"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Napravi se ne moreta povezati"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Izklopi internetno povezavo prek mobilnega telefona"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Dostopna točka ali internetna povezava prek mobilnega telefona je vklopljena"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Med gostovanjem lahko nastanejo dodatni stroški"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-sq/strings.xml b/Tethering/res/values-mcc310-mnc004-sq/strings.xml
new file mode 100644
index 0000000..37f6ad2
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-sq/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Ndarja e internetit nuk ka internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Pajisjet nuk mund të lidhen"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Çaktivizo ndarjen e internetit"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Zona e qasjes për internet ose ndarja e internetit është aktive"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Mund të zbatohen tarifime shtesë kur je në roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-sr/strings.xml b/Tethering/res/values-mcc310-mnc004-sr/strings.xml
new file mode 100644
index 0000000..5566d03
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-sr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Привезивање нема приступ интернету"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Повезивање уређаја није успело"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Искључи привезивање"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Укључен је хотспот или привезивање"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Можда важе додатни трошкови у ромингу"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-sv/strings.xml b/Tethering/res/values-mcc310-mnc004-sv/strings.xml
new file mode 100644
index 0000000..9765acd
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-sv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Det finns ingen internetanslutning för internetdelningen"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Enheterna kan inte anslutas"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Inaktivera internetdelning"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Surfzon eller internetdelning har aktiverats"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ytterligare avgifter kan tillkomma vid roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-sw/strings.xml b/Tethering/res/values-mcc310-mnc004-sw/strings.xml
new file mode 100644
index 0000000..cf850c9
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-sw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Kipengele cha kusambaza mtandao hakina intaneti"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Imeshindwa kuunganisha vifaa"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Zima kipengele cha kusambaza mtandao"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Umewasha kipengele cha kusambaza mtandao au mtandao pepe"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Huenda ukatozwa gharama za ziada ukitumia mitandao ya ng\'ambo"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-ta/strings.xml b/Tethering/res/values-mcc310-mnc004-ta/strings.xml
new file mode 100644
index 0000000..f4b15aa
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-ta/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"இணைப்பு முறைக்கு இணைய இணைப்பு இல்லை"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"சாதனங்களால் இணைய முடியவில்லை"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"இணைப்பு முறையை ஆஃப் செய்"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ஹாட்ஸ்பாட் அல்லது இணைப்பு முறை ஆன் செய்யப்பட்டுள்ளது"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-te/strings.xml b/Tethering/res/values-mcc310-mnc004-te/strings.xml
new file mode 100644
index 0000000..937d34d
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-te/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"టెథరింగ్ చేయడానికి ఇంటర్నెట్ కనెక్షన్ లేదు"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"పరికరాలు కనెక్ట్ అవ్వడం లేదు"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"టెథరింగ్‌ను ఆఫ్ చేయండి"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"హాట్‌స్పాట్ లేదా టెథరింగ్ ఆన్‌లో ఉంది"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"రోమింగ్‌లో ఉన్నప్పుడు అదనపు ఛార్జీలు వర్తించవచ్చు"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-th/strings.xml b/Tethering/res/values-mcc310-mnc004-th/strings.xml
new file mode 100644
index 0000000..f781fae
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-th/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือไม่มีอินเทอร์เน็ต"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"อุปกรณ์เชื่อมต่อไม่ได้"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ปิดการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ฮอตสปอตหรือการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือเปิดอยู่"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"อาจมีค่าใช้จ่ายเพิ่มเติมขณะโรมมิ่ง"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-tl/strings.xml b/Tethering/res/values-mcc310-mnc004-tl/strings.xml
new file mode 100644
index 0000000..8d5d465
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-tl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Walang internet ang pag-tether"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Hindi makakonekta ang mga device"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"I-off ang pag-tether"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Naka-on ang Hotspot o pag-tether"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Posibleng magkaroon ng mga karagdagang singil habang nagro-roam"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-tr/strings.xml b/Tethering/res/values-mcc310-mnc004-tr/strings.xml
new file mode 100644
index 0000000..80cab33
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-tr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering\'in internet bağlantısı yok"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Cihazlar bağlanamıyor"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tethering\'i kapat"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot veya tethering açık"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Dolaşım sırasında ek ücretler uygulanabilir"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-uk/strings.xml b/Tethering/res/values-mcc310-mnc004-uk/strings.xml
new file mode 100644
index 0000000..c05932a
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-uk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Телефон, який використовується як модем, не підключений до Інтернету"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Не вдається підключити пристрої"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Вимкнути використання телефона як модема"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Увімкнено точку доступу або використання телефона як модема"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"У роумінгу може стягуватися додаткова плата"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-ur/strings.xml b/Tethering/res/values-mcc310-mnc004-ur/strings.xml
new file mode 100644
index 0000000..d820eee
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-ur/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"ٹیدرنگ میں انٹرنیٹ نہیں ہے"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"آلات منسلک نہیں ہو سکتے"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ٹیدرنگ آف کریں"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ہاٹ اسپاٹ یا ٹیدرنگ آن ہے"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"رومنگ کے دوران اضافی چارجز لاگو ہو سکتے ہیں"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-uz/strings.xml b/Tethering/res/values-mcc310-mnc004-uz/strings.xml
new file mode 100644
index 0000000..726148a
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-uz/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Modem internetga ulanmagan"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Qurilmalar ulanmadi"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Modem rejimini faolsizlantirish"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot yoki modem rejimi yoniq"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Rouming vaqtida qoʻshimcha haq olinishi mumkin"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-vi/strings.xml b/Tethering/res/values-mcc310-mnc004-vi/strings.xml
new file mode 100644
index 0000000..b7cb045
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-vi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Không có Internet để chia sẻ kết Internet"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Các thiết bị không thể kết nối"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tắt tính năng chia sẻ Internet"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Điểm phát sóng hoặc tính năng chia sẻ Internet đang bật"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Bạn có thể mất thêm phí dữ liệu khi chuyển vùng"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-zh-rCN/strings.xml b/Tethering/res/values-mcc310-mnc004-zh-rCN/strings.xml
new file mode 100644
index 0000000..af91aff
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-zh-rCN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"共享网络未连接到互联网"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"设备无法连接"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"关闭网络共享"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"热点或网络共享已开启"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"漫游时可能会产生额外的费用"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-zh-rHK/strings.xml b/Tethering/res/values-mcc310-mnc004-zh-rHK/strings.xml
new file mode 100644
index 0000000..28e6b80
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-zh-rHK/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"無法透過網絡共享連線至互聯網"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"裝置無法連接"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"關閉網絡共享"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"熱點或網絡共享已開啟"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"漫遊時可能需要支付額外費用"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml b/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml
new file mode 100644
index 0000000..528a1e5
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"無法透過網路共用連上網際網路"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"裝置無法連線"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"關閉網路共用"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"無線基地台或網路共用已開啟"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"使用漫遊服務可能須支付額外費用"</string>
+</resources>
diff --git a/Tethering/res/values-mcc310-mnc004-zu/strings.xml b/Tethering/res/values-mcc310-mnc004-zu/strings.xml
new file mode 100644
index 0000000..11eb666
--- /dev/null
+++ b/Tethering/res/values-mcc310-mnc004-zu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="5030042590486713460">"Ukusebenzisa ifoni njengemodemu akunayo i-inthanethi"</string>
+    <string name="no_upstream_notification_message" msgid="3843613362272973447">"Amadivayisi awakwazi ukuxhumeka"</string>
+    <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Vala ukusebenzisa ifoni njengemodemu"</string>
+    <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"I-hotspot noma ukusebenzisa ifoni njengemodemu kuvuliwe"</string>
+    <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Kungaba nezinkokhelo ezengeziwe uma uzula"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-af/strings.xml b/Tethering/res/values-mcc311-mnc480-af/strings.xml
new file mode 100644
index 0000000..9bfa531
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-af/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Verbinding het nie internet nie"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Toestelle kan nie koppel nie"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Skakel verbinding af"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Warmkol of verbinding is aan"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Bykomende heffings kan geld terwyl jy swerf"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-am/strings.xml b/Tethering/res/values-mcc311-mnc480-am/strings.xml
new file mode 100644
index 0000000..5949dfa
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-am/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"ማስተሳሰር ምንም በይነመረብ የለውም"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"መሣሪያዎችን ማገናኘት አይቻልም"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ማስተሳሰርን አጥፋ"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"መገናኛ ነጥብ ወይም ማስተሳሰር በርቷል"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"በሚያንዣብብበት ጊዜ ተጨማሪ ክፍያዎች ተፈጻሚ ሊሆኑ ይችላሉ"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-ar/strings.xml b/Tethering/res/values-mcc311-mnc480-ar/strings.xml
new file mode 100644
index 0000000..8467f9b
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-ar/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"ما مِن اتصال بالإنترنت خلال التوصيل"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"تعذّر اتصال الأجهزة"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"إيقاف التوصيل"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"نقطة الاتصال أو التوصيل مفعّلان"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"قد يتم تطبيق رسوم إضافية أثناء التجوال."</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-as/strings.xml b/Tethering/res/values-mcc311-mnc480-as/strings.xml
new file mode 100644
index 0000000..9776bd8
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-as/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"টে\'ডাৰিঙৰ ইণ্টাৰনেট নাই"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"ডিভাইচসমূহ সংযোগ কৰিব নোৱাৰি"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"টে\'ডাৰিং অফ কৰক"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"হটস্পট অথবা টে\'ডাৰিং অন আছে"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ৰ\'মিঙত থাকিলে অতিৰিক্ত মাচুল প্ৰযোজ্য হ’ব পাৰে"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-az/strings.xml b/Tethering/res/values-mcc311-mnc480-az/strings.xml
new file mode 100644
index 0000000..e6d3eaf
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-az/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Modemin internetə girişi yoxdur"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Cihazları qoşmaq mümkün deyil"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Modemi deaktiv edin"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot və ya modem aktivdir"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Rouminq zamanı əlavə ödənişlər tətbiq edilə bilər"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-b+sr+Latn/strings.xml b/Tethering/res/values-mcc311-mnc480-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..4c8a1df
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-b+sr+Latn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Privezivanje nema pristup internetu"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Povezivanje uređaja nije uspelo"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Isključi privezivanje"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Uključen je hotspot ili privezivanje"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Možda važe dodatni troškovi u romingu"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-be/strings.xml b/Tethering/res/values-mcc311-mnc480-be/strings.xml
new file mode 100644
index 0000000..edfa41e
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-be/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Рэжым мадэма выкарыстоўваецца без доступу да інтэрнэту"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Не ўдалося падключыць прылады"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Выключыць рэжым мадэма"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Хот-спот або рэжым мадэма ўключаны"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Пры выкарыстанні роўмінгу можа спаганяцца дадатковая плата"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-bg/strings.xml b/Tethering/res/values-mcc311-mnc480-bg/strings.xml
new file mode 100644
index 0000000..f563981
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-bg/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Тетърингът няма връзка с интернет"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Устройствата не могат да установят връзка"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Изключване на тетъринга"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Точката за достъп или тетърингът са включени"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Възможно е да ви бъдат начислени допълнителни такси при роуминг"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-bn/strings.xml b/Tethering/res/values-mcc311-mnc480-bn/strings.xml
new file mode 100644
index 0000000..d8ecd2e
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-bn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"টিথারিং করার জন্য কোনও ইন্টারনেট কানেকশন নেই"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"ডিভাইস কানেক্ট করতে পারছে না"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"টিথারিং বন্ধ করুন"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"হটস্পট বা টিথারিং চালু আছে"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"রোমিংয়ের সময় অতিরিক্ত চার্জ করা হতে পারে"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-bs/strings.xml b/Tethering/res/values-mcc311-mnc480-bs/strings.xml
new file mode 100644
index 0000000..b85fd5e
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-bs/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Povezivanje putem mobitela nema internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Uređaji se ne mogu povezati"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Isključi povezivanje putem mobitela"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Pristupna tačka ili povezivanje putem mobitela je uključeno"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Mogu nastati dodatni troškovi u romingu"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-ca/strings.xml b/Tethering/res/values-mcc311-mnc480-ca/strings.xml
new file mode 100644
index 0000000..a357215
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-ca/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"La compartició de xarxa no té accés a Internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"No es poden connectar els dispositius"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactiva la compartició de xarxa"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"S\'ha activat el punt d\'accés Wi‑Fi o la compartició de xarxa"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"És possible que s\'apliquin costos addicionals en itinerància"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-cs/strings.xml b/Tethering/res/values-mcc311-mnc480-cs/strings.xml
new file mode 100644
index 0000000..91196be
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-cs/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering nemá připojení k internetu"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Zařízení se nemůžou připojit"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Vypnout tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Je zapnutý hotspot nebo tethering"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Při roamingu mohou být účtovány dodatečné poplatky"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-da/strings.xml b/Tethering/res/values-mcc311-mnc480-da/strings.xml
new file mode 100644
index 0000000..1968900
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-da/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Netdeling har ingen internetforbindelse"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Enheder kan ikke oprette forbindelse"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Deaktiver netdeling"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot eller netdeling er aktiveret"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Der opkræves muligvis yderligere gebyrer ved roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-de/strings.xml b/Tethering/res/values-mcc311-mnc480-de/strings.xml
new file mode 100644
index 0000000..eb3f8c5
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-de/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering hat keinen Internetzugriff"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Geräte können sich nicht verbinden"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tethering deaktivieren"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot oder Tethering ist aktiviert"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Für das Roaming können zusätzliche Gebühren anfallen"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-el/strings.xml b/Tethering/res/values-mcc311-mnc480-el/strings.xml
new file mode 100644
index 0000000..56c3d81
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-el/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Η σύνδεση δεν έχει πρόσβαση στο διαδίκτυο"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Δεν είναι δυνατή η σύνδεση των συσκευών"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Απενεργοποιήστε τη σύνδεση"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ενεργό σημείο πρόσβασης Wi-Fi ή ενεργή σύνδεση"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ενδέχεται να ισχύουν επιπλέον χρεώσεις κατά την περιαγωγή."</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-en-rAU/strings.xml b/Tethering/res/values-mcc311-mnc480-en-rAU/strings.xml
new file mode 100644
index 0000000..dd1a197
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-en-rAU/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-en-rCA/strings.xml b/Tethering/res/values-mcc311-mnc480-en-rCA/strings.xml
new file mode 100644
index 0000000..dd1a197
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-en-rCA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-en-rGB/strings.xml b/Tethering/res/values-mcc311-mnc480-en-rGB/strings.xml
new file mode 100644
index 0000000..dd1a197
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-en-rGB/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-en-rIN/strings.xml b/Tethering/res/values-mcc311-mnc480-en-rIN/strings.xml
new file mode 100644
index 0000000..dd1a197
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-en-rIN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-en-rXC/strings.xml b/Tethering/res/values-mcc311-mnc480-en-rXC/strings.xml
new file mode 100644
index 0000000..d3347aa
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-en-rXC/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‎‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‎‏‎‎‎Tethering has no internet‎‏‎‎‏‎"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎Devices can’t connect‎‏‎‎‏‎"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎Turn off tethering‎‏‎‎‏‎"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‎‏‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎Hotspot or tethering is on‎‏‎‎‏‎"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‏‏‏‏‎‎‎‏‎‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‎Additional charges may apply while roaming‎‏‎‎‏‎"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-es-rUS/strings.xml b/Tethering/res/values-mcc311-mnc480-es-rUS/strings.xml
new file mode 100644
index 0000000..2f0504f
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-es-rUS/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"La conexión mediante dispositivo móvil no tiene Internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"No se pueden conectar los dispositivos"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactivar conexión mediante dispositivo móvil"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Se activó el hotspot o la conexión mediante dispositivo móvil"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Es posible que se apliquen cargos adicionales por roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-es/strings.xml b/Tethering/res/values-mcc311-mnc480-es/strings.xml
new file mode 100644
index 0000000..2d8f882
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-es/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"La conexión no se puede compartir, porque no hay acceso a Internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Los dispositivos no se pueden conectar"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactivar conexión compartida"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Punto de acceso o conexión compartida activados"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Puede que se apliquen cargos adicionales en itinerancia"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-et/strings.xml b/Tethering/res/values-mcc311-mnc480-et/strings.xml
new file mode 100644
index 0000000..8493c47
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-et/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Jagamisel puudub internetiühendus"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Seadmed ei saa ühendust luua"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Lülita jagamine välja"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Kuumkoht või jagamine on sisse lülitatud"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Rändluse kasutamisega võivad kaasneda lisatasud"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-eu/strings.xml b/Tethering/res/values-mcc311-mnc480-eu/strings.xml
new file mode 100644
index 0000000..33bccab
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-eu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Konexioa partekatzeko aukerak ez du Interneteko konexiorik"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Ezin dira konektatu gailuak"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desaktibatu konexioa partekatzeko aukera"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Wifi-gunea edo konexioa partekatzeko aukera aktibatuta dago"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Baliteke kostu gehigarriak ordaindu behar izatea ibiltaritzan"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-fa/strings.xml b/Tethering/res/values-mcc311-mnc480-fa/strings.xml
new file mode 100644
index 0000000..cf8a0cc
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-fa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"«اشتراک‌گذاری اینترنت» به اینترنت دسترسی ندارد"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"دستگاه‌ها متصل نمی‌شوند"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"خاموش کردن «اشتراک‌گذاری اینترنت»"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"«نقطه اتصال» یا «اشتراک‌گذاری اینترنت» روشن است"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ممکن است درحین فراگردی تغییرات دیگر اعمال شود"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-fi/strings.xml b/Tethering/res/values-mcc311-mnc480-fi/strings.xml
new file mode 100644
index 0000000..6a3ab80
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-fi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Ei jaettavaa internetyhteyttä"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Laitteet eivät voi muodostaa yhteyttä"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Laita yhteyden jakaminen pois päältä"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot tai yhteyden jakaminen on päällä"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Roaming voi aiheuttaa lisämaksuja"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-fr-rCA/strings.xml b/Tethering/res/values-mcc311-mnc480-fr-rCA/strings.xml
new file mode 100644
index 0000000..ffb9bf6
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-fr-rCA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Le partage de connexion n\'est pas connecté à Internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Impossible de connecter les appareils"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Désactiver le partage de connexion"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Le point d\'accès ou le partage de connexion est activé"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-fr/strings.xml b/Tethering/res/values-mcc311-mnc480-fr/strings.xml
new file mode 100644
index 0000000..768bce3
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-fr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Aucune connexion à Internet n\'est disponible pour le partage de connexion"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Impossible de connecter les appareils"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Désactiver le partage de connexion"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Le point d\'accès ou le partage de connexion est activé"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-gl/strings.xml b/Tethering/res/values-mcc311-mnc480-gl/strings.xml
new file mode 100644
index 0000000..0c4195a
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-gl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"A conexión compartida non ten Internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Non se puideron conectar os dispositivos"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactivar conexión compartida"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Está activada a zona wifi ou a conexión compartida"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Pódense aplicar cargos adicionais en itinerancia"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-gu/strings.xml b/Tethering/res/values-mcc311-mnc480-gu/strings.xml
new file mode 100644
index 0000000..e9d33a7
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-gu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"ઇન્ટરનેટ શેર કરવાની સુવિધામાં ઇન્ટરનેટ નથી"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"ડિવાઇસ કનેક્ટ કરી શકાતા નથી"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ઇન્ટરનેટ શેર કરવાની સુવિધા બંધ કરો"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"હૉટસ્પૉટ અથવા ઇન્ટરનેટ શેર કરવાની સુવિધા ચાલુ છે"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"રોમિંગમાં વધારાના શુલ્ક લાગી શકે છે"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-hi/strings.xml b/Tethering/res/values-mcc311-mnc480-hi/strings.xml
new file mode 100644
index 0000000..aa418ac
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-hi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"टेदरिंग से इंटरनेट नहीं चल रहा"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"डिवाइस कनेक्ट नहीं हो पा रहे"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"टेदरिंग बंद करें"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"हॉटस्पॉट या टेदरिंग चालू है"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिंग के दौरान अतिरिक्त शुल्क लग सकता है"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-hr/strings.xml b/Tethering/res/values-mcc311-mnc480-hr/strings.xml
new file mode 100644
index 0000000..51c524a
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-hr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Modemsko povezivanje nema internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Uređaji se ne mogu povezati"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Isključivanje modemskog povezivanja"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Uključena je žarišna točka ili modemsko povezivanje"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"U roamingu su mogući dodatni troškovi"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-hu/strings.xml b/Tethering/res/values-mcc311-mnc480-hu/strings.xml
new file mode 100644
index 0000000..164e45e
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-hu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Nincs internetkapcsolat az internet megosztásához"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Az eszközök nem tudnak csatlakozni"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Internetmegosztás kikapcsolása"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"A hotspot vagy az internetmegosztás be van kapcsolva"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Roaming során további díjak léphetnek fel"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-hy/strings.xml b/Tethering/res/values-mcc311-mnc480-hy/strings.xml
new file mode 100644
index 0000000..e76c0a4
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-hy/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Մոդեմի ռեժիմի կապը բացակայում է"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Չհաջողվեց միացնել սարքը"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Անջատել մոդեմի ռեժիմը"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Թեժ կետը կամ մոդեմի ռեժիմը միացված է"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ռոումինգում կարող են լրացուցիչ վճարներ գանձվել"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-in/strings.xml b/Tethering/res/values-mcc311-mnc480-in/strings.xml
new file mode 100644
index 0000000..2b817f8
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-in/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Tidak ada koneksi internet di tethering"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Perangkat tidak dapat terhubung"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Nonaktifkan tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot atau tethering aktif"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Biaya tambahan mungkin berlaku saat roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-is/strings.xml b/Tethering/res/values-mcc311-mnc480-is/strings.xml
new file mode 100644
index 0000000..a338d9c
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-is/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Tjóðrun er ekki með internettengingu"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Tæki geta ekki tengst"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Slökkva á tjóðrun"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Kveikt er á heitum reit eða tjóðrun"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Viðbótargjöld kunna að eiga við í reiki"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-it/strings.xml b/Tethering/res/values-mcc311-mnc480-it/strings.xml
new file mode 100644
index 0000000..77769c2
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-it/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Nessuna connessione a Internet per il tethering"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Impossibile connettere i dispositivi"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Disattiva il tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot o tethering attivi"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Potrebbero essere applicati costi aggiuntivi durante il roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-iw/strings.xml b/Tethering/res/values-mcc311-mnc480-iw/strings.xml
new file mode 100644
index 0000000..5267b51
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-iw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"אי אפשר להפעיל את תכונת שיתוף האינטרנט בין מכשירים כי אין חיבור לאינטרנט"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"למכשירים אין אפשרות להתחבר"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"השבתה של שיתוף האינטרנט בין מכשירים"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"תכונת הנקודה לשיתוף אינטרנט או תכונת שיתוף האינטרנט בין מכשירים פועלת"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ייתכנו חיובים נוספים בעת נדידה"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-ja/strings.xml b/Tethering/res/values-mcc311-mnc480-ja/strings.xml
new file mode 100644
index 0000000..66a9a6d
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-ja/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"テザリングがインターネットに接続されていません"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"デバイスを接続できません"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"テザリングを OFF にする"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"アクセス ポイントまたはテザリングが ON です"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ローミング時に追加料金が発生することがあります"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-ka/strings.xml b/Tethering/res/values-mcc311-mnc480-ka/strings.xml
new file mode 100644
index 0000000..d8ad880
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-ka/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"ტეტერინგს არ აქვს ინტერნეტზე წვდომა"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"მოწყობილობები ვერ ახერხებენ დაკავშირებას"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ტეტერინგის გამორთვა"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ჩართულია უსადენო ქსელი ან ტეტერინგი"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"როუმინგის გამოყენებისას შეიძლება ჩამოგეჭრათ დამატებითი საფასური"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-kk/strings.xml b/Tethering/res/values-mcc311-mnc480-kk/strings.xml
new file mode 100644
index 0000000..1ddd6b4
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-kk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Тетеринг режимі интернет байланысынсыз пайдаланылуда"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Құрылғыларды байланыстыру мүмкін емес"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Тетерингіні өшіру"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Хотспот немесе тетеринг қосулы"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Роуминг кезінде қосымша ақы алынуы мүмкін."</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-km/strings.xml b/Tethering/res/values-mcc311-mnc480-km/strings.xml
new file mode 100644
index 0000000..cf5a137
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-km/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"ការភ្ជាប់​មិនមានអ៊ីនធឺណិត​ទេ"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"មិនអាច​ភ្ជាប់ឧបករណ៍​បានទេ"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"បិទការភ្ជាប់"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ហតស្ប៉ត ឬការភ្ជាប់​ត្រូវបានបើក"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"អាចមាន​ការគិតថ្លៃ​បន្ថែម នៅពេល​រ៉ូមីង"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-kn/strings.xml b/Tethering/res/values-mcc311-mnc480-kn/strings.xml
new file mode 100644
index 0000000..68ae68b
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-kn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"ಟೆಥರಿಂಗ್‌ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಕನೆಕ್ಷನ್ ಹೊಂದಿಲ್ಲ"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"ಸಾಧನಗಳನ್ನು ಕನೆಕ್ಟ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ಟೆಥರಿಂಗ್‌ ಆಫ್ ಮಾಡಿ"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ಹಾಟ್‌ಸ್ಪಾಟ್ ಅಥವಾ ಟೆಥರಿಂಗ್‌ ಆನ್ ಆಗಿದೆ"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ರೋಮಿಂಗ್‌ನಲ್ಲಿರುವಾಗ ಹೆಚ್ಚುವರಿ ಶುಲ್ಕಗಳು ಅನ್ವಯವಾಗಬಹುದು"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-ko/strings.xml b/Tethering/res/values-mcc311-mnc480-ko/strings.xml
new file mode 100644
index 0000000..17185ba
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-ko/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"테더링으로 인터넷을 사용할 수 없음"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"기기에서 연결할 수 없음"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"테더링 사용 중지"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"핫스팟 또는 테더링 켜짐"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"로밍 중에는 추가 요금이 발생할 수 있습니다."</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-ky/strings.xml b/Tethering/res/values-mcc311-mnc480-ky/strings.xml
new file mode 100644
index 0000000..6a9fb98
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-ky/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Модем режими Интернети жок колдонулууда"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Түзмөктөр туташпай жатат"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Модем режимин өчүрүү"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Байланыш түйүнү же модем режими күйүк"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Роумингде кошумча акы алынышы мүмкүн"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-lo/strings.xml b/Tethering/res/values-mcc311-mnc480-lo/strings.xml
new file mode 100644
index 0000000..bcc4b57
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-lo/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"ການປ່ອຍສັນຍານບໍ່ມີອິນເຕີເນັດ"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"ອຸປະກອນບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ປິດການປ່ອຍສັນຍານ"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ເປີດໃຊ້ຮັອດສະປອດ ຫຼື ການປ່ອຍສັນຍານຢູ່"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ອາດມີຄ່າໃຊ້ຈ່າຍເພີ່ມເຕີມໃນລະຫວ່າງການໂຣມມິງ"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-lt/strings.xml b/Tethering/res/values-mcc311-mnc480-lt/strings.xml
new file mode 100644
index 0000000..011c2c1
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-lt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Nėra įrenginio kaip modemo naudojimo interneto ryšio"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Nepavyko susieti įrenginių"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Išjungti įrenginio kaip modemo naudojimą"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Įjungtas viešosios interneto prieigos taškas arba įrenginio kaip modemo naudojimas"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Veikiant tarptinkliniam ryšiui gali būti taikomi papildomi mokesčiai"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-lv/strings.xml b/Tethering/res/values-mcc311-mnc480-lv/strings.xml
new file mode 100644
index 0000000..5cb2f3b
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-lv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Piesaistei nav interneta savienojuma"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Nevar savienot ierīces"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Izslēgt piesaisti"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ir ieslēgts tīklājs vai piesaiste"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Viesabonēšanas laikā var tikt piemērota papildu samaksa"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-mk/strings.xml b/Tethering/res/values-mcc311-mnc480-mk/strings.xml
new file mode 100644
index 0000000..4cbfd88
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-mk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Нема интернет преку мобилен"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Уредите не може да се поврзат"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Исклучи интернет преку мобилен"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Точката на пристап или интернетот преку мобилен е вклучен"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"При роаминг може да се наплатат дополнителни трошоци"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-ml/strings.xml b/Tethering/res/values-mcc311-mnc480-ml/strings.xml
new file mode 100644
index 0000000..9cf4eaf
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-ml/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"ടെതറിംഗിന് ഇന്റർനെറ്റ് ഇല്ല"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"ഉപകരണങ്ങൾ കണക്റ്റ് ചെയ്യാനാവില്ല"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ടെതറിംഗ് ഓഫാക്കുക"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ഹോട്ട്‌സ്‌പോട്ട് അല്ലെങ്കിൽ ടെതറിംഗ് ഓണാണ്"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"റോമിംഗ് ചെയ്യുമ്പോൾ അധിക നിരക്കുകൾ ബാധകമായേക്കാം"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-mn/strings.xml b/Tethering/res/values-mcc311-mnc480-mn/strings.xml
new file mode 100644
index 0000000..47c82c1
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-mn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Модемд интернэт алга байна"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Төхөөрөмжүүд холбогдох боломжгүй байна"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Модем болгохыг унтраах"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Сүлжээний цэг эсвэл модем болгох асаалттай байна"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Роумингийн үеэр нэмэлт төлбөр нэхэмжилж болзошгүй"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-mr/strings.xml b/Tethering/res/values-mcc311-mnc480-mr/strings.xml
new file mode 100644
index 0000000..ad9e809
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-mr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"टेदरिंगला इंटरनेट नाही"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"डिव्हाइस कनेक्ट होऊ शकत नाहीत"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"टेदरिंग बंद करा"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"हॉटस्पॉट किंवा टेदरिंग सुरू आहे"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिंगदरम्यान अतिरिक्त शुल्क लागू होऊ शकतात"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-ms/strings.xml b/Tethering/res/values-mcc311-mnc480-ms/strings.xml
new file mode 100644
index 0000000..e708cb8
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-ms/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Penambatan tiada Internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Peranti tidak dapat disambungkan"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Matikan penambatan"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Tempat liputan atau penambatan dihidupkan"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Caj tambahan mungkin digunakan semasa perayauan"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-my/strings.xml b/Tethering/res/values-mcc311-mnc480-my/strings.xml
new file mode 100644
index 0000000..ba54622
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-my/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်းတွင် အင်တာနက် မရှိပါ"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"စက်များ ချိတ်ဆက်၍ မရပါ"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ပိတ်ရန်"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ဟော့စပေါ့ (သို့) မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ဖွင့်ထားသည်"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ပြင်ပကွန်ရက်နှင့် ချိတ်ဆက်သည့်အခါ နောက်ထပ်ကျသင့်မှုများ ရှိနိုင်သည်"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-nb/strings.xml b/Tethering/res/values-mcc311-mnc480-nb/strings.xml
new file mode 100644
index 0000000..57db484
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-nb/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Internettdeling har ikke internettilgang"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Enhetene kan ikke koble til"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Slå av internettdeling"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Wi-Fi-sone eller internettdeling er på"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ytterligere kostnader kan påløpe under roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-ne/strings.xml b/Tethering/res/values-mcc311-mnc480-ne/strings.xml
new file mode 100644
index 0000000..1503244
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-ne/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"टेदरिङमार्फत इन्टरनेट कनेक्सन प्राप्त हुन सकेन"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"यन्त्रहरू कनेक्ट गर्न सकिएन"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"टेदरिङ निष्क्रिय पार्नुहोस्"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"हटस्पट वा टेदरिङ सक्रिय छ"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-nl/strings.xml b/Tethering/res/values-mcc311-mnc480-nl/strings.xml
new file mode 100644
index 0000000..b08133f
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-nl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering heeft geen internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Apparaten kunnen niet worden verbonden"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tethering uitschakelen"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot of tethering is ingeschakeld"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Er kunnen extra kosten voor roaming in rekening worden gebracht."</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-or/strings.xml b/Tethering/res/values-mcc311-mnc480-or/strings.xml
new file mode 100644
index 0000000..1ad4ca3
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-or/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"ଟିଥରିଂ ପାଇଁ କୌଣସି ଇଣ୍ଟର୍ନେଟ୍ ସଂଯୋଗ ନାହିଁ"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"ଡିଭାଇସଗୁଡ଼ିକ ସଂଯୋଗ କରାଯାଇପାରିବ ନାହିଁ"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ଟିଥରିଂ ବନ୍ଦ କରନ୍ତୁ"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ହଟସ୍ପଟ୍ କିମ୍ବା ଟିଥରିଂ ଚାଲୁ ଅଛି"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ରୋମିଂରେ ଥିବା ସମୟରେ ଅତିରିକ୍ତ ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-pa/strings.xml b/Tethering/res/values-mcc311-mnc480-pa/strings.xml
new file mode 100644
index 0000000..88def56
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-pa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"ਟੈਦਰਿੰਗ ਕੋਲ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"ਡੀਵਾਈਸ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ਟੈਦਰਿੰਗ ਬੰਦ ਕਰੋ"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ਹੌਟਸਪੌਟ ਜਾਂ ਟੈਦਰਿੰਗ ਚਾਲੂ ਹੈ"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ਰੋਮਿੰਗ ਦੌਰਾਨ ਵਧੀਕ ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-pl/strings.xml b/Tethering/res/values-mcc311-mnc480-pl/strings.xml
new file mode 100644
index 0000000..f9890ab
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-pl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering nie ma internetu"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Urządzenia nie mogą się połączyć"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Wyłącz tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot lub tethering jest włączony"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Podczas korzystania z roamingu mogą zostać naliczone dodatkowe opłaty"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-pt-rBR/strings.xml b/Tethering/res/values-mcc311-mnc480-pt-rBR/strings.xml
new file mode 100644
index 0000000..ce3b884
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-pt-rBR/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"O tethering não tem Internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Não é possível conectar os dispositivos"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desativar o tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ponto de acesso ou tethering ativado"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Pode haver cobranças extras durante o roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-pt-rPT/strings.xml b/Tethering/res/values-mcc311-mnc480-pt-rPT/strings.xml
new file mode 100644
index 0000000..7e883ea
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-pt-rPT/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"A ligação (à Internet) via telemóvel não tem Internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Não é possível ligar os dispositivos"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desativar ligação (à Internet) via telemóvel"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"A zona Wi-Fi ou a ligação (à Internet) via telemóvel está ativada"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Podem aplicar-se custos adicionais em roaming."</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-pt/strings.xml b/Tethering/res/values-mcc311-mnc480-pt/strings.xml
new file mode 100644
index 0000000..ce3b884
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-pt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"O tethering não tem Internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Não é possível conectar os dispositivos"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desativar o tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ponto de acesso ou tethering ativado"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Pode haver cobranças extras durante o roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-ro/strings.xml b/Tethering/res/values-mcc311-mnc480-ro/strings.xml
new file mode 100644
index 0000000..1009417
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-ro/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Procesul de tethering nu are internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Dispozitivele nu se pot conecta"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Dezactivați procesul de tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"S-a activat hotspotul sau tethering"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Se pot aplica taxe suplimentare pentru roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-ru/strings.xml b/Tethering/res/values-mcc311-mnc480-ru/strings.xml
new file mode 100644
index 0000000..88683be
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-ru/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Режим модема используется без доступа к Интернету"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Невозможно подключить устройства."</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Отключить режим модема"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Включены точка доступа или режим модема"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"За использование услуг связи в роуминге может взиматься дополнительная плата."</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-si/strings.xml b/Tethering/res/values-mcc311-mnc480-si/strings.xml
new file mode 100644
index 0000000..176bcdb
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-si/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"ටෙදරින් හට අන්තර්ජාලය නැත"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"උපාංගවලට සම්බන්ධ විය නොහැකිය"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ටෙදරින් ක්‍රියාවිරහිත කරන්න"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"හොට්ස්පොට් හෝ ටෙදරින් ක්‍රියාත්මකයි"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"රෝමිං අතරතුර අමතර ගාස්තු අදාළ විය හැකිය"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-sk/strings.xml b/Tethering/res/values-mcc311-mnc480-sk/strings.xml
new file mode 100644
index 0000000..b9e2127
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-sk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering nemá internetové pripojenie"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Zariadenia sa nemôžu pripojiť"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Vypnúť tethering"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Je zapnutý hotspot alebo tethering"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Počas roamingu vám môžu byť účtované ďalšie poplatky"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-sl/strings.xml b/Tethering/res/values-mcc311-mnc480-sl/strings.xml
new file mode 100644
index 0000000..e8140e6
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-sl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Internetna povezava prek mobilnega telefona ni vzpostavljena"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Napravi se ne moreta povezati"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Izklopi internetno povezavo prek mobilnega telefona"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Dostopna točka ali internetna povezava prek mobilnega telefona je vklopljena"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Med gostovanjem lahko nastanejo dodatni stroški"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-sq/strings.xml b/Tethering/res/values-mcc311-mnc480-sq/strings.xml
new file mode 100644
index 0000000..61e698d
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-sq/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Ndarja e internetit nuk ka internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Pajisjet nuk mund të lidhen"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Çaktivizo ndarjen e internetit"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Zona e qasjes për internet ose ndarja e internetit është aktive"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Mund të zbatohen tarifime shtesë kur je në roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-sr/strings.xml b/Tethering/res/values-mcc311-mnc480-sr/strings.xml
new file mode 100644
index 0000000..b4c411c
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-sr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Привезивање нема приступ интернету"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Повезивање уређаја није успело"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Искључи привезивање"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Укључен је хотспот или привезивање"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Можда важе додатни трошкови у ромингу"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-sv/strings.xml b/Tethering/res/values-mcc311-mnc480-sv/strings.xml
new file mode 100644
index 0000000..4f543e4
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-sv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Det finns ingen internetanslutning för internetdelningen"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Enheterna kan inte anslutas"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Inaktivera internetdelning"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Surfzon eller internetdelning har aktiverats"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ytterligare avgifter kan tillkomma vid roaming"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-sw/strings.xml b/Tethering/res/values-mcc311-mnc480-sw/strings.xml
new file mode 100644
index 0000000..ac347ab
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-sw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Kipengele cha kusambaza mtandao hakina intaneti"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Imeshindwa kuunganisha vifaa"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Zima kipengele cha kusambaza mtandao"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Umewasha kipengele cha kusambaza mtandao au mtandao pepe"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Huenda ukatozwa gharama za ziada ukitumia mitandao ya ng\'ambo"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-ta/strings.xml b/Tethering/res/values-mcc311-mnc480-ta/strings.xml
new file mode 100644
index 0000000..2ea2467
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-ta/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"இணைப்பு முறைக்கு இணைய இணைப்பு இல்லை"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"சாதனங்களால் இணைய முடியவில்லை"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"இணைப்பு முறையை ஆஃப் செய்"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ஹாட்ஸ்பாட் அல்லது இணைப்பு முறை ஆன் செய்யப்பட்டுள்ளது"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-te/strings.xml b/Tethering/res/values-mcc311-mnc480-te/strings.xml
new file mode 100644
index 0000000..9360297
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-te/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"టెథరింగ్ చేయడానికి ఇంటర్నెట్ కనెక్షన్ లేదు"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"పరికరాలు కనెక్ట్ అవ్వడం లేదు"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"టెథరింగ్‌ను ఆఫ్ చేయండి"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"హాట్‌స్పాట్ లేదా టెథరింగ్ ఆన్‌లో ఉంది"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"రోమింగ్‌లో ఉన్నప్పుడు అదనపు ఛార్జీలు వర్తించవచ్చు"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-th/strings.xml b/Tethering/res/values-mcc311-mnc480-th/strings.xml
new file mode 100644
index 0000000..9c4d7e0
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-th/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือไม่มีอินเทอร์เน็ต"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"อุปกรณ์เชื่อมต่อไม่ได้"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ปิดการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ฮอตสปอตหรือการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือเปิดอยู่"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"อาจมีค่าใช้จ่ายเพิ่มเติมขณะโรมมิ่ง"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-tl/strings.xml b/Tethering/res/values-mcc311-mnc480-tl/strings.xml
new file mode 100644
index 0000000..a7c78a5
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-tl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Walang internet ang pag-tether"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Hindi makakonekta ang mga device"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"I-off ang pag-tether"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Naka-on ang Hotspot o pag-tether"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Posibleng magkaroon ng mga karagdagang singil habang nagro-roam"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-tr/strings.xml b/Tethering/res/values-mcc311-mnc480-tr/strings.xml
new file mode 100644
index 0000000..93da2c3
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-tr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering\'in internet bağlantısı yok"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Cihazlar bağlanamıyor"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tethering\'i kapat"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot veya tethering açık"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Dolaşım sırasında ek ücretler uygulanabilir"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-uk/strings.xml b/Tethering/res/values-mcc311-mnc480-uk/strings.xml
new file mode 100644
index 0000000..ee0dcd2
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-uk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Телефон, який використовується як модем, не підключений до Інтернету"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Не вдається підключити пристрої"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Вимкнути використання телефона як модема"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Увімкнено точку доступу або використання телефона як модема"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"У роумінгу може стягуватися додаткова плата"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-ur/strings.xml b/Tethering/res/values-mcc311-mnc480-ur/strings.xml
new file mode 100644
index 0000000..41cd28e
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-ur/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"ٹیدرنگ میں انٹرنیٹ نہیں ہے"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"آلات منسلک نہیں ہو سکتے"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ٹیدرنگ آف کریں"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ہاٹ اسپاٹ یا ٹیدرنگ آن ہے"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"رومنگ کے دوران اضافی چارجز لاگو ہو سکتے ہیں"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-uz/strings.xml b/Tethering/res/values-mcc311-mnc480-uz/strings.xml
new file mode 100644
index 0000000..c847bc9
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-uz/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Modem internetga ulanmagan"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Qurilmalar ulanmadi"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Modem rejimini faolsizlantirish"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot yoki modem rejimi yoniq"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Rouming vaqtida qoʻshimcha haq olinishi mumkin"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-vi/strings.xml b/Tethering/res/values-mcc311-mnc480-vi/strings.xml
new file mode 100644
index 0000000..a74326f
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-vi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Không có Internet để chia sẻ kết Internet"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Các thiết bị không thể kết nối"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tắt tính năng chia sẻ Internet"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Điểm phát sóng hoặc tính năng chia sẻ Internet đang bật"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Bạn có thể mất thêm phí dữ liệu khi chuyển vùng"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-zh-rCN/strings.xml b/Tethering/res/values-mcc311-mnc480-zh-rCN/strings.xml
new file mode 100644
index 0000000..d737003
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-zh-rCN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"共享网络未连接到互联网"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"设备无法连接"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"关闭网络共享"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"热点或网络共享已开启"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"漫游时可能会产生额外的费用"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-zh-rHK/strings.xml b/Tethering/res/values-mcc311-mnc480-zh-rHK/strings.xml
new file mode 100644
index 0000000..f378a9d
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-zh-rHK/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"無法透過網絡共享連線至互聯網"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"裝置無法連接"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"關閉網絡共享"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"熱點或網絡共享已開啟"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"漫遊時可能需要支付額外費用"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml b/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml
new file mode 100644
index 0000000..cd653df
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"無法透過網路共用連上網際網路"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"裝置無法連線"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"關閉網路共用"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"無線基地台或網路共用已開啟"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"使用漫遊服務可能須支付額外費用"</string>
+</resources>
diff --git a/Tethering/res/values-mcc311-mnc480-zu/strings.xml b/Tethering/res/values-mcc311-mnc480-zu/strings.xml
new file mode 100644
index 0000000..32f6df5
--- /dev/null
+++ b/Tethering/res/values-mcc311-mnc480-zu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="no_upstream_notification_title" msgid="611650570559011140">"Ukusebenzisa ifoni njengemodemu akunayo i-inthanethi"</string>
+    <string name="no_upstream_notification_message" msgid="6508394877641864863">"Amadivayisi awakwazi ukuxhumeka"</string>
+    <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Vala ukusebenzisa ifoni njengemodemu"</string>
+    <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"I-hotspot noma ukusebenzisa ifoni njengemodemu kuvuliwe"</string>
+    <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Kungaba nezinkokhelo ezengeziwe uma uzula"</string>
+</resources>
diff --git a/Tethering/res/values-mk/strings.xml b/Tethering/res/values-mk/strings.xml
index 0fab8aa..9ad9b9a 100644
--- a/Tethering/res/values-mk/strings.xml
+++ b/Tethering/res/values-mk/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Поврзувањето или точката на пристап се активни"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Допрете за поставување."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Врзувањето е оневозможено"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Контактирајте со администраторот за детали"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Активно е врзување или точка на пристап"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Допрете за поставување."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Врзувањето е оневозможено"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Контактирајте со администраторот за детали"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус на точката на пристап и врзувањето"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-ml/strings.xml b/Tethering/res/values-ml/strings.xml
index fd7e556..9db79ce 100644
--- a/Tethering/res/values-ml/strings.xml
+++ b/Tethering/res/values-ml/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ടെതറിംഗ് അല്ലെങ്കിൽ ഹോട്ട്സ്‌പോട്ട് സജീവമാണ്"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"സജ്ജമാക്കാൻ ടാപ്പുചെയ്യുക."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ടെതറിംഗ് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"വിശദവിവരങ്ങൾക്ക് നിങ്ങളുടെ അഡ്മിനെ ബന്ധപ്പെടുക"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"ടെതറിംഗ് അല്ലെങ്കിൽ ഹോട്ട്സ്‌പോട്ട് സജീവമാണ്"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"സജ്ജീകരിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ടെതറിംഗ് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"വിശദാംശങ്ങൾക്ക് നിങ്ങളുടെ അഡ്മിനെ ബന്ധപ്പെടുക"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ഹോട്ട്‌സ്പോട്ടിന്റെയും ടെതറിംഗിന്റെയും നില"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-mn/strings.xml b/Tethering/res/values-mn/strings.xml
index 4596577..42d1edb 100644
--- a/Tethering/res/values-mn/strings.xml
+++ b/Tethering/res/values-mn/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Модем болгох эсвэл идэвхтэй цэг болгох"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Тохируулахын тулд товшино уу."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Модем болгох боломжгүй байна"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Дэлгэрэнгүй мэдээлэл авахын тулд админтайгаа холбогдоно уу"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Модем болгох эсвэл сүлжээний цэг идэвхтэй байна"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Тохируулахын тулд товшино уу."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Модем болгохыг идэвхгүй болгосон"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Дэлгэрэнгүй мэдээлэл авахын тулд админтайгаа холбогдоно уу"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Сүлжээний цэг болон модем болгох төлөв"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-mr/strings.xml b/Tethering/res/values-mr/strings.xml
index 85c9ade..13995b6 100644
--- a/Tethering/res/values-mr/strings.xml
+++ b/Tethering/res/values-mr/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग किंवा हॉटस्पॉट सक्रिय"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करण्यासाठी टॅप करा."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग बंद आहे"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"तपशीलांसाठी तुमच्या प्रशासकाशी संपर्क साधा"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"टेदरिंग किंवा हॉटस्पॉट अ‍ॅक्टिव्ह आहे"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"सेट करण्यासाठी टॅप करा."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"टेदरिंग बंद केले आहे"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"तपशीलांसाठी तुमच्या ॲडमिनशी संपर्क साधा"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"हॉटस्पॉट आणि टेदरिंगची स्थिती"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-ms/strings.xml b/Tethering/res/values-ms/strings.xml
index ec6bdbd..d6a67f3 100644
--- a/Tethering/res/values-ms/strings.xml
+++ b/Tethering/res/values-ms/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Penambatan atau titik panas aktif"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Ketik untuk membuat persediaan."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Penambatan dilumpuhkan"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi pentadbir anda untuk maklumat lanjut"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Penambatan atau tempat liputan aktif"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Ketik untuk membuat persediaan."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Penambatan dilumpuhkan"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hubungi pentadbir anda untuk mendapatkan maklumat lanjut"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status tempat liputan &amp; penambatan"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-my/strings.xml b/Tethering/res/values-my/strings.xml
index 83978b6..49f6b88 100644
--- a/Tethering/res/values-my/strings.xml
+++ b/Tethering/res/values-my/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"တဆင့်ပြန်လည်လွှင့်ခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"စနစ်ထည့်သွင်းရန် တို့ပါ။"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"မိုဘိုင်းဖုန်းကို မိုဒမ်အဖြစ်သုံးခြင်းအား ပိတ်ထားသည်"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"အသေးစိတ်အချက်အလက်များအတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"စနစ်ထည့်သွင်းရန် တို့ပါ။"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်းကို ပိတ်ထားသည်"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"အသေးစိတ်အတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ဟော့စပေါ့နှင့် မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း အခြေအနေ"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-nb/strings.xml b/Tethering/res/values-nb/strings.xml
index 9abf32d..9594e0a 100644
--- a/Tethering/res/values-nb/strings.xml
+++ b/Tethering/res/values-nb/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Internettdeling eller trådløs sone er aktiv"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Trykk for å konfigurere."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Internettdeling er slått av"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ta kontakt med administratoren din for å få mer informasjon"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Internettdeling eller Wi-Fi-sone er aktiv"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Trykk for å konfigurere."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Internettdeling er slått av"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Ta kontakt med administratoren din for å få mer informasjon"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status for Wi-Fi-sone og internettdeling"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-ne/strings.xml b/Tethering/res/values-ne/strings.xml
index c886929..72ae3a8 100644
--- a/Tethering/res/values-ne/strings.xml
+++ b/Tethering/res/values-ne/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"टेथर गर्ने वा हटस्पट सक्रिय"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"सेटअप गर्न ट्याप गर्नुहोस्।"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिङलाई असक्षम पारिएको छ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"विवरणहरूका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"टेदरिङ वा हटस्पट सक्रिय छ"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"सेटअप गर्न ट्याप गर्नुहोस्।"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"टेदरिङ सुविधा असक्षम पारिएको छ"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"विवरणहरूका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"हटस्पट तथा टेदरिङको स्थिति"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-nl/strings.xml b/Tethering/res/values-nl/strings.xml
index 0ec4bff..18b2bbf 100644
--- a/Tethering/res/values-nl/strings.xml
+++ b/Tethering/res/values-nl/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering of hotspot actief"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tik om in te stellen."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is uitgeschakeld"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Neem contact op met je beheerder voor meer informatie"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering of hotspot actief"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tik om in te stellen."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is uitgeschakeld"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Neem contact op met je beheerder voor meer informatie"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status van hotspot en tethering"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-or/strings.xml b/Tethering/res/values-or/strings.xml
index 4576857..a15a6db 100644
--- a/Tethering/res/values-or/strings.xml
+++ b/Tethering/res/values-or/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ଟିଥରିଙ୍ଗ କିମ୍ୱା ହଟସ୍ପଟ୍‌ ସକ୍ରିୟ ଅଛି"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"ସେଟଅପ୍‍ କରିବାକୁ ଟାପ୍‍ କରନ୍ତୁ।"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ଟିଥରିଙ୍ଗ ଅକ୍ଷମ କରାଯାଇଛି"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ବିବରଣୀ ପାଇଁ ନିଜ ଆଡମିନ୍‌ଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"ଟିଥେରିଂ କିମ୍ୱା ହଟସ୍ପଟ୍ ସକ୍ରିୟ ଅଛି"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"ସେଟ୍ ଅପ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ଟିଥେରିଂ ଅକ୍ଷମ କରାଯାଇଛି"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"ବିବରଣୀଗୁଡ଼ିକ ପାଇଁ ଆପଣଙ୍କ ଆଡମିନଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ହଟସ୍ପଟ୍ ଓ ଟିଥେରିଂ ସ୍ଥିତି"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-pa/strings.xml b/Tethering/res/values-pa/strings.xml
index deddf2e..a8235e4 100644
--- a/Tethering/res/values-pa/strings.xml
+++ b/Tethering/res/values-pa/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ਟੈਦਰਿੰਗ ਜਾਂ ਹੌਟਸਪੌਟ ਕਿਰਿਆਸ਼ੀਲ"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"ਸਥਾਪਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ਟੈਦਰਿੰਗ ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"ਟੈਦਰਿੰਗ ਜਾਂ ਹੌਟਸਪੌਟ ਕਿਰਿਆਸ਼ੀਲ"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"ਸੈੱਟਅੱਪ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ਟੈਦਰਿੰਗ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ਹੌਟਸਪੌਟ ਅਤੇ ਟੈਦਰਿੰਗ ਦੀ ਸਥਿਤੀ"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-pl/strings.xml b/Tethering/res/values-pl/strings.xml
index 48d8468..ccb017d 100644
--- a/Tethering/res/values-pl/strings.xml
+++ b/Tethering/res/values-pl/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Aktywny tethering lub punkt dostępu"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Kliknij, by skonfigurować."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering został wyłączony"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Aby uzyskać szczegółowe informacje, skontaktuj się z administratorem"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Aktywny tethering lub punkt dostępu"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Kliknij, by skonfigurować"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering został wyłączony"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Aby uzyskać szczegółowe informacje, skontaktuj się z administratorem"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot i tethering – stan"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-pt-rBR/strings.xml b/Tethering/res/values-pt-rBR/strings.xml
index 32c22b8..a0a4745 100644
--- a/Tethering/res/values-pt-rBR/strings.xml
+++ b/Tethering/res/values-pt-rBR/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Ponto de acesso ou tethering ativo"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Ponto de acesso ou tethering ativo"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering desativado"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Fale com seu administrador para saber detalhes"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status de ponto de acesso e tethering"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-pt-rPT/strings.xml b/Tethering/res/values-pt-rPT/strings.xml
index 641e22f..e3f03fc 100644
--- a/Tethering/res/values-pt-rPT/strings.xml
+++ b/Tethering/res/values-pt-rPT/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Ligação ponto a ponto ou hotspot activos"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"A ligação (à Internet) via telemóvel está desativada."</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacte o gestor para obter detalhes."</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Ligação (à Internet) via telemóvel ou zona Wi-Fi ativas"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"A ligação (à Internet) via telemóvel está desativada."</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacte o administrador para obter detalhes."</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado da zona Wi-Fi e da ligação (à Internet) via telemóvel"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-pt/strings.xml b/Tethering/res/values-pt/strings.xml
index 32c22b8..a0a4745 100644
--- a/Tethering/res/values-pt/strings.xml
+++ b/Tethering/res/values-pt/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Ponto de acesso ou tethering ativo"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Ponto de acesso ou tethering ativo"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering desativado"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Fale com seu administrador para saber detalhes"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status de ponto de acesso e tethering"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-ro/strings.xml b/Tethering/res/values-ro/strings.xml
index f861f73..5706a4a 100644
--- a/Tethering/res/values-ro/strings.xml
+++ b/Tethering/res/values-ro/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering sau hotspot activ"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Atingeți ca să configurați."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tetheringul este dezactivat"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contactați administratorul pentru detalii"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering sau hotspot activ"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Atingeți ca să configurați."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tetheringul este dezactivat"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contactați administratorul pentru detalii"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Starea hotspotului și a tetheringului"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-ru/strings.xml b/Tethering/res/values-ru/strings.xml
index 027cb41..7cb6f7d 100644
--- a/Tethering/res/values-ru/strings.xml
+++ b/Tethering/res/values-ru/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Включен режим модема"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Нажмите, чтобы настроить."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Включить режим модема нельзя"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Обратитесь к администратору, чтобы узнать подробности."</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Включен режим модема или точка доступа"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Нажмите, чтобы настроить."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Использование телефона в качестве модема запрещено"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Чтобы узнать подробности, обратитесь к администратору."</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус хот-спота и режима модема"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-si/strings.xml b/Tethering/res/values-si/strings.xml
index 7d8599f..ec34c22 100644
--- a/Tethering/res/values-si/strings.xml
+++ b/Tethering/res/values-si/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ටෙදරින් හෝ හොට්ස්පොට් සක්‍රීයයි"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"පිහිටුවීමට තට්ටු කරන්න."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ටෙදරින් අබල කර ඇත"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"විස්තර සඳහා ඔබගේ පරිපාලක අමතන්න"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"ටෙදරින් හෝ හොට්ස්පොට් සක්‍රීයයි"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"පිහිටුවීමට තට්ටු කරන්න."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ටෙදරින් අබල කර ඇත"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"විස්තර සඳහා ඔබගේ පරිපාලක අමතන්න"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"හොට්ස්පොට් &amp; ටෙදරින් තත්ත්වය"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-sk/strings.xml b/Tethering/res/values-sk/strings.xml
index a8fe297..43e787c 100644
--- a/Tethering/res/values-sk/strings.xml
+++ b/Tethering/res/values-sk/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering alebo prístupový bod je aktívny"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Klepnutím prejdete na nastavenie."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering je deaktivovaný"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"O podrobnosti požiadajte svojho správcu"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering alebo prístupový bod je aktívny"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Klepnutím prejdete na nastavenie."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering je deaktivovaný"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"O podrobnosti požiadajte svojho správcu"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stav hotspotu a tetheringu"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-sl/strings.xml b/Tethering/res/values-sl/strings.xml
index b5e5e38..5943362 100644
--- a/Tethering/res/values-sl/strings.xml
+++ b/Tethering/res/values-sl/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Aktivna povezava z internetom ali dostopna točka sta aktivni"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Dotaknite se, če želite nastaviti."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Povezava z internetom prek mobilnega telefona je onemogočena"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Za podrobnosti se obrnite na skrbnika"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Povezava z internetom prek mobilnega telefona ali dostopna točka je aktivna"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Dotaknite se, če želite nastaviti."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Povezava z internetom prek mobilnega telefona je onemogočena"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Za podrobnosti se obrnite na skrbnika"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stanje dostopne točke in povezave z internetom prek mobilnega telefona"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-sq/strings.xml b/Tethering/res/values-sq/strings.xml
index fdd4906..21e1155 100644
--- a/Tethering/res/values-sq/strings.xml
+++ b/Tethering/res/values-sq/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Lidhja e çiftimit ose ajo e qasjes në zona publike interneti është aktive"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Trokit për ta konfiguruar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Lidhja e çiftimit është çaktivizuar"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakto me administratorin për detaje"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Ndarja e internetit ose zona e qasjes së internetit është aktive"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Trokit për ta konfiguruar."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Ndarja e internetit është çaktivizuar"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakto me administratorin për detaje"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Statusi i zonës së qasjes dhe ndarjes së internetit"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-sr/strings.xml b/Tethering/res/values-sr/strings.xml
index 9fab345..e2e4dc6 100644
--- a/Tethering/res/values-sr/strings.xml
+++ b/Tethering/res/values-sr/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Активно повезивање са интернетом преко мобилног уређаја или хотспот"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Додирните да бисте подесили."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Привезивање је онемогућено"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Потражите детаље од администратора"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Привезивање или хотспот је активан"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Додирните да бисте подесили."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Привезивање је онемогућено"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Потражите детаље од администратора"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус хотспота и привезивања"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-sv/strings.xml b/Tethering/res/values-sv/strings.xml
index 10eeb0f..72702c2 100644
--- a/Tethering/res/values-sv/strings.xml
+++ b/Tethering/res/values-sv/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Internetdelning eller surfzon aktiverad"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tryck om du vill konfigurera."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Internetdelning har inaktiverats"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakta administratören om du vill veta mer"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Internetdelning eller surfzon har aktiverats"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tryck om du vill konfigurera."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Internetdelning har inaktiverats"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakta administratören om du vill veta mer"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Trådlös surfzon och internetdelning har inaktiverats"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-sw/strings.xml b/Tethering/res/values-sw/strings.xml
index 3353963..65e4aa8 100644
--- a/Tethering/res/values-sw/strings.xml
+++ b/Tethering/res/values-sw/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Kushiriki au kusambaza intaneti kumewashwa"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Gusa ili uweke mipangilio."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Umezima kipengele cha kusambaza mtandao"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Wasiliana na msimamizi wako ili upate maelezo zaidi"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Kusambaza mtandao au mtandaopepe umewashwa"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Gusa ili uweke mipangilio."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Umezima kipengele cha kusambaza mtandao"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Wasiliana na msimamizi wako ili upate maelezo zaidi"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Mtandaopepe na hali ya kusambaza mtandao"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-ta/strings.xml b/Tethering/res/values-ta/strings.xml
index b1e5cc2..4aba62d 100644
--- a/Tethering/res/values-ta/strings.xml
+++ b/Tethering/res/values-ta/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"டெதெரிங்/ஹாட்ஸ்பாட் இயங்குகிறது"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"அமைக்க, தட்டவும்."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"இணைப்பு முறை முடக்கப்பட்டுள்ளது"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"விவரங்களுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"டெதெரிங் அல்லது ஹாட்ஸ்பாட் இயங்குகிறது"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"அமைக்க, தட்டவும்."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"டெதெரிங் முடக்கப்பட்டுள்ளது"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"விவரங்களுக்கு உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ஹாட்ஸ்பாட் &amp; டெதெரிங் நிலை"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-te/strings.xml b/Tethering/res/values-te/strings.xml
index aae40de..1f91791 100644
--- a/Tethering/res/values-te/strings.xml
+++ b/Tethering/res/values-te/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"టీథర్ చేయబడినది లేదా హాట్‌స్పాట్ సక్రియంగా ఉండేది"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"సెటప్ చేయడానికి నొక్కండి."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"టెథెరింగ్ నిలిపివేయబడింది"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"వివరాల కోసం మీ నిర్వాహకులను సంప్రదించండి"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"టెథరింగ్ లేదా హాట్‌స్పాట్ యాక్టివ్‌గా ఉంది"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"సెటప్ చేయడానికి ట్యాప్ చేయండి."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"టెథరింగ్ డిజేబుల్ చేయబడింది"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"వివరాల కోసం మీ అడ్మిన్‌ని సంప్రదించండి"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"హాట్‌స్పాట్ &amp; టెథరింగ్ స్థితి"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-th/strings.xml b/Tethering/res/values-th/strings.xml
index 1b80056..44171c0 100644
--- a/Tethering/res/values-th/strings.xml
+++ b/Tethering/res/values-th/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"การปล่อยสัญญาณหรือฮอตสปอตทำงานอยู่"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"แตะเพื่อตั้งค่า"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ปิดใช้การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือแล้ว"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ติดต่อผู้ดูแลระบบเพื่อขอรายละเอียด"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือหรือฮอตสปอตทำงานอยู่"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"แตะเพื่อตั้งค่า"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ปิดใช้การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือแล้ว"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"ติดต่อผู้ดูแลระบบเพื่อขอรายละเอียด"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"สถานะฮอตสปอตและการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-tl/strings.xml b/Tethering/res/values-tl/strings.xml
index 12863f9..7347dd3 100644
--- a/Tethering/res/values-tl/strings.xml
+++ b/Tethering/res/values-tl/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Pagsasama o aktibong hotspot"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"I-tap upang i-set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Naka-disable ang pag-tether"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Makipag-ugnayan sa iyong admin para sa mga detalye"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Aktibo ang pag-tether o hotspot"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"I-tap para i-set up."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Naka-disable ang pag-tether"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Makipag-ugnayan sa iyong admin para sa mga detalye"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status ng hotspot at pag-tether"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-tr/strings.xml b/Tethering/res/values-tr/strings.xml
index bfcf1ac..32030f1 100644
--- a/Tethering/res/values-tr/strings.xml
+++ b/Tethering/res/values-tr/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering veya hotspot etkin"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Ayarlamak için dokunun."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering devre dışı bırakıldı"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ayrıntılı bilgi için yöneticinize başvurun"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering veya hotspot etkin"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Ayarlamak için dokunun."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering devre dışı bırakıldı"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Ayrıntılı bilgi için yöneticinize başvurun"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot ve tethering durumu"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-uk/strings.xml b/Tethering/res/values-uk/strings.xml
index 8e159c0..1ca89b3 100644
--- a/Tethering/res/values-uk/strings.xml
+++ b/Tethering/res/values-uk/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Прив\'язка чи точка дост. активна"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Торкніться, щоб налаштувати."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Використання телефона в режимі модема вимкнено"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Щоб дізнатися більше, зв’яжіться з адміністратором"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Модем чи точка доступу активні"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Натисніть, щоб налаштувати."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Використання телефона як модема вимкнено"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Щоб дізнатися більше, зв\'яжіться з адміністратором"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус точки доступу та модема"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-ur/strings.xml b/Tethering/res/values-ur/strings.xml
index 89195d4..d72c7d4 100644
--- a/Tethering/res/values-ur/strings.xml
+++ b/Tethering/res/values-ur/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ٹیدرنگ یا ہاٹ اسپاٹ فعال"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"سیٹ اپ کرنے کیلئے تھپتھپائیں۔"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ٹیدرنگ غیر فعال ہے"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"تفصیلات کے لئے اپنے منتظم سے رابطہ کریں"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"ٹیدرنگ یا ہاٹ اسپاٹ فعال"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"سیٹ اپ کرنے کیلئے تھپتھپائیں۔"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ٹیدرنگ غیر فعال ہے"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"تفصیلات کے لئے اپنے منتظم سے رابطہ کریں"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ہاٹ اسپاٹ اور ٹیتھرنگ کا اسٹیٹس"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-uz/strings.xml b/Tethering/res/values-uz/strings.xml
index 0ac4d4a..af3b2eb 100644
--- a/Tethering/res/values-uz/strings.xml
+++ b/Tethering/res/values-uz/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Modem rejimi yoniq"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Sozlash uchun bosing."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Modem rejimi faolsizlantirildi"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Tafsilotlari uchun administratoringizga murojaat qiling"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Modem rejimi yoki hotspot yoniq"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Sozlash uchun bosing."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Modem rejimi faolsizlantirildi"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Tafsilotlari uchun administratoringizga murojaat qiling"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot va modem rejimi holati"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-vi/strings.xml b/Tethering/res/values-vi/strings.xml
index 85a4db8..21a0735 100644
--- a/Tethering/res/values-vi/strings.xml
+++ b/Tethering/res/values-vi/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Chức năng điểm truy cập Internet hoặc điểm phát sóng đang hoạt động"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Nhấn để thiết lập."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Đã tắt tính năng chia sẻ kết nối"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hãy liên hệ với quản trị viên của bạn để biết chi tiết"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tính năng chia sẻ Internet hoặc điểm phát sóng đang hoạt động"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Hãy nhấn để thiết lập."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Đã tắt tính năng chia sẻ Internet"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hãy liên hệ với quản trị viên của bạn để biết chi tiết"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Trạng thái điểm phát sóng và chia sẻ Internet"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-zh-rCN/strings.xml b/Tethering/res/values-zh-rCN/strings.xml
index ff1fe03..98e3b4b 100644
--- a/Tethering/res/values-zh-rCN/strings.xml
+++ b/Tethering/res/values-zh-rCN/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"网络共享或热点已启用"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"点按即可进行设置。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"网络共享已停用"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"请与您的管理员联系以了解详情"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"网络共享或热点已启用"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"点按即可设置。"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"网络共享已停用"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"如需了解详情,请与您的管理员联系"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"热点和网络共享状态"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-zh-rHK/strings.xml b/Tethering/res/values-zh-rHK/strings.xml
index 0de39fa..9cafd42 100644
--- a/Tethering/res/values-zh-rHK/strings.xml
+++ b/Tethering/res/values-zh-rHK/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"已啟用網絡共享或熱點"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"輕按即可設定。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"網絡共享已停用"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"請聯絡您的管理員以瞭解詳情"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"網絡共享或熱點已啟用"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"輕按即可設定。"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"網絡共享已停用"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"請聯絡您的管理員以瞭解詳情"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"熱點和網絡共享狀態"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-zh-rTW/strings.xml b/Tethering/res/values-zh-rTW/strings.xml
index 9a117bb..50a50bf 100644
--- a/Tethering/res/values-zh-rTW/strings.xml
+++ b/Tethering/res/values-zh-rTW/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"網路共用或無線基地台已啟用"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"輕觸即可進行設定。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"數據連線已停用"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"詳情請洽你的管理員"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"網路共用或無線基地台已啟用"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"輕觸即可進行設定。"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"網路共用已停用"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"詳情請洽你的管理員"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"無線基地台與網路共用狀態"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values-zu/strings.xml b/Tethering/res/values-zu/strings.xml
index 8fe10d8..f210f87 100644
--- a/Tethering/res/values-zu/strings.xml
+++ b/Tethering/res/values-zu/strings.xml
@@ -1,8 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Ukusebenzisa njengemodemu noma i-hotspot ephathekayo kuvuliwe"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Thepha ukuze usethe."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Ukusebenzisa ifoni njengemodemu kukhutshaziwe"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Xhumana nomphathi wakho ukuze uthole imininingwane"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Ukusebenzisa njengemodemu noma i-hotspot ephathekayo kuvuliwe"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Thepha ukuze usethe."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Ukusebenzisa ifoni njengemodemu kukhutshaziwe"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Xhumana nomphathi wakho ukuze uthole imininingwane"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"I-Hotspot nesimo sokusebenzisa ifoni njengemodemu"</string>
+    <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+    <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+    <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+    <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+    <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
 </resources>
diff --git a/Tethering/res/values/config.xml b/Tethering/res/values/config.xml
index 5f8d299..4391006 100644
--- a/Tethering/res/values/config.xml
+++ b/Tethering/res/values/config.xml
@@ -40,6 +40,8 @@
     <string-array translatable="false" name="config_tether_wifi_regexs">
         <item>"wlan\\d"</item>
         <item>"softap\\d"</item>
+        <item>"ap_br_wlan\\d"</item>
+        <item>"ap_br_softap\\d"</item>
     </string-array>
 
     <!-- List of regexpressions describing the interface (if any) that represent tetherable
diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index 52d59fc..194737a 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -67,13 +67,12 @@
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
 import com.android.networkstack.tethering.BpfCoordinator;
+import com.android.networkstack.tethering.BpfCoordinator.ClientInfo;
 import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
 import com.android.networkstack.tethering.PrivateAddressCoordinator;
 
-import java.io.IOException;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
-import java.net.NetworkInterface;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -186,16 +185,6 @@
             return InterfaceParams.getByName(ifName);
         }
 
-        /** Get |ifName|'s interface index. */
-        public int getIfindex(String ifName) {
-            try {
-                return NetworkInterface.getByName(ifName).getIndex();
-            } catch (IOException | NullPointerException e) {
-                Log.e(TAG, "Can't determine interface index for interface " + ifName);
-                return 0;
-            }
-        }
-
         /** Create a DhcpServer instance to be used by IpServer. */
         public abstract void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
                 DhcpServerCallbacks cb);
@@ -941,11 +930,38 @@
         }
     }
 
+    // TODO: consider moving into BpfCoordinator.
+    private void updateClientInfoIpv4(NeighborEvent e) {
+        // TODO: Perhaps remove this protection check.
+        // See the related comment in #addIpv6ForwardingRule.
+        if (!mUsingBpfOffload) return;
+
+        if (e == null) return;
+        if (!(e.ip instanceof Inet4Address) || e.ip.isMulticastAddress()
+                || e.ip.isLoopbackAddress() || e.ip.isLinkLocalAddress()) {
+            return;
+        }
+
+        // When deleting clients, IpServer still need to pass a non-null MAC, even though it's
+        // ignored. Do this here instead of in the ClientInfo constructor to ensure that
+        // IpServer never add clients with a null MAC, only delete them.
+        final MacAddress clientMac = e.isValid() ? e.macAddr : NULL_MAC_ADDRESS;
+        final ClientInfo clientInfo = new ClientInfo(mInterfaceParams.index,
+                mInterfaceParams.macAddr, (Inet4Address) e.ip, clientMac);
+        if (e.isValid()) {
+            mBpfCoordinator.tetherOffloadClientAdd(this, clientInfo);
+        } else {
+            // TODO: Delete all related offload rules which are using this client.
+            mBpfCoordinator.tetherOffloadClientRemove(this, clientInfo);
+        }
+    }
+
     private void handleNeighborEvent(NeighborEvent e) {
         if (mInterfaceParams != null
                 && mInterfaceParams.index == e.ifindex
                 && mInterfaceParams.hasMacAddress) {
             updateIpv6ForwardingRules(mLastIPv6UpstreamIfindex, mLastIPv6UpstreamIfindex, e);
+            updateClientInfoIpv4(e);
         }
     }
 
@@ -1111,9 +1127,19 @@
         }
     }
 
+    private void startConntrackMonitoring() {
+        mBpfCoordinator.startMonitoring(this);
+    }
+
+    private void stopConntrackMonitoring() {
+        mBpfCoordinator.stopMonitoring(this);
+    }
+
     class BaseServingState extends State {
         @Override
         public void enter() {
+            startConntrackMonitoring();
+
             if (!startIPv4()) {
                 mLastError = TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR;
                 return;
@@ -1149,6 +1175,7 @@
             }
 
             stopIPv4();
+            stopConntrackMonitoring();
 
             resetLinkProperties();
         }
diff --git a/Tethering/src/android/net/util/BaseNetdUnsolicitedEventListener.java b/Tethering/src/android/net/util/BaseNetdUnsolicitedEventListener.java
deleted file mode 100644
index b1ffdb0..0000000
--- a/Tethering/src/android/net/util/BaseNetdUnsolicitedEventListener.java
+++ /dev/null
@@ -1,75 +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 android.net.util;
-
-import android.net.INetdUnsolicitedEventListener;
-
-import androidx.annotation.NonNull;
-
-/**
- * Base {@link INetdUnsolicitedEventListener} that provides no-op implementations which can be
- * overridden.
- */
-public class BaseNetdUnsolicitedEventListener extends INetdUnsolicitedEventListener.Stub {
-
-    @Override
-    public void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs,
-            int uid) { }
-
-    @Override
-    public void onQuotaLimitReached(@NonNull String alertName, @NonNull String ifName) { }
-
-    @Override
-    public void onInterfaceDnsServerInfo(@NonNull String ifName, long lifetimeS,
-            @NonNull String[] servers) { }
-
-    @Override
-    public void onInterfaceAddressUpdated(@NonNull String addr, String ifName, int flags,
-            int scope) { }
-
-    @Override
-    public void onInterfaceAddressRemoved(@NonNull String addr, @NonNull String ifName, int flags,
-            int scope) { }
-
-    @Override
-    public void onInterfaceAdded(@NonNull String ifName) { }
-
-    @Override
-    public void onInterfaceRemoved(@NonNull String ifName) { }
-
-    @Override
-    public void onInterfaceChanged(@NonNull String ifName, boolean up) { }
-
-    @Override
-    public void onInterfaceLinkStateChanged(@NonNull String ifName, boolean up) { }
-
-    @Override
-    public void onRouteChanged(boolean updated, @NonNull String route, @NonNull String gateway,
-            @NonNull String ifName) { }
-
-    @Override
-    public void onStrictCleartextDetected(int uid, @NonNull String hex) { }
-
-    @Override
-    public int getInterfaceVersion() {
-        return INetdUnsolicitedEventListener.VERSION;
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return INetdUnsolicitedEventListener.HASH;
-    }
-}
diff --git a/Tethering/src/android/net/util/TetheringUtils.java b/Tethering/src/android/net/util/TetheringUtils.java
index 53b54f7..9e7cc2f 100644
--- a/Tethering/src/android/net/util/TetheringUtils.java
+++ b/Tethering/src/android/net/util/TetheringUtils.java
@@ -21,6 +21,8 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.networkstack.tethering.TetherStatsValue;
+
 import java.io.FileDescriptor;
 import java.net.Inet6Address;
 import java.net.SocketException;
@@ -34,6 +36,10 @@
  * {@hide}
  */
 public class TetheringUtils {
+    static {
+        System.loadLibrary("tetherutilsjni");
+    }
+
     public static final byte[] ALL_NODES = new byte[] {
         (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
     };
@@ -91,6 +97,13 @@
             txPackets = tetherStats.txPackets;
         }
 
+        public ForwardedStats(@NonNull TetherStatsValue tetherStats) {
+            rxBytes = tetherStats.rxBytes;
+            rxPackets = tetherStats.rxPackets;
+            txBytes = tetherStats.txBytes;
+            txPackets = tetherStats.txPackets;
+        }
+
         public ForwardedStats(@NonNull ForwardedStats other) {
             rxBytes = other.rxBytes;
             rxPackets = other.rxPackets;
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 20f30ea..985328f 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -23,25 +23,31 @@
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.NetworkStats.UID_TETHERING;
+import static android.net.ip.ConntrackMonitor.ConntrackEvent;
 import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
+import static android.system.OsConstants.ETH_P_IP;
+import static android.system.OsConstants.ETH_P_IPV6;
 
 import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
 
 import android.app.usage.NetworkStatsManager;
 import android.net.INetd;
+import android.net.LinkProperties;
 import android.net.MacAddress;
 import android.net.NetworkStats;
 import android.net.NetworkStats.Entry;
 import android.net.TetherOffloadRuleParcel;
-import android.net.TetherStatsParcel;
+import android.net.ip.ConntrackMonitor;
+import android.net.ip.ConntrackMonitor.ConntrackEventConsumer;
 import android.net.ip.IpServer;
+import android.net.netlink.NetlinkConstants;
 import android.net.netstats.provider.NetworkStatsProvider;
+import android.net.util.InterfaceParams;
 import android.net.util.SharedLog;
 import android.net.util.TetheringUtils.ForwardedStats;
 import android.os.ConditionVariable;
 import android.os.Handler;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
+import android.system.ErrnoException;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseArray;
@@ -51,13 +57,23 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.modules.utils.build.SdkLevel;
+import com.android.net.module.util.NetworkStackConstants;
+import com.android.net.module.util.Struct;
+import com.android.networkstack.tethering.apishim.common.BpfCoordinatorShim;
 
+import java.net.Inet4Address;
 import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  *  This coordinator is responsible for providing BPF offload relevant functionality.
@@ -69,8 +85,39 @@
  * @hide
  */
 public class BpfCoordinator {
+    // Ensure the JNI code is loaded. In production this will already have been loaded by
+    // TetherService, but for tests it needs to be either loaded here or loaded by every test.
+    // TODO: is there a better way?
+    static {
+        System.loadLibrary("tetherutilsjni");
+    }
+
+    static final boolean DOWNSTREAM = true;
+    static final boolean UPSTREAM = false;
+
     private static final String TAG = BpfCoordinator.class.getSimpleName();
     private static final int DUMP_TIMEOUT_MS = 10_000;
+    private static final MacAddress NULL_MAC_ADDRESS = MacAddress.fromString(
+            "00:00:00:00:00:00");
+    private static final String TETHER_DOWNSTREAM4_MAP_PATH = makeMapPath(DOWNSTREAM, 4);
+    private static final String TETHER_UPSTREAM4_MAP_PATH = makeMapPath(UPSTREAM, 4);
+    private static final String TETHER_DOWNSTREAM6_FS_PATH = makeMapPath(DOWNSTREAM, 6);
+    private static final String TETHER_UPSTREAM6_FS_PATH = makeMapPath(UPSTREAM, 6);
+    private static final String TETHER_STATS_MAP_PATH = makeMapPath("stats");
+    private static final String TETHER_LIMIT_MAP_PATH = makeMapPath("limit");
+    private static final String TETHER_ERROR_MAP_PATH = makeMapPath("error");
+
+    /** The names of all the BPF counters defined in bpf_tethering.h. */
+    public static final String[] sBpfCounterNames = getBpfCounterNames();
+
+    private static String makeMapPath(String which) {
+        return "/sys/fs/bpf/tethering/map_offload_tether_" + which + "_map";
+    }
+
+    private static String makeMapPath(boolean downstream, int ipVersion) {
+        return makeMapPath((downstream ? "downstream" : "upstream") + ipVersion);
+    }
+
 
     @VisibleForTesting
     enum StatsType {
@@ -86,8 +133,12 @@
     private final SharedLog mLog;
     @NonNull
     private final Dependencies mDeps;
+    @NonNull
+    private final ConntrackMonitor mConntrackMonitor;
     @Nullable
     private final BpfTetherStatsProvider mStatsProvider;
+    @NonNull
+    private final BpfCoordinatorShim mBpfCoordinatorShim;
 
     // True if BPF offload is supported, false otherwise. The BPF offload could be disabled by
     // a runtime resource overlay package or device configuration. This flag is only initialized
@@ -146,9 +197,30 @@
     private final HashMap<IpServer, LinkedHashMap<Inet6Address, Ipv6ForwardingRule>>
             mIpv6ForwardingRules = new LinkedHashMap<>();
 
+    // Map of downstream client maps. Each of these maps represents the IPv4 clients for a given
+    // downstream. Needed to build IPv4 forwarding rules when conntrack events are received.
+    // Each map:
+    // - Is owned by the IpServer that is responsible for that downstream.
+    // - Must only be modified by that IpServer.
+    // - Is created when the IpServer adds its first client, and deleted when the IpServer deletes
+    //   its last client.
+    // Note that relying on the client address for finding downstream is okay for now because the
+    // client address is unique. See PrivateAddressCoordinator#requestDownstreamAddress.
+    // TODO: Refactor if any possible that the client address is not unique.
+    private final HashMap<IpServer, HashMap<Inet4Address, ClientInfo>>
+            mTetherClients = new HashMap<>();
+
+    // Set for which downstream is monitoring the conntrack netlink message.
+    private final Set<IpServer> mMonitoringIpServers = new HashSet<>();
+
+    // Map of upstream interface IPv4 address to interface index.
+    // TODO: consider making the key to be unique because the upstream address is not unique. It
+    // is okay for now because there have only one upstream generally.
+    private final HashMap<Inet4Address, Integer> mIpv4UpstreamIndices = new HashMap<>();
+
     // Runnable that used by scheduling next polling of stats.
     private final Runnable mScheduledPollingTask = () -> {
-        updateForwardedStatsFromNetd();
+        updateForwardedStats();
         maybeSchedulePollingStats();
     };
 
@@ -168,6 +240,88 @@
 
         /** Get tethering configuration. */
         @Nullable public abstract TetheringConfiguration getTetherConfig();
+
+        /** Get conntrack monitor. */
+        @NonNull public ConntrackMonitor getConntrackMonitor(ConntrackEventConsumer consumer) {
+            return new ConntrackMonitor(getHandler(), getSharedLog(), consumer);
+        }
+
+        /**
+         * Check OS Build at least S.
+         *
+         * TODO: move to BpfCoordinatorShim once the test doesn't need the mocked OS build for
+         * testing different code flows concurrently.
+         */
+        public boolean isAtLeastS() {
+            // TODO: consider using ShimUtils.isAtLeastS.
+            return SdkLevel.isAtLeastS();
+        }
+
+        /** Get downstream4 BPF map. */
+        @Nullable public BpfMap<Tether4Key, Tether4Value> getBpfDownstream4Map() {
+            try {
+                return new BpfMap<>(TETHER_DOWNSTREAM4_MAP_PATH,
+                    BpfMap.BPF_F_RDWR, Tether4Key.class, Tether4Value.class);
+            } catch (ErrnoException e) {
+                Log.e(TAG, "Cannot create downstream4 map: " + e);
+                return null;
+            }
+        }
+
+        /** Get upstream4 BPF map. */
+        @Nullable public BpfMap<Tether4Key, Tether4Value> getBpfUpstream4Map() {
+            try {
+                return new BpfMap<>(TETHER_UPSTREAM4_MAP_PATH,
+                    BpfMap.BPF_F_RDWR, Tether4Key.class, Tether4Value.class);
+            } catch (ErrnoException e) {
+                Log.e(TAG, "Cannot create upstream4 map: " + e);
+                return null;
+            }
+        }
+
+        /** Get downstream6 BPF map. */
+        @Nullable public BpfMap<TetherDownstream6Key, Tether6Value> getBpfDownstream6Map() {
+            try {
+                return new BpfMap<>(TETHER_DOWNSTREAM6_FS_PATH,
+                    BpfMap.BPF_F_RDWR, TetherDownstream6Key.class, Tether6Value.class);
+            } catch (ErrnoException e) {
+                Log.e(TAG, "Cannot create downstream6 map: " + e);
+                return null;
+            }
+        }
+
+        /** Get upstream6 BPF map. */
+        @Nullable public BpfMap<TetherUpstream6Key, Tether6Value> getBpfUpstream6Map() {
+            try {
+                return new BpfMap<>(TETHER_UPSTREAM6_FS_PATH, BpfMap.BPF_F_RDWR,
+                        TetherUpstream6Key.class, Tether6Value.class);
+            } catch (ErrnoException e) {
+                Log.e(TAG, "Cannot create upstream6 map: " + e);
+                return null;
+            }
+        }
+
+        /** Get stats BPF map. */
+        @Nullable public BpfMap<TetherStatsKey, TetherStatsValue> getBpfStatsMap() {
+            try {
+                return new BpfMap<>(TETHER_STATS_MAP_PATH,
+                    BpfMap.BPF_F_RDWR, TetherStatsKey.class, TetherStatsValue.class);
+            } catch (ErrnoException e) {
+                Log.e(TAG, "Cannot create stats map: " + e);
+                return null;
+            }
+        }
+
+        /** Get limit BPF map. */
+        @Nullable public BpfMap<TetherLimitKey, TetherLimitValue> getBpfLimitMap() {
+            try {
+                return new BpfMap<>(TETHER_LIMIT_MAP_PATH,
+                    BpfMap.BPF_F_RDWR, TetherLimitKey.class, TetherLimitValue.class);
+            } catch (ErrnoException e) {
+                Log.e(TAG, "Cannot create limit map: " + e);
+                return null;
+            }
+        }
     }
 
     @VisibleForTesting
@@ -177,6 +331,7 @@
         mNetd = mDeps.getNetd();
         mLog = mDeps.getSharedLog().forSubComponent(TAG);
         mIsBpfEnabled = isBpfEnabled();
+        mConntrackMonitor = mDeps.getConntrackMonitor(new BpfConntrackEventConsumer());
         BpfTetherStatsProvider provider = new BpfTetherStatsProvider();
         try {
             mDeps.getNetworkStatsManager().registerNetworkStatsProvider(
@@ -188,6 +343,11 @@
             provider = null;
         }
         mStatsProvider = provider;
+
+        mBpfCoordinatorShim = BpfCoordinatorShim.getBpfCoordinatorShim(deps);
+        if (!mBpfCoordinatorShim.isInitialized()) {
+            mLog.e("Bpf shim not initialized");
+        }
     }
 
     /**
@@ -199,8 +359,8 @@
     public void startPolling() {
         if (mPollingStarted) return;
 
-        if (!mIsBpfEnabled) {
-            mLog.i("Offload disabled");
+        if (!isUsingBpf()) {
+            mLog.i("BPF is not using");
             return;
         }
 
@@ -225,12 +385,68 @@
         if (mHandler.hasCallbacks(mScheduledPollingTask)) {
             mHandler.removeCallbacks(mScheduledPollingTask);
         }
-        updateForwardedStatsFromNetd();
+        updateForwardedStats();
         mPollingStarted = false;
 
         mLog.i("Polling stopped");
     }
 
+    private boolean isUsingBpf() {
+        return mIsBpfEnabled && mBpfCoordinatorShim.isInitialized();
+    }
+
+    /**
+     * Start conntrack message monitoring.
+     * Note that this can be only called on handler thread.
+     *
+     * TODO: figure out a better logging for non-interesting conntrack message.
+     * For example, the following logging is an IPCTNL_MSG_CT_GET message but looks scary.
+     * +---------------------------------------------------------------------------+
+     * | ERROR unparsable netlink msg: 1400000001010103000000000000000002000000    |
+     * +------------------+--------------------------------------------------------+
+     * |                  | struct nlmsghdr                                        |
+     * | 14000000         | length = 20                                            |
+     * | 0101             | type = NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_GET  |
+     * | 0103             | flags                                                  |
+     * | 00000000         | seqno = 0                                              |
+     * | 00000000         | pid = 0                                                |
+     * |                  | struct nfgenmsg                                        |
+     * | 02               | nfgen_family  = AF_INET                                |
+     * | 00               | version = NFNETLINK_V0                                 |
+     * | 0000             | res_id                                                 |
+     * +------------------+--------------------------------------------------------+
+     * See NetlinkMonitor#handlePacket, NetlinkMessage#parseNfMessage.
+     */
+    public void startMonitoring(@NonNull final IpServer ipServer) {
+        if (!isUsingBpf()) return;
+
+        if (mMonitoringIpServers.contains(ipServer)) {
+            Log.wtf(TAG, "The same downstream " + ipServer.interfaceName()
+                    + " should not start monitoring twice.");
+            return;
+        }
+
+        if (mMonitoringIpServers.isEmpty()) {
+            mConntrackMonitor.start();
+            mLog.i("Monitoring started");
+        }
+
+        mMonitoringIpServers.add(ipServer);
+    }
+
+    /**
+     * Stop conntrack event monitoring.
+     * Note that this can be only called on handler thread.
+     */
+    public void stopMonitoring(@NonNull final IpServer ipServer) {
+        mMonitoringIpServers.remove(ipServer);
+
+        if (!mMonitoringIpServers.isEmpty()) return;
+
+        mConntrackMonitor.stop();
+        mLog.i("Monitoring stopped");
+    }
+
     /**
      * Add forwarding rule. After adding the first rule on a given upstream, must add the data
      * limit on the given upstream.
@@ -238,15 +454,10 @@
      */
     public void tetherOffloadRuleAdd(
             @NonNull final IpServer ipServer, @NonNull final Ipv6ForwardingRule rule) {
-        if (!mIsBpfEnabled) return;
+        if (!isUsingBpf()) return;
 
-        try {
-            // TODO: Perhaps avoid to add a duplicate rule.
-            mNetd.tetherOffloadRuleAdd(rule.toTetherOffloadRuleParcel());
-        } catch (RemoteException | ServiceSpecificException e) {
-            mLog.e("Could not add IPv6 forwarding rule: ", e);
-            return;
-        }
+        // TODO: Perhaps avoid to add a duplicate rule.
+        if (!mBpfCoordinatorShim.tetherOffloadRuleAdd(rule)) return;
 
         if (!mIpv6ForwardingRules.containsKey(ipServer)) {
             mIpv6ForwardingRules.put(ipServer, new LinkedHashMap<Inet6Address,
@@ -254,7 +465,7 @@
         }
         LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules = mIpv6ForwardingRules.get(ipServer);
 
-        // Setup the data limit on the given upstream if the first rule is added.
+        // When the first rule is added to an upstream, setup upstream forwarding and data limit.
         final int upstreamIfindex = rule.upstreamIfindex;
         if (!isAnyRuleOnUpstream(upstreamIfindex)) {
             // If failed to set a data limit, probably should not use this upstream, because
@@ -265,6 +476,19 @@
                 final String iface = mInterfaceNames.get(upstreamIfindex);
                 mLog.e("Setting data limit for " + iface + " failed.");
             }
+
+        }
+
+        if (!isAnyRuleFromDownstreamToUpstream(rule.downstreamIfindex, rule.upstreamIfindex)) {
+            final int downstream = rule.downstreamIfindex;
+            final int upstream = rule.upstreamIfindex;
+            // TODO: support upstream forwarding on non-point-to-point interfaces.
+            // TODO: get the MTU from LinkProperties and update the rules when it changes.
+            if (!mBpfCoordinatorShim.startUpstreamIpv6Forwarding(downstream, upstream,
+                    NULL_MAC_ADDRESS, NULL_MAC_ADDRESS, NetworkStackConstants.ETHER_MTU)) {
+                mLog.e("Failed to enable upstream IPv6 forwarding from "
+                        + mInterfaceNames.get(downstream) + " to " + mInterfaceNames.get(upstream));
+            }
         }
 
         // Must update the adding rule after calling #isAnyRuleOnUpstream because it needs to
@@ -279,15 +503,9 @@
      */
     public void tetherOffloadRuleRemove(
             @NonNull final IpServer ipServer, @NonNull final Ipv6ForwardingRule rule) {
-        if (!mIsBpfEnabled) return;
+        if (!isUsingBpf()) return;
 
-        try {
-            // TODO: Perhaps avoid to remove a non-existent rule.
-            mNetd.tetherOffloadRuleRemove(rule.toTetherOffloadRuleParcel());
-        } catch (RemoteException | ServiceSpecificException e) {
-            mLog.e("Could not remove IPv6 forwarding rule: ", e);
-            return;
-        }
+        if (!mBpfCoordinatorShim.tetherOffloadRuleRemove(rule)) return;
 
         LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules = mIpv6ForwardingRules.get(ipServer);
         if (rules == null) return;
@@ -303,19 +521,32 @@
             mIpv6ForwardingRules.remove(ipServer);
         }
 
+        // If no more rules between this upstream and downstream, stop upstream forwarding.
+        if (!isAnyRuleFromDownstreamToUpstream(rule.downstreamIfindex, rule.upstreamIfindex)) {
+            final int downstream = rule.downstreamIfindex;
+            final int upstream = rule.upstreamIfindex;
+            if (!mBpfCoordinatorShim.stopUpstreamIpv6Forwarding(downstream, upstream)) {
+                mLog.e("Failed to disable upstream IPv6 forwarding from "
+                        + mInterfaceNames.get(downstream) + " to " + mInterfaceNames.get(upstream));
+            }
+        }
+
         // Do cleanup functionality if there is no more rule on the given upstream.
         final int upstreamIfindex = rule.upstreamIfindex;
         if (!isAnyRuleOnUpstream(upstreamIfindex)) {
-            try {
-                final TetherStatsParcel stats =
-                        mNetd.tetherOffloadGetAndClearStats(upstreamIfindex);
-                // Update the last stats delta and delete the local cache for a given upstream.
-                updateQuotaAndStatsFromSnapshot(new TetherStatsParcel[] {stats});
-                mStats.remove(upstreamIfindex);
-            } catch (RemoteException | ServiceSpecificException e) {
-                Log.wtf(TAG, "Exception when cleanup tether stats for upstream index "
-                        + upstreamIfindex + ": ", e);
+            final TetherStatsValue statsValue =
+                    mBpfCoordinatorShim.tetherOffloadGetAndClearStats(upstreamIfindex);
+            if (statsValue == null) {
+                Log.wtf(TAG, "Fail to cleanup tether stats for upstream index " + upstreamIfindex);
+                return;
             }
+
+            SparseArray<TetherStatsValue> tetherStatsList = new SparseArray<TetherStatsValue>();
+            tetherStatsList.put(upstreamIfindex, statsValue);
+
+            // Update the last stats delta and delete the local cache for a given upstream.
+            updateQuotaAndStatsFromSnapshot(tetherStatsList);
+            mStats.remove(upstreamIfindex);
         }
     }
 
@@ -324,7 +555,7 @@
      * Note that this can be only called on handler thread.
      */
     public void tetherOffloadRuleClear(@NonNull final IpServer ipServer) {
-        if (!mIsBpfEnabled) return;
+        if (!isUsingBpf()) return;
 
         final LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules = mIpv6ForwardingRules.get(
                 ipServer);
@@ -341,19 +572,29 @@
      * Note that this can be only called on handler thread.
      */
     public void tetherOffloadRuleUpdate(@NonNull final IpServer ipServer, int newUpstreamIfindex) {
-        if (!mIsBpfEnabled) return;
+        if (!isUsingBpf()) return;
 
         final LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules = mIpv6ForwardingRules.get(
                 ipServer);
         if (rules == null) return;
 
         // Need to build a rule list because the rule map may be changed in the iteration.
-        for (final Ipv6ForwardingRule rule : new ArrayList<Ipv6ForwardingRule>(rules.values())) {
+        // First remove all the old rules, then add all the new rules. This is because the upstream
+        // forwarding code in tetherOffloadRuleAdd cannot support rules on two upstreams at the
+        // same time. Deleting the rules first ensures that upstream forwarding is disabled on the
+        // old upstream when the last rule is removed from it, and re-enabled on the new upstream
+        // when the first rule is added to it.
+        // TODO: Once the IPv6 client processing code has moved from IpServer to BpfCoordinator, do
+        // something smarter.
+        final ArrayList<Ipv6ForwardingRule> rulesCopy = new ArrayList<>(rules.values());
+        for (final Ipv6ForwardingRule rule : rulesCopy) {
             // Remove the old rule before adding the new one because the map uses the same key for
             // both rules. Reversing the processing order causes that the new rule is removed as
             // unexpected.
             // TODO: Add new rule first to reduce the latency which has no rule.
             tetherOffloadRuleRemove(ipServer, rule);
+        }
+        for (final Ipv6ForwardingRule rule : rulesCopy) {
             tetherOffloadRuleAdd(ipServer, rule.onNewUpstream(newUpstreamIfindex));
         }
     }
@@ -365,7 +606,7 @@
      * Note that this can be only called on handler thread.
      */
     public void addUpstreamNameToLookupTable(int upstreamIfindex, @NonNull String upstreamIface) {
-        if (!mIsBpfEnabled) return;
+        if (!isUsingBpf()) return;
 
         if (upstreamIfindex == 0 || TextUtils.isEmpty(upstreamIface)) return;
 
@@ -382,6 +623,80 @@
     }
 
     /**
+     * Add downstream client.
+     */
+    public void tetherOffloadClientAdd(@NonNull final IpServer ipServer,
+            @NonNull final ClientInfo client) {
+        if (!isUsingBpf()) return;
+
+        if (!mTetherClients.containsKey(ipServer)) {
+            mTetherClients.put(ipServer, new HashMap<Inet4Address, ClientInfo>());
+        }
+
+        HashMap<Inet4Address, ClientInfo> clients = mTetherClients.get(ipServer);
+        clients.put(client.clientAddress, client);
+    }
+
+    /**
+     * Remove downstream client.
+     */
+    public void tetherOffloadClientRemove(@NonNull final IpServer ipServer,
+            @NonNull final ClientInfo client) {
+        if (!isUsingBpf()) return;
+
+        HashMap<Inet4Address, ClientInfo> clients = mTetherClients.get(ipServer);
+        if (clients == null) return;
+
+        // If no rule is removed, return early. Avoid unnecessary work on a non-existent rule
+        // which may have never been added or removed already.
+        if (clients.remove(client.clientAddress) == null) return;
+
+        // Remove the downstream entry if it has no more rule.
+        if (clients.isEmpty()) {
+            mTetherClients.remove(ipServer);
+        }
+    }
+
+    /**
+     * Call when UpstreamNetworkState may be changed.
+     * If upstream has ipv4 for tethering, update this new UpstreamNetworkState to map. The
+     * upstream interface index and its address mapping is prepared for building IPv4
+     * offload rule.
+     *
+     * TODO: Delete the unused upstream interface mapping.
+     * TODO: Support ether ip upstream interface.
+     */
+    public void addUpstreamIfindexToMap(LinkProperties lp) {
+        if (!mPollingStarted) return;
+
+        // This will not work on a network that is using 464xlat because hasIpv4Address will not be
+        // true.
+        // TODO: need to consider 464xlat.
+        if (lp == null || !lp.hasIpv4Address()) return;
+
+        // Support raw ip upstream interface only.
+        final InterfaceParams params = InterfaceParams.getByName(lp.getInterfaceName());
+        if (params == null || params.hasMacAddress) return;
+
+        Collection<InetAddress> addresses = lp.getAddresses();
+        for (InetAddress addr: addresses) {
+            if (addr instanceof Inet4Address) {
+                Inet4Address i4addr = (Inet4Address) addr;
+                if (!i4addr.isAnyLocalAddress() && !i4addr.isLinkLocalAddress()
+                        && !i4addr.isLoopbackAddress() && !i4addr.isMulticastAddress()) {
+                    mIpv4UpstreamIndices.put(i4addr, params.index);
+                }
+            }
+        }
+    }
+
+
+    // TODO: make mInterfaceNames accessible to the shim and move this code to there.
+    private String getIfName(long ifindex) {
+        return mInterfaceNames.get((int) ifindex, Long.toString(ifindex));
+    }
+
+    /**
      * Dump information.
      * Block the function until all the data are dumped on the handler thread or timed-out. The
      * reason is that dumpsys invokes this function on the thread of caller and the data may only
@@ -396,6 +711,7 @@
                     ? "registered" : "not registered"));
             pw.println("Upstream quota: " + mInterfaceQuotas.toString());
             pw.println("Polling interval: " + getPollingInterval() + " ms");
+            pw.println("Bpf shim: " + mBpfCoordinatorShim.toString());
 
             pw.println("Forwarding stats:");
             pw.increaseIndent();
@@ -408,11 +724,15 @@
 
             pw.println("Forwarding rules:");
             pw.increaseIndent();
-            if (mIpv6ForwardingRules.size() == 0) {
-                pw.println("<empty>");
-            } else {
-                dumpIpv6ForwardingRules(pw);
-            }
+            dumpIpv6UpstreamRules(pw);
+            dumpIpv6ForwardingRules(pw);
+            dumpIpv4ForwardingRules(pw);
+            pw.decreaseIndent();
+
+            pw.println();
+            pw.println("Forwarding counters:");
+            pw.increaseIndent();
+            dumpCounters(pw);
             pw.decreaseIndent();
 
             dumpDone.open();
@@ -432,6 +752,11 @@
     }
 
     private void dumpIpv6ForwardingRules(@NonNull IndentingPrintWriter pw) {
+        if (mIpv6ForwardingRules.size() == 0) {
+            pw.println("No IPv6 rules");
+            return;
+        }
+
         for (Map.Entry<IpServer, LinkedHashMap<Inet6Address, Ipv6ForwardingRule>> entry :
                 mIpv6ForwardingRules.entrySet()) {
             IpServer ipServer = entry.getKey();
@@ -452,11 +777,97 @@
         }
     }
 
+    private String ipv6UpstreamRuletoString(TetherUpstream6Key key, Tether6Value value) {
+        return String.format("%d(%s) -> %d(%s) %04x %s %s",
+                key.iif, getIfName(key.iif), value.oif, getIfName(value.oif),
+                value.ethProto, value.ethSrcMac, value.ethDstMac);
+    }
+
+    private void dumpIpv6UpstreamRules(IndentingPrintWriter pw) {
+        try (BpfMap<TetherUpstream6Key, Tether6Value> map = mDeps.getBpfUpstream6Map()) {
+            if (map == null) {
+                pw.println("No IPv6 upstream");
+                return;
+            }
+            if (map.isEmpty()) {
+                pw.println("No IPv6 upstream rules");
+                return;
+            }
+            map.forEach((k, v) -> pw.println(ipv6UpstreamRuletoString(k, v)));
+        } catch (ErrnoException e) {
+            pw.println("Error dumping IPv4 map: " + e);
+        }
+    }
+
+    private String ipv4RuleToString(Tether4Key key, Tether4Value value) {
+        final String private4, public4, dst4;
+        try {
+            private4 = InetAddress.getByAddress(key.src4).getHostAddress();
+            dst4 = InetAddress.getByAddress(key.dst4).getHostAddress();
+            public4 = InetAddress.getByAddress(value.src46).getHostAddress();
+        } catch (UnknownHostException impossible) {
+            throw new AssertionError("4-byte array not valid IPv4 address!");
+        }
+        return String.format("%d(%s) %d(%s) %s:%d -> %s:%d -> %s:%d",
+                key.iif, getIfName(key.iif), value.oif, getIfName(value.oif),
+                private4, key.srcPort, public4, value.srcPort, dst4, key.dstPort);
+    }
+
+    private void dumpIpv4ForwardingRules(IndentingPrintWriter pw) {
+        try (BpfMap<Tether4Key, Tether4Value> map = mDeps.getBpfUpstream4Map()) {
+            if (map == null) {
+                pw.println("No IPv4 support");
+                return;
+            }
+            if (map.isEmpty()) {
+                pw.println("No IPv4 rules");
+                return;
+            }
+            pw.println("[IPv4]: iif(iface) oif(iface) src nat dst");
+            pw.increaseIndent();
+            map.forEach((k, v) -> pw.println(ipv4RuleToString(k, v)));
+        } catch (ErrnoException e) {
+            pw.println("Error dumping IPv4 map: " + e);
+        }
+        pw.decreaseIndent();
+    }
+
+    /**
+     * Simple struct that only contains a u32. Must be public because Struct needs access to it.
+     * TODO: make this a public inner class of Struct so anyone can use it as, e.g., Struct.U32?
+     */
+    public static class U32Struct extends Struct {
+        @Struct.Field(order = 0, type = Struct.Type.U32)
+        public long val;
+    }
+
+    private void dumpCounters(@NonNull IndentingPrintWriter pw) {
+        try (BpfMap<U32Struct, U32Struct> map = new BpfMap<>(TETHER_ERROR_MAP_PATH,
+                BpfMap.BPF_F_RDONLY, U32Struct.class, U32Struct.class)) {
+
+            map.forEach((k, v) -> {
+                String counterName;
+                try {
+                    counterName = sBpfCounterNames[(int) k.val];
+                } catch (IndexOutOfBoundsException e) {
+                    // Should never happen because this code gets the counter name from the same
+                    // include file as the BPF program that increments the counter.
+                    Log.wtf(TAG, "Unknown tethering counter type " + k.val);
+                    counterName = Long.toString(k.val);
+                }
+                if (v.val > 0) pw.println(String.format("%s: %d", counterName, v.val));
+            });
+        } catch (ErrnoException e) {
+            pw.println("Error dumping counter map: " + e);
+        }
+    }
+
     /** IPv6 forwarding rule class. */
     public static class Ipv6ForwardingRule {
         public final int upstreamIfindex;
         public final int downstreamIfindex;
 
+        // TODO: store a ClientInfo object instead of storing address, srcMac, and dstMac directly.
         @NonNull
         public final Inet6Address address;
         @NonNull
@@ -497,6 +908,23 @@
             return parcel;
         }
 
+        /**
+         * Return a TetherDownstream6Key object built from the rule.
+         */
+        @NonNull
+        public TetherDownstream6Key makeTetherDownstream6Key() {
+            return new TetherDownstream6Key(upstreamIfindex, address.getAddress());
+        }
+
+        /**
+         * Return a Tether6Value object built from the rule.
+         */
+        @NonNull
+        public Tether6Value makeTether6Value() {
+            return new Tether6Value(downstreamIfindex, dstMac, srcMac, ETH_P_IPV6,
+                    NetworkStackConstants.ETHER_MTU);
+        }
+
         @Override
         public boolean equals(Object o) {
             if (!(o instanceof Ipv6ForwardingRule)) return false;
@@ -516,6 +944,48 @@
         }
     }
 
+    /** Tethering client information class. */
+    public static class ClientInfo {
+        public final int downstreamIfindex;
+
+        @NonNull
+        public final MacAddress downstreamMac;
+        @NonNull
+        public final Inet4Address clientAddress;
+        @NonNull
+        public final MacAddress clientMac;
+
+        public ClientInfo(int downstreamIfindex,
+                @NonNull MacAddress downstreamMac, @NonNull Inet4Address clientAddress,
+                @NonNull MacAddress clientMac) {
+            this.downstreamIfindex = downstreamIfindex;
+            this.downstreamMac = downstreamMac;
+            this.clientAddress = clientAddress;
+            this.clientMac = clientMac;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof ClientInfo)) return false;
+            ClientInfo that = (ClientInfo) o;
+            return this.downstreamIfindex == that.downstreamIfindex
+                    && Objects.equals(this.downstreamMac, that.downstreamMac)
+                    && Objects.equals(this.clientAddress, that.clientAddress)
+                    && Objects.equals(this.clientMac, that.clientMac);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(downstreamIfindex, downstreamMac, clientAddress, clientMac);
+        }
+
+        @Override
+        public String toString() {
+            return String.format("downstream: %d (%s), client: %s (%s)",
+                    downstreamIfindex, downstreamMac, clientAddress, clientMac);
+        }
+    }
+
     /**
      * A BPF tethering stats provider to provide network statistics to the system.
      * Note that this class' data may only be accessed on the handler thread.
@@ -582,6 +1052,99 @@
         }
     }
 
+    @Nullable
+    private ClientInfo getClientInfo(@NonNull Inet4Address clientAddress) {
+        for (HashMap<Inet4Address, ClientInfo> clients : mTetherClients.values()) {
+            for (ClientInfo client : clients.values()) {
+                if (clientAddress.equals(client.clientAddress)) {
+                    return client;
+                }
+            }
+        }
+        return null;
+    }
+
+    // Support raw ip only.
+    // TODO: add ether ip support.
+    private class BpfConntrackEventConsumer implements ConntrackEventConsumer {
+        @NonNull
+        private Tether4Key makeTetherUpstream4Key(
+                @NonNull ConntrackEvent e, @NonNull ClientInfo c) {
+            return new Tether4Key(c.downstreamIfindex, c.downstreamMac,
+                    e.tupleOrig.protoNum, e.tupleOrig.srcIp.getAddress(),
+                    e.tupleOrig.dstIp.getAddress(), e.tupleOrig.srcPort, e.tupleOrig.dstPort);
+        }
+
+        @NonNull
+        private Tether4Key makeTetherDownstream4Key(
+                @NonNull ConntrackEvent e, @NonNull ClientInfo c, int upstreamIndex) {
+            return new Tether4Key(upstreamIndex, NULL_MAC_ADDRESS /* dstMac (rawip) */,
+                    e.tupleReply.protoNum, e.tupleReply.srcIp.getAddress(),
+                    e.tupleReply.dstIp.getAddress(), e.tupleReply.srcPort, e.tupleReply.dstPort);
+        }
+
+        @NonNull
+        private Tether4Value makeTetherUpstream4Value(@NonNull ConntrackEvent e,
+                int upstreamIndex) {
+            return new Tether4Value(upstreamIndex,
+                    NULL_MAC_ADDRESS /* ethDstMac (rawip) */,
+                    NULL_MAC_ADDRESS /* ethSrcMac (rawip) */, ETH_P_IP,
+                    NetworkStackConstants.ETHER_MTU, toIpv4MappedAddressBytes(e.tupleReply.dstIp),
+                    toIpv4MappedAddressBytes(e.tupleReply.srcIp), e.tupleReply.dstPort,
+                    e.tupleReply.srcPort, 0 /* lastUsed, filled by bpf prog only */);
+        }
+
+        @NonNull
+        private Tether4Value makeTetherDownstream4Value(@NonNull ConntrackEvent e,
+                @NonNull ClientInfo c, int upstreamIndex) {
+            return new Tether4Value(c.downstreamIfindex,
+                    c.clientMac, c.downstreamMac, ETH_P_IP, NetworkStackConstants.ETHER_MTU,
+                    toIpv4MappedAddressBytes(e.tupleOrig.dstIp),
+                    toIpv4MappedAddressBytes(e.tupleOrig.srcIp),
+                    e.tupleOrig.dstPort, e.tupleOrig.srcPort,
+                    0 /* lastUsed, filled by bpf prog only */);
+        }
+
+        @NonNull
+        private byte[] toIpv4MappedAddressBytes(Inet4Address ia4) {
+            final byte[] addr4 = ia4.getAddress();
+            final byte[] addr6 = new byte[16];
+            addr6[10] = (byte) 0xff;
+            addr6[11] = (byte) 0xff;
+            addr6[12] = addr4[0];
+            addr6[13] = addr4[1];
+            addr6[14] = addr4[2];
+            addr6[15] = addr4[3];
+            return addr6;
+        }
+
+        public void accept(ConntrackEvent e) {
+            final ClientInfo tetherClient = getClientInfo(e.tupleOrig.srcIp);
+            if (tetherClient == null) return;
+
+            final Integer upstreamIndex = mIpv4UpstreamIndices.get(e.tupleReply.dstIp);
+            if (upstreamIndex == null) return;
+
+            final Tether4Key upstream4Key = makeTetherUpstream4Key(e, tetherClient);
+            final Tether4Key downstream4Key = makeTetherDownstream4Key(e, tetherClient,
+                    upstreamIndex);
+
+            if (e.msgType == (NetlinkConstants.NFNL_SUBSYS_CTNETLINK << 8
+                    | NetlinkConstants.IPCTNL_MSG_CT_DELETE)) {
+                mBpfCoordinatorShim.tetherOffloadRuleRemove(false, upstream4Key);
+                mBpfCoordinatorShim.tetherOffloadRuleRemove(true, downstream4Key);
+                return;
+            }
+
+            final Tether4Value upstream4Value = makeTetherUpstream4Value(e, upstreamIndex);
+            final Tether4Value downstream4Value = makeTetherDownstream4Value(e, tetherClient,
+                    upstreamIndex);
+
+            mBpfCoordinatorShim.tetherOffloadRuleAdd(false, upstream4Key, upstream4Value);
+            mBpfCoordinatorShim.tetherOffloadRuleAdd(true, downstream4Key, downstream4Value);
+        }
+    }
+
     private boolean isBpfEnabled() {
         final TetheringConfiguration config = mDeps.getTetherConfig();
         return (config != null) ? config.isBpfOffloadEnabled() : true /* default value */;
@@ -607,20 +1170,13 @@
         return quotaBytes;
     }
 
-    private boolean sendDataLimitToNetd(int ifIndex, long quotaBytes) {
+    private boolean sendDataLimitToBpfMap(int ifIndex, long quotaBytes) {
         if (ifIndex == 0) {
             Log.wtf(TAG, "Invalid interface index.");
             return false;
         }
 
-        try {
-            mNetd.tetherOffloadSetInterfaceQuota(ifIndex, quotaBytes);
-        } catch (RemoteException | ServiceSpecificException e) {
-            mLog.e("Exception when updating quota " + quotaBytes + ": ", e);
-            return false;
-        }
-
-        return true;
+        return mBpfCoordinatorShim.tetherOffloadSetInterfaceQuota(ifIndex, quotaBytes);
     }
 
     // Handle the data limit update from the service which is the stats provider registered for.
@@ -633,7 +1189,7 @@
         if (ifIndex == 0) return;
 
         final long quotaBytes = getQuotaBytes(iface);
-        sendDataLimitToNetd(ifIndex, quotaBytes);
+        sendDataLimitToBpfMap(ifIndex, quotaBytes);
     }
 
     // Handle the data limit update while adding forwarding rules.
@@ -644,7 +1200,7 @@
             return false;
         }
         final long quotaBytes = getQuotaBytes(iface);
-        return sendDataLimitToNetd(ifIndex, quotaBytes);
+        return sendDataLimitToBpfMap(ifIndex, quotaBytes);
     }
 
     private boolean isAnyRuleOnUpstream(int upstreamIfindex) {
@@ -657,6 +1213,19 @@
         return false;
     }
 
+    private boolean isAnyRuleFromDownstreamToUpstream(int downstreamIfindex, int upstreamIfindex) {
+        for (LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules : mIpv6ForwardingRules
+                .values()) {
+            for (Ipv6ForwardingRule rule : rules.values()) {
+                if (downstreamIfindex == rule.downstreamIfindex
+                        && upstreamIfindex == rule.upstreamIfindex) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     @NonNull
     private NetworkStats buildNetworkStats(@NonNull StatsType type, int ifIndex,
             @NonNull final ForwardedStats diff) {
@@ -690,10 +1259,11 @@
     }
 
     private void updateQuotaAndStatsFromSnapshot(
-            @NonNull final TetherStatsParcel[] tetherStatsList) {
+            @NonNull final SparseArray<TetherStatsValue> tetherStatsList) {
         long usedAlertQuota = 0;
-        for (TetherStatsParcel tetherStats : tetherStatsList) {
-            final Integer ifIndex = tetherStats.ifIndex;
+        for (int i = 0; i < tetherStatsList.size(); i++) {
+            final Integer ifIndex = tetherStatsList.keyAt(i);
+            final TetherStatsValue tetherStats = tetherStatsList.valueAt(i);
             final ForwardedStats curr = new ForwardedStats(tetherStats);
             final ForwardedStats base = mStats.get(ifIndex);
             final ForwardedStats diff = (base != null) ? curr.subtract(base) : curr;
@@ -725,16 +1295,15 @@
         // TODO: Count the used limit quota for notifying data limit reached.
     }
 
-    private void updateForwardedStatsFromNetd() {
-        final TetherStatsParcel[] tetherStatsList;
-        try {
-            // The reported tether stats are total data usage for all currently-active upstream
-            // interfaces since tethering start.
-            tetherStatsList = mNetd.tetherOffloadGetStats();
-        } catch (RemoteException | ServiceSpecificException e) {
-            mLog.e("Problem fetching tethering stats: ", e);
+    private void updateForwardedStats() {
+        final SparseArray<TetherStatsValue> tetherStatsList =
+                mBpfCoordinatorShim.tetherOffloadGetStats();
+
+        if (tetherStatsList == null) {
+            mLog.e("Problem fetching tethering stats");
             return;
         }
+
         updateQuotaAndStatsFromSnapshot(tetherStatsList);
     }
 
@@ -775,4 +1344,6 @@
     final SparseArray<String> getInterfaceNamesForTesting() {
         return mInterfaceNames;
     }
+
+    private static native String[] getBpfCounterNames();
 }
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfMap.java b/Tethering/src/com/android/networkstack/tethering/BpfMap.java
new file mode 100644
index 0000000..9a9376f
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/BpfMap.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2020 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 com.android.networkstack.tethering;
+
+import static android.system.OsConstants.EEXIST;
+import static android.system.OsConstants.ENOENT;
+
+import android.system.ErrnoException;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.Struct;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.function.BiConsumer;
+
+/**
+ * BpfMap is a key -> value mapping structure that is designed to maintained the bpf map entries.
+ * This is a wrapper class of in-kernel data structure. The in-kernel data can be read/written by
+ * passing syscalls with map file descriptor.
+ *
+ * @param <K> the key of the map.
+ * @param <V> the value of the map.
+ */
+public class BpfMap<K extends Struct, V extends Struct> implements AutoCloseable {
+    static {
+        System.loadLibrary("tetherutilsjni");
+    }
+
+    // Following definitions from kernel include/uapi/linux/bpf.h
+    public static final int BPF_F_RDWR = 0;
+    public static final int BPF_F_RDONLY = 1 << 3;
+    public static final int BPF_F_WRONLY = 1 << 4;
+
+    public static final int BPF_MAP_TYPE_HASH = 1;
+
+    private static final int BPF_F_NO_PREALLOC = 1;
+
+    private static final int BPF_ANY = 0;
+    private static final int BPF_NOEXIST = 1;
+    private static final int BPF_EXIST = 2;
+
+    private final int mMapFd;
+    private final Class<K> mKeyClass;
+    private final Class<V> mValueClass;
+    private final int mKeySize;
+    private final int mValueSize;
+
+    /**
+     * Create a BpfMap map wrapper with "path" of filesystem.
+     *
+     * @param flag the access mode, one of BPF_F_RDWR, BPF_F_RDONLY, or BPF_F_WRONLY.
+     * @throws ErrnoException if the BPF map associated with {@code path} cannot be retrieved.
+     * @throws NullPointerException if {@code path} is null.
+     */
+    public BpfMap(@NonNull final String path, final int flag, final Class<K> key,
+            final Class<V> value) throws ErrnoException, NullPointerException {
+        mMapFd = bpfFdGet(path, flag);
+
+        mKeyClass = key;
+        mValueClass = value;
+        mKeySize = Struct.getSize(key);
+        mValueSize = Struct.getSize(value);
+    }
+
+     /**
+     * Constructor for testing only.
+     * The derived class implements an internal mocked map. It need to implement all functions
+     * which are related with the native BPF map because the BPF map handler is not initialized.
+     * See BpfCoordinatorTest#TestBpfMap.
+     */
+    @VisibleForTesting
+    protected BpfMap(final Class<K> key, final Class<V> value) {
+        mMapFd = -1;
+        mKeyClass = key;
+        mValueClass = value;
+        mKeySize = Struct.getSize(key);
+        mValueSize = Struct.getSize(value);
+    }
+
+    /**
+     * Update an existing or create a new key -> value entry in an eBbpf map.
+     */
+    public void updateEntry(K key, V value) throws ErrnoException {
+        writeToMapEntry(mMapFd, key.writeToBytes(), value.writeToBytes(), BPF_ANY);
+    }
+
+    /**
+     * If the key does not exist in the map, insert key -> value entry into eBpf map.
+     * Otherwise IllegalStateException will be thrown.
+     */
+    public void insertEntry(K key, V value)
+            throws ErrnoException, IllegalStateException {
+        try {
+            writeToMapEntry(mMapFd, key.writeToBytes(), value.writeToBytes(), BPF_NOEXIST);
+        } catch (ErrnoException e) {
+            if (e.errno == EEXIST) throw new IllegalStateException(key + " already exists");
+
+            throw e;
+        }
+    }
+
+    /**
+     * If the key already exists in the map, replace its value. Otherwise NoSuchElementException
+     * will be thrown.
+     */
+    public void replaceEntry(K key, V value)
+            throws ErrnoException, NoSuchElementException {
+        try {
+            writeToMapEntry(mMapFd, key.writeToBytes(), value.writeToBytes(), BPF_EXIST);
+        } catch (ErrnoException e) {
+            if (e.errno == ENOENT) throw new NoSuchElementException(key + " not found");
+
+            throw e;
+        }
+    }
+
+    /** Remove existing key from eBpf map. Return false if map was not modified. */
+    public boolean deleteEntry(K key) throws ErrnoException {
+        return deleteMapEntry(mMapFd, key.writeToBytes());
+    }
+
+    /** Returns {@code true} if this map contains no elements. */
+    public boolean isEmpty() throws ErrnoException {
+        return getFirstKey() == null;
+    }
+
+    private K getNextKeyInternal(@Nullable K key) throws ErrnoException {
+        final byte[] rawKey = getNextRawKey(
+                key == null ? null : key.writeToBytes());
+        if (rawKey == null) return null;
+
+        final ByteBuffer buffer = ByteBuffer.wrap(rawKey);
+        buffer.order(ByteOrder.nativeOrder());
+        return Struct.parse(mKeyClass, buffer);
+    }
+
+    /**
+     * Get the next key of the passed-in key. If the passed-in key is not found, return the first
+     * key. If the passed-in key is the last one, return null.
+     *
+     * TODO: consider allowing null passed-in key.
+     */
+    public K getNextKey(@NonNull K key) throws ErrnoException {
+        Objects.requireNonNull(key);
+        return getNextKeyInternal(key);
+    }
+
+    private byte[] getNextRawKey(@Nullable final byte[] key) throws ErrnoException {
+        byte[] nextKey = new byte[mKeySize];
+        if (getNextMapKey(mMapFd, key, nextKey)) return nextKey;
+
+        return null;
+    }
+
+    /** Get the first key of eBpf map. */
+    public K getFirstKey() throws ErrnoException {
+        return getNextKeyInternal(null);
+    }
+
+    /** Check whether a key exists in the map. */
+    public boolean containsKey(@NonNull K key) throws ErrnoException {
+        Objects.requireNonNull(key);
+
+        final byte[] rawValue = getRawValue(key.writeToBytes());
+        return rawValue != null;
+    }
+
+    /** Retrieve a value from the map. Return null if there is no such key. */
+    public V getValue(@NonNull K key) throws ErrnoException {
+        Objects.requireNonNull(key);
+        final byte[] rawValue = getRawValue(key.writeToBytes());
+
+        if (rawValue == null) return null;
+
+        final ByteBuffer buffer = ByteBuffer.wrap(rawValue);
+        buffer.order(ByteOrder.nativeOrder());
+        return Struct.parse(mValueClass, buffer);
+    }
+
+    private byte[] getRawValue(final byte[] key) throws ErrnoException {
+        byte[] value = new byte[mValueSize];
+        if (findMapEntry(mMapFd, key, value)) return value;
+
+        return null;
+    }
+
+    /**
+     * Iterate through the map and handle each key -> value retrieved base on the given BiConsumer.
+     * The given BiConsumer may to delete the passed-in entry, but is not allowed to perform any
+     * other structural modifications to the map, such as adding entries or deleting other entries.
+     * Otherwise, iteration will result in undefined behaviour.
+     */
+    public void forEach(BiConsumer<K, V> action) throws ErrnoException {
+        @Nullable K nextKey = getFirstKey();
+
+        while (nextKey != null) {
+            @NonNull final K curKey = nextKey;
+            @NonNull final V value = getValue(curKey);
+
+            nextKey = getNextKey(curKey);
+            action.accept(curKey, value);
+        }
+    }
+
+    @Override
+    public void close() throws ErrnoException {
+        closeMap(mMapFd);
+    }
+
+    private static native int closeMap(int fd) throws ErrnoException;
+
+    private native int bpfFdGet(String path, int mode) throws ErrnoException, NullPointerException;
+
+    private native void writeToMapEntry(int fd, byte[] key, byte[] value, int flags)
+            throws ErrnoException;
+
+    private native boolean deleteMapEntry(int fd, byte[] key) throws ErrnoException;
+
+    // If key is found, the operation returns true and the nextKey would reference to the next
+    // element.  If key is not found, the operation returns true and the nextKey would reference to
+    // the first element.  If key is the last element, false is returned.
+    private native boolean getNextMapKey(int fd, byte[] key, byte[] nextKey) throws ErrnoException;
+
+    private native boolean findMapEntry(int fd, byte[] key, byte[] value) throws ErrnoException;
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java b/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
index bb7322f..b1e3cfe 100644
--- a/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
+++ b/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
@@ -418,7 +418,8 @@
             if (period <= 0) return;
 
             Intent intent = new Intent(ACTION_PROVISIONING_ALARM);
-            mProvisioningRecheckAlarm = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+            mProvisioningRecheckAlarm = PendingIntent.getBroadcast(mContext, 0, intent,
+                    PendingIntent.FLAG_IMMUTABLE);
             AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(
                     Context.ALARM_SERVICE);
             long periodMs = period * MS_PER_HOUR;
diff --git a/Tethering/src/com/android/networkstack/tethering/Tether4Key.java b/Tethering/src/com/android/networkstack/tethering/Tether4Key.java
new file mode 100644
index 0000000..a01ea34
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/Tether4Key.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 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 com.android.networkstack.tethering;
+
+import android.net.MacAddress;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet4Address;
+import java.net.UnknownHostException;
+import java.util.Objects;
+
+/** Key type for downstream & upstream IPv4 forwarding maps. */
+public class Tether4Key extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long iif;
+
+    @Field(order = 1, type = Type.EUI48)
+    public final MacAddress dstMac;
+
+    @Field(order = 2, type = Type.U8, padding = 1)
+    public final short l4proto;
+
+    @Field(order = 3, type = Type.ByteArray, arraysize = 4)
+    public final byte[] src4;
+
+    @Field(order = 4, type = Type.ByteArray, arraysize = 4)
+    public final byte[] dst4;
+
+    @Field(order = 5, type = Type.UBE16)
+    public final int srcPort;
+
+    @Field(order = 6, type = Type.UBE16)
+    public final int dstPort;
+
+    public Tether4Key(final long iif, @NonNull final MacAddress dstMac, final short l4proto,
+            final byte[] src4, final byte[] dst4, final int srcPort,
+            final int dstPort) {
+        Objects.requireNonNull(dstMac);
+
+        this.iif = iif;
+        this.dstMac = dstMac;
+        this.l4proto = l4proto;
+        this.src4 = src4;
+        this.dst4 = dst4;
+        this.srcPort = srcPort;
+        this.dstPort = dstPort;
+    }
+
+    @Override
+    public String toString() {
+        try {
+            return String.format(
+                    "iif: %d, dstMac: %s, l4proto: %d, src4: %s, dst4: %s, "
+                            + "srcPort: %d, dstPort: %d",
+                    iif, dstMac, l4proto,
+                    Inet4Address.getByAddress(src4), Inet4Address.getByAddress(dst4),
+                    Short.toUnsignedInt((short) srcPort), Short.toUnsignedInt((short) dstPort));
+        } catch (UnknownHostException | IllegalArgumentException e) {
+            return String.format("Invalid IP address", e);
+        }
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/Tether4Value.java b/Tethering/src/com/android/networkstack/tethering/Tether4Value.java
new file mode 100644
index 0000000..03a226c
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/Tether4Value.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2020 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 com.android.networkstack.tethering;
+
+import android.net.MacAddress;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Objects;
+
+/** Value type for downstream & upstream IPv4 forwarding maps. */
+public class Tether4Value extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long oif;
+
+    // The ethhdr struct which is defined in uapi/linux/if_ether.h
+    @Field(order = 1, type = Type.EUI48)
+    public final MacAddress ethDstMac;
+    @Field(order = 2, type = Type.EUI48)
+    public final MacAddress ethSrcMac;
+    @Field(order = 3, type = Type.UBE16)
+    public final int ethProto;  // Packet type ID field.
+
+    @Field(order = 4, type = Type.U16)
+    public final int pmtu;
+
+    @Field(order = 5, type = Type.ByteArray, arraysize = 16)
+    public final byte[] src46;
+
+    @Field(order = 6, type = Type.ByteArray, arraysize = 16)
+    public final byte[] dst46;
+
+    @Field(order = 7, type = Type.UBE16)
+    public final int srcPort;
+
+    @Field(order = 8, type = Type.UBE16)
+    public final int dstPort;
+
+    // TODO: consider using U64.
+    @Field(order = 9, type = Type.U63)
+    public final long lastUsed;
+
+    public Tether4Value(final long oif, @NonNull final MacAddress ethDstMac,
+            @NonNull final MacAddress ethSrcMac, final int ethProto, final int pmtu,
+            final byte[] src46, final byte[] dst46, final int srcPort,
+            final int dstPort, final long lastUsed) {
+        Objects.requireNonNull(ethDstMac);
+        Objects.requireNonNull(ethSrcMac);
+
+        this.oif = oif;
+        this.ethDstMac = ethDstMac;
+        this.ethSrcMac = ethSrcMac;
+        this.ethProto = ethProto;
+        this.pmtu = pmtu;
+        this.src46 = src46;
+        this.dst46 = dst46;
+        this.srcPort = srcPort;
+        this.dstPort = dstPort;
+        this.lastUsed = lastUsed;
+    }
+
+    @Override
+    public String toString() {
+        try {
+            return String.format(
+                    "oif: %d, ethDstMac: %s, ethSrcMac: %s, ethProto: %d, pmtu: %d, "
+                            + "src46: %s, dst46: %s, srcPort: %d, dstPort: %d, "
+                            + "lastUsed: %d",
+                    oif, ethDstMac, ethSrcMac, ethProto, pmtu,
+                    InetAddress.getByAddress(src46), InetAddress.getByAddress(dst46),
+                    Short.toUnsignedInt((short) srcPort), Short.toUnsignedInt((short) dstPort),
+                    lastUsed);
+        } catch (UnknownHostException | IllegalArgumentException e) {
+            return String.format("Invalid IP address", e);
+        }
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/Tether6Value.java b/Tethering/src/com/android/networkstack/tethering/Tether6Value.java
new file mode 100644
index 0000000..b3107fd
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/Tether6Value.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 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 com.android.networkstack.tethering;
+
+import android.net.MacAddress;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.Struct;
+
+import java.util.Objects;
+
+/** Value type for downstream and upstream IPv6 forwarding maps. */
+public class Tether6Value extends Struct {
+    @Field(order = 0, type = Type.S32)
+    public final int oif; // The output interface index.
+
+    // The ethhdr struct which is defined in uapi/linux/if_ether.h
+    @Field(order = 1, type = Type.EUI48)
+    public final MacAddress ethDstMac; // The destination mac address.
+    @Field(order = 2, type = Type.EUI48)
+    public final MacAddress ethSrcMac; // The source mac address.
+    @Field(order = 3, type = Type.UBE16)
+    public final int ethProto; // Packet type ID field.
+
+    @Field(order = 4, type = Type.U16)
+    public final int pmtu; // The maximum L3 output path/route mtu.
+
+    public Tether6Value(final int oif, @NonNull final MacAddress ethDstMac,
+            @NonNull final MacAddress ethSrcMac, final int ethProto, final int pmtu) {
+        Objects.requireNonNull(ethSrcMac);
+        Objects.requireNonNull(ethDstMac);
+
+        this.oif = oif;
+        this.ethDstMac = ethDstMac;
+        this.ethSrcMac = ethSrcMac;
+        this.ethProto = ethProto;
+        this.pmtu = pmtu;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("oif: %d, dstMac: %s, srcMac: %s, proto: %d, pmtu: %d", oif,
+                ethDstMac, ethSrcMac, ethProto, pmtu);
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherDownstream6Key.java b/Tethering/src/com/android/networkstack/tethering/TetherDownstream6Key.java
new file mode 100644
index 0000000..3860cba
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/TetherDownstream6Key.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 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 com.android.networkstack.tethering;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+/** The key of BpfMap which is used for bpf offload. */
+public class TetherDownstream6Key extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long iif; // The input interface index.
+
+    @Field(order = 1, type = Type.ByteArray, arraysize = 16)
+    public final byte[] neigh6; // The destination IPv6 address.
+
+    public TetherDownstream6Key(final long iif, final byte[] neigh6) {
+        try {
+            final Inet6Address unused = (Inet6Address) InetAddress.getByAddress(neigh6);
+        } catch (ClassCastException | UnknownHostException e) {
+            throw new IllegalArgumentException("Invalid IPv6 address: "
+                    + Arrays.toString(neigh6));
+        }
+        this.iif = iif;
+        this.neigh6 = neigh6;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+
+        if (!(obj instanceof TetherDownstream6Key)) return false;
+
+        final TetherDownstream6Key that = (TetherDownstream6Key) obj;
+
+        return iif == that.iif && Arrays.equals(neigh6, that.neigh6);
+    }
+
+    @Override
+    public int hashCode() {
+        return Long.hashCode(iif) ^ Arrays.hashCode(neigh6);
+    }
+
+    @Override
+    public String toString() {
+        try {
+            return String.format("iif: %d, neigh: %s", iif, Inet6Address.getByAddress(neigh6));
+        } catch (UnknownHostException e) {
+            // Should not happen because construtor already verify neigh6.
+            throw new IllegalStateException("Invalid TetherDownstream6Key");
+        }
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherLimitKey.java b/Tethering/src/com/android/networkstack/tethering/TetherLimitKey.java
new file mode 100644
index 0000000..bc9bb47
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/TetherLimitKey.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020 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 com.android.networkstack.tethering;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/** The key of BpfMap which is used for tethering per-interface limit. */
+public class TetherLimitKey extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long ifindex;  // upstream interface index
+
+    public TetherLimitKey(final long ifindex) {
+        this.ifindex = ifindex;
+    }
+
+    // TODO: remove equals, hashCode and toString once aosp/1536721 is merged.
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+
+        if (!(obj instanceof TetherLimitKey)) return false;
+
+        final TetherLimitKey that = (TetherLimitKey) obj;
+
+        return ifindex == that.ifindex;
+    }
+
+    @Override
+    public int hashCode() {
+        return Long.hashCode(ifindex);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("ifindex: %d", ifindex);
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherLimitValue.java b/Tethering/src/com/android/networkstack/tethering/TetherLimitValue.java
new file mode 100644
index 0000000..ed7e7d4
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/TetherLimitValue.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2020 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 com.android.networkstack.tethering;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/** The value of BpfMap which is used for tethering per-interface limit. */
+public class TetherLimitValue extends Struct {
+    // Use the signed long variable to store the int64 limit on limit BPF map.
+    // S64 is enough for each interface limit even at 5Gbps for ~468 years.
+    // 2^63 / (5 * 1000 * 1000 * 1000) * 8 / 86400 / 365 = 468.
+    // Note that QUOTA_UNLIMITED (-1) indicates there is no limit.
+    @Field(order = 0, type = Type.S64)
+    public final long limit;
+
+    public TetherLimitValue(final long limit) {
+        this.limit = limit;
+    }
+
+    // TODO: remove equals, hashCode and toString once aosp/1536721 is merged.
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+
+        if (!(obj instanceof TetherLimitValue)) return false;
+
+        final TetherLimitValue that = (TetherLimitValue) obj;
+
+        return limit == that.limit;
+    }
+
+    @Override
+    public int hashCode() {
+        return Long.hashCode(limit);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("limit: %d", limit);
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherStatsKey.java b/Tethering/src/com/android/networkstack/tethering/TetherStatsKey.java
new file mode 100644
index 0000000..5442480
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/TetherStatsKey.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020 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 com.android.networkstack.tethering;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/** The key of BpfMap which is used for tethering stats. */
+public class TetherStatsKey extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long ifindex;  // upstream interface index
+
+    public TetherStatsKey(final long ifindex) {
+        this.ifindex = ifindex;
+    }
+
+    // TODO: remove equals, hashCode and toString once aosp/1536721 is merged.
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+
+        if (!(obj instanceof TetherStatsKey)) return false;
+
+        final TetherStatsKey that = (TetherStatsKey) obj;
+
+        return ifindex == that.ifindex;
+    }
+
+    @Override
+    public int hashCode() {
+        return Long.hashCode(ifindex);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("ifindex: %d", ifindex);
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherStatsValue.java b/Tethering/src/com/android/networkstack/tethering/TetherStatsValue.java
new file mode 100644
index 0000000..844d2e8
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/TetherStatsValue.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2020 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 com.android.networkstack.tethering;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/** The key of BpfMap which is used for tethering stats. */
+public class TetherStatsValue extends Struct {
+    // Use the signed long variable to store the uint64 stats from stats BPF map.
+    // U63 is enough for each data element even at 5Gbps for ~468 years.
+    // 2^63 / (5 * 1000 * 1000 * 1000) * 8 / 86400 / 365 = 468.
+    @Field(order = 0, type = Type.U63)
+    public final long rxPackets;
+    @Field(order = 1, type = Type.U63)
+    public final long rxBytes;
+    @Field(order = 2, type = Type.U63)
+    public final long rxErrors;
+    @Field(order = 3, type = Type.U63)
+    public final long txPackets;
+    @Field(order = 4, type = Type.U63)
+    public final long txBytes;
+    @Field(order = 5, type = Type.U63)
+    public final long txErrors;
+
+    public TetherStatsValue(final long rxPackets, final long rxBytes, final long rxErrors,
+            final long txPackets, final long txBytes, final long txErrors) {
+        this.rxPackets = rxPackets;
+        this.rxBytes = rxBytes;
+        this.rxErrors = rxErrors;
+        this.txPackets = txPackets;
+        this.txBytes = txBytes;
+        this.txErrors = txErrors;
+    }
+
+    // TODO: remove equals, hashCode and toString once aosp/1536721 is merged.
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+
+        if (!(obj instanceof TetherStatsValue)) return false;
+
+        final TetherStatsValue that = (TetherStatsValue) obj;
+
+        return rxPackets == that.rxPackets
+                && rxBytes == that.rxBytes
+                && rxErrors == that.rxErrors
+                && txPackets == that.txPackets
+                && txBytes == that.txBytes
+                && txErrors == that.txErrors;
+    }
+
+    @Override
+    public int hashCode() {
+        return Long.hashCode(rxPackets) ^ Long.hashCode(rxBytes) ^ Long.hashCode(rxErrors)
+                ^ Long.hashCode(txPackets) ^ Long.hashCode(txBytes) ^ Long.hashCode(txErrors);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("rxPackets: %s, rxBytes: %s, rxErrors: %s, txPackets: %s, "
+                + "txBytes: %s, txErrors: %s", rxPackets, rxBytes, rxErrors, txPackets,
+                txBytes, txErrors);
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java b/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java
new file mode 100644
index 0000000..c736f2a
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 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 com.android.networkstack.tethering;
+
+import com.android.net.module.util.Struct;
+
+/** Key type for upstream IPv6 forwarding map. */
+public class TetherUpstream6Key extends Struct {
+    @Field(order = 0, type = Type.S32)
+    public final int iif; // The input interface index.
+
+    public TetherUpstream6Key(int iif) {
+        this.iif = iif;
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 62ae88c..ac5857d 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -93,7 +93,6 @@
 import android.net.TetheringRequestParcel;
 import android.net.ip.IpServer;
 import android.net.shared.NetdUtils;
-import android.net.util.BaseNetdUnsolicitedEventListener;
 import android.net.util.InterfaceSet;
 import android.net.util.PrefixUtils;
 import android.net.util.SharedLog;
@@ -132,6 +131,7 @@
 import com.android.internal.util.MessageUtils;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
+import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -1636,6 +1636,13 @@
         protected void handleNewUpstreamNetworkState(UpstreamNetworkState ns) {
             mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
             mOffload.updateUpstreamNetworkState(ns);
+
+            // TODO: Delete all related offload rules which are using this upstream.
+            if (ns != null) {
+                // Add upstream index to the map. The upstream interface index is required while
+                // the conntrack event builds the offload rules.
+                mBpfCoordinator.addUpstreamIfindexToMap(ns.linkProperties);
+            }
         }
 
         private void handleInterfaceServingStateActive(int mode, IpServer who) {
@@ -1682,12 +1689,14 @@
             // If this is a Wi-Fi interface, tell WifiManager of any errors
             // or the inactive serving state.
             if (who.interfaceType() == TETHERING_WIFI) {
-                if (who.lastError() != TETHER_ERROR_NO_ERROR) {
-                    getWifiManager().updateInterfaceIpState(
-                            who.interfaceName(), IFACE_IP_MODE_CONFIGURATION_ERROR);
+                final WifiManager mgr = getWifiManager();
+                final String iface = who.interfaceName();
+                if (mgr == null) {
+                    Log.wtf(TAG, "Skipping WifiManager notification about inactive tethering");
+                } else if (who.lastError() != TETHER_ERROR_NO_ERROR) {
+                    mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_CONFIGURATION_ERROR);
                 } else {
-                    getWifiManager().updateInterfaceIpState(
-                            who.interfaceName(), IFACE_IP_MODE_UNSPECIFIED);
+                    mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_UNSPECIFIED);
                 }
             }
         }
@@ -2218,6 +2227,13 @@
                 && !isProvisioningNeededButUnavailable();
     }
 
+    private void dumpBpf(IndentingPrintWriter pw) {
+        pw.println("BPF offload:");
+        pw.increaseIndent();
+        mBpfCoordinator.dump(pw);
+        pw.decreaseIndent();
+    }
+
     void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) {
         // Binder.java closes the resource for us.
         @SuppressWarnings("resource")
@@ -2228,6 +2244,11 @@
             return;
         }
 
+        if (argsContain(args, "bpf")) {
+            dumpBpf(pw);
+            return;
+        }
+
         pw.println("Tethering:");
         pw.increaseIndent();
 
@@ -2279,10 +2300,7 @@
         mOffloadController.dump(pw);
         pw.decreaseIndent();
 
-        pw.println("BPF offload:");
-        pw.increaseIndent();
-        mBpfCoordinator.dump(pw);
-        pw.decreaseIndent();
+        dumpBpf(pw);
 
         pw.println("Private address coordinator:");
         pw.increaseIndent();
@@ -2405,6 +2423,19 @@
             mLog.log(iface + " is not a tetherable iface, ignoring");
             return;
         }
+
+        final PackageManager pm = mContext.getPackageManager();
+        if ((interfaceType == TETHERING_WIFI || interfaceType == TETHERING_WIGIG)
+                && !pm.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+            mLog.log(iface + " is not tetherable, because WiFi feature is disabled");
+            return;
+        }
+        if (interfaceType == TETHERING_WIFI_P2P
+                && !pm.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)) {
+            mLog.log(iface + " is not tetherable, because WiFi Direct feature is disabled");
+            return;
+        }
+
         maybeTrackNewInterfaceLocked(iface, interfaceType);
     }
 
diff --git a/Tethering/src/com/android/networkstack/tethering/TetheringService.java b/Tethering/src/com/android/networkstack/tethering/TetheringService.java
index 613328d..c69dc49 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetheringService.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetheringService.java
@@ -82,7 +82,6 @@
      */
     @VisibleForTesting
     public Tethering makeTethering(TetheringDependencies deps) {
-        System.loadLibrary("tetherutilsjni");
         return new Tethering(deps);
     }
 
diff --git a/Tethering/tests/Android.bp b/Tethering/tests/Android.bp
index 731144c..8f31c57 100644
--- a/Tethering/tests/Android.bp
+++ b/Tethering/tests/Android.bp
@@ -14,6 +14,10 @@
 // limitations under the License.
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 filegroup {
     name: "TetheringTestsJarJarRules",
     srcs: ["jarjar-rules.txt"],
diff --git a/Tethering/tests/integration/Android.bp b/Tethering/tests/integration/Android.bp
index 42f83bf..f63df2c 100644
--- a/Tethering/tests/integration/Android.bp
+++ b/Tethering/tests/integration/Android.bp
@@ -13,6 +13,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 //
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 java_defaults {
     name: "TetheringIntegrationTestsDefaults",
     srcs: [
@@ -70,6 +74,7 @@
     test_config: "AndroidTest_Coverage.xml",
     defaults: ["libnetworkstackutilsjni_deps"],
     static_libs: [
+        "NetdStaticLibTestsLib",
         "NetworkStaticLibTestsLib",
         "NetworkStackTestsLib",
         "TetheringTestsLib",
@@ -81,6 +86,7 @@
         "libstaticjvmtiagent",
         // For NetworkStackUtils included in NetworkStackBase
         "libnetworkstackutilsjni",
+        "libtetherutilsjni",
     ],
     jarjar_rules: ":TetheringTestsJarJarRules",
     compile_multilib: "both",
diff --git a/Tethering/tests/mts/Android.bp b/Tethering/tests/mts/Android.bp
index f925b0a..20a5f18 100644
--- a/Tethering/tests/mts/Android.bp
+++ b/Tethering/tests/mts/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 android_test {
     // This tests for functionality that is not required for devices that
     // don't use Tethering mainline module.
diff --git a/Tethering/tests/privileged/Android.bp b/Tethering/tests/privileged/Android.bp
index 9217345..75fdd6e 100644
--- a/Tethering/tests/privileged/Android.bp
+++ b/Tethering/tests/privileged/Android.bp
@@ -14,6 +14,10 @@
 // limitations under the License.
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 java_defaults {
     name: "TetheringPrivilegedTestsJniDefaults",
     jni_libs: [
diff --git a/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java b/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
new file mode 100644
index 0000000..cceaa8c
--- /dev/null
+++ b/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2020 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 com.android.networkstack.tethering;
+
+import static android.system.OsConstants.ETH_P_IPV6;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.net.MacAddress;
+import android.os.Build;
+import android.system.ErrnoException;
+import android.system.OsConstants;
+import android.util.ArrayMap;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.InetAddress;
+import java.util.NoSuchElementException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+@RunWith(AndroidJUnit4.class)
+@IgnoreUpTo(Build.VERSION_CODES.R)
+public final class BpfMapTest {
+    // Sync from packages/modules/Connectivity/Tethering/bpf_progs/offload.c.
+    private static final int TEST_MAP_SIZE = 16;
+    private static final String TETHER_DOWNSTREAM6_FS_PATH =
+            "/sys/fs/bpf/tethering/map_test_tether_downstream6_map";
+
+    private ArrayMap<TetherDownstream6Key, Tether6Value> mTestData;
+
+    private BpfMap<TetherDownstream6Key, Tether6Value> mTestMap;
+
+    @BeforeClass
+    public static void setupOnce() {
+        System.loadLibrary("tetherutilsjni");
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mTestData = new ArrayMap<>();
+        mTestData.put(createTetherDownstream6Key(101, "2001:db8::1"),
+                createTether6Value(11, "00:00:00:00:00:0a", "11:11:11:00:00:0b",
+                ETH_P_IPV6, 1280));
+        mTestData.put(createTetherDownstream6Key(102, "2001:db8::2"),
+                createTether6Value(22, "00:00:00:00:00:0c", "22:22:22:00:00:0d",
+                ETH_P_IPV6, 1400));
+        mTestData.put(createTetherDownstream6Key(103, "2001:db8::3"),
+                createTether6Value(33, "00:00:00:00:00:0e", "33:33:33:00:00:0f",
+                ETH_P_IPV6, 1500));
+
+        initTestMap();
+    }
+
+    private void initTestMap() throws Exception {
+        mTestMap = new BpfMap<>(
+                TETHER_DOWNSTREAM6_FS_PATH, BpfMap.BPF_F_RDWR,
+                TetherDownstream6Key.class, Tether6Value.class);
+
+        mTestMap.forEach((key, value) -> {
+            try {
+                assertTrue(mTestMap.deleteEntry(key));
+            } catch (ErrnoException e) {
+                fail("Fail to delete the key " + key + ": " + e);
+            }
+        });
+        assertNull(mTestMap.getFirstKey());
+        assertTrue(mTestMap.isEmpty());
+    }
+
+    private TetherDownstream6Key createTetherDownstream6Key(long iif, String address)
+            throws Exception {
+        final InetAddress ipv6Address = InetAddress.getByName(address);
+
+        return new TetherDownstream6Key(iif, ipv6Address.getAddress());
+    }
+
+    private Tether6Value createTether6Value(int oif, String src, String dst, int proto, int pmtu) {
+        final MacAddress srcMac = MacAddress.fromString(src);
+        final MacAddress dstMac = MacAddress.fromString(dst);
+
+        return new Tether6Value(oif, dstMac, srcMac, proto, pmtu);
+    }
+
+    @Test
+    public void testGetFd() throws Exception {
+        try (BpfMap readOnlyMap = new BpfMap<>(TETHER_DOWNSTREAM6_FS_PATH, BpfMap.BPF_F_RDONLY,
+                TetherDownstream6Key.class, Tether6Value.class)) {
+            assertNotNull(readOnlyMap);
+            try {
+                readOnlyMap.insertEntry(mTestData.keyAt(0), mTestData.valueAt(0));
+                fail("Writing RO map should throw ErrnoException");
+            } catch (ErrnoException expected) {
+                assertEquals(OsConstants.EPERM, expected.errno);
+            }
+        }
+        try (BpfMap writeOnlyMap = new BpfMap<>(TETHER_DOWNSTREAM6_FS_PATH, BpfMap.BPF_F_WRONLY,
+                TetherDownstream6Key.class, Tether6Value.class)) {
+            assertNotNull(writeOnlyMap);
+            try {
+                writeOnlyMap.getFirstKey();
+                fail("Reading WO map should throw ErrnoException");
+            } catch (ErrnoException expected) {
+                assertEquals(OsConstants.EPERM, expected.errno);
+            }
+        }
+        try (BpfMap readWriteMap = new BpfMap<>(TETHER_DOWNSTREAM6_FS_PATH, BpfMap.BPF_F_RDWR,
+                TetherDownstream6Key.class, Tether6Value.class)) {
+            assertNotNull(readWriteMap);
+        }
+    }
+
+    @Test
+    public void testIsEmpty() throws Exception {
+        assertNull(mTestMap.getFirstKey());
+        assertTrue(mTestMap.isEmpty());
+
+        mTestMap.insertEntry(mTestData.keyAt(0), mTestData.valueAt(0));
+        assertFalse(mTestMap.isEmpty());
+
+        mTestMap.deleteEntry((mTestData.keyAt(0)));
+        assertTrue(mTestMap.isEmpty());
+    }
+
+    @Test
+    public void testGetFirstKey() throws Exception {
+        // getFirstKey on an empty map returns null.
+        assertFalse(mTestMap.containsKey(mTestData.keyAt(0)));
+        assertNull(mTestMap.getFirstKey());
+        assertNull(mTestMap.getValue(mTestData.keyAt(0)));
+
+        // getFirstKey on a non-empty map returns the first key.
+        mTestMap.insertEntry(mTestData.keyAt(0), mTestData.valueAt(0));
+        assertEquals(mTestData.keyAt(0), mTestMap.getFirstKey());
+    }
+
+    @Test
+    public void testGetNextKey() throws Exception {
+        // [1] If the passed-in key is not found on empty map, return null.
+        final TetherDownstream6Key nonexistentKey =
+                createTetherDownstream6Key(1234, "2001:db8::10");
+        assertNull(mTestMap.getNextKey(nonexistentKey));
+
+        // [2] If the passed-in key is null on empty map, throw NullPointerException.
+        try {
+            mTestMap.getNextKey(null);
+            fail("Getting next key with null key should throw NullPointerException");
+        } catch (NullPointerException expected) { }
+
+        // The BPF map has one entry now.
+        final ArrayMap<TetherDownstream6Key, Tether6Value> resultMap =
+                new ArrayMap<>();
+        mTestMap.insertEntry(mTestData.keyAt(0), mTestData.valueAt(0));
+        resultMap.put(mTestData.keyAt(0), mTestData.valueAt(0));
+
+        // [3] If the passed-in key is the last key, return null.
+        // Because there is only one entry in the map, the first key equals the last key.
+        final TetherDownstream6Key lastKey = mTestMap.getFirstKey();
+        assertNull(mTestMap.getNextKey(lastKey));
+
+        // The BPF map has two entries now.
+        mTestMap.insertEntry(mTestData.keyAt(1), mTestData.valueAt(1));
+        resultMap.put(mTestData.keyAt(1), mTestData.valueAt(1));
+
+        // [4] If the passed-in key is found, return the next key.
+        TetherDownstream6Key nextKey = mTestMap.getFirstKey();
+        while (nextKey != null) {
+            if (resultMap.remove(nextKey).equals(nextKey)) {
+                fail("Unexpected result: " + nextKey);
+            }
+            nextKey = mTestMap.getNextKey(nextKey);
+        }
+        assertTrue(resultMap.isEmpty());
+
+        // [5] If the passed-in key is not found on non-empty map, return the first key.
+        assertEquals(mTestMap.getFirstKey(), mTestMap.getNextKey(nonexistentKey));
+
+        // [6] If the passed-in key is null on non-empty map, throw NullPointerException.
+        try {
+            mTestMap.getNextKey(null);
+            fail("Getting next key with null key should throw NullPointerException");
+        } catch (NullPointerException expected) { }
+    }
+
+    @Test
+    public void testUpdateBpfMap() throws Exception {
+        final TetherDownstream6Key key = mTestData.keyAt(0);
+        final Tether6Value value = mTestData.valueAt(0);
+        final Tether6Value value2 = mTestData.valueAt(1);
+        assertFalse(mTestMap.deleteEntry(key));
+
+        // updateEntry will create an entry if it does not exist already.
+        mTestMap.updateEntry(key, value);
+        assertTrue(mTestMap.containsKey(key));
+        final Tether6Value result = mTestMap.getValue(key);
+        assertEquals(value, result);
+
+        // updateEntry will update an entry that already exists.
+        mTestMap.updateEntry(key, value2);
+        assertTrue(mTestMap.containsKey(key));
+        final Tether6Value result2 = mTestMap.getValue(key);
+        assertEquals(value2, result2);
+
+        assertTrue(mTestMap.deleteEntry(key));
+        assertFalse(mTestMap.containsKey(key));
+    }
+
+    @Test
+    public void testInsertReplaceEntry() throws Exception {
+        final TetherDownstream6Key key = mTestData.keyAt(0);
+        final Tether6Value value = mTestData.valueAt(0);
+        final Tether6Value value2 = mTestData.valueAt(1);
+
+        try {
+            mTestMap.replaceEntry(key, value);
+            fail("Replacing non-existent key " + key + " should throw NoSuchElementException");
+        } catch (NoSuchElementException expected) { }
+        assertFalse(mTestMap.containsKey(key));
+
+        mTestMap.insertEntry(key, value);
+        assertTrue(mTestMap.containsKey(key));
+        final Tether6Value result = mTestMap.getValue(key);
+        assertEquals(value, result);
+        try {
+            mTestMap.insertEntry(key, value);
+            fail("Inserting existing key " + key + " should throw IllegalStateException");
+        } catch (IllegalStateException expected) { }
+
+        mTestMap.replaceEntry(key, value2);
+        assertTrue(mTestMap.containsKey(key));
+        final Tether6Value result2 = mTestMap.getValue(key);
+        assertEquals(value2, result2);
+    }
+
+    @Test
+    public void testIterateBpfMap() throws Exception {
+        final ArrayMap<TetherDownstream6Key, Tether6Value> resultMap =
+                new ArrayMap<>(mTestData);
+
+        for (int i = 0; i < resultMap.size(); i++) {
+            mTestMap.insertEntry(resultMap.keyAt(i), resultMap.valueAt(i));
+        }
+
+        mTestMap.forEach((key, value) -> {
+            if (!value.equals(resultMap.remove(key))) {
+                fail("Unexpected result: " + key + ", value: " + value);
+            }
+        });
+        assertTrue(resultMap.isEmpty());
+    }
+
+    @Test
+    public void testIterateEmptyMap() throws Exception {
+        // Can't use an int because variables used in a lambda must be final.
+        final AtomicInteger count = new AtomicInteger();
+        mTestMap.forEach((key, value) -> count.incrementAndGet());
+        // Expect that the consumer was never called.
+        assertEquals(0, count.get());
+    }
+
+    @Test
+    public void testIterateDeletion() throws Exception {
+        final ArrayMap<TetherDownstream6Key, Tether6Value> resultMap =
+                new ArrayMap<>(mTestData);
+
+        for (int i = 0; i < resultMap.size(); i++) {
+            mTestMap.insertEntry(resultMap.keyAt(i), resultMap.valueAt(i));
+        }
+
+        // Can't use an int because variables used in a lambda must be final.
+        final AtomicInteger count = new AtomicInteger();
+        mTestMap.forEach((key, value) -> {
+            try {
+                assertTrue(mTestMap.deleteEntry(key));
+            } catch (ErrnoException e) {
+                fail("Fail to delete key " + key + ": " + e);
+            }
+            if (!value.equals(resultMap.remove(key))) {
+                fail("Unexpected result: " + key + ", value: " + value);
+            }
+            count.incrementAndGet();
+        });
+        assertEquals(3, count.get());
+        assertTrue(resultMap.isEmpty());
+        assertNull(mTestMap.getFirstKey());
+    }
+
+    @Test
+    public void testInsertOverflow() throws Exception {
+        final ArrayMap<TetherDownstream6Key, Tether6Value> testData =
+                new ArrayMap<>();
+
+        // Build test data for TEST_MAP_SIZE + 1 entries.
+        for (int i = 1; i <= TEST_MAP_SIZE + 1; i++) {
+            testData.put(createTetherDownstream6Key(i, "2001:db8::1"),
+                    createTether6Value(100, "de:ad:be:ef:00:01", "de:ad:be:ef:00:02",
+                    ETH_P_IPV6, 1500));
+        }
+
+        // Insert #TEST_MAP_SIZE test entries to the map. The map has reached the limit.
+        for (int i = 0; i < TEST_MAP_SIZE; i++) {
+            mTestMap.insertEntry(testData.keyAt(i), testData.valueAt(i));
+        }
+
+        // The map won't allow inserting any more entries.
+        try {
+            mTestMap.insertEntry(testData.keyAt(TEST_MAP_SIZE), testData.valueAt(TEST_MAP_SIZE));
+            fail("Writing too many entries should throw ErrnoException");
+        } catch (ErrnoException expected) {
+            // Expect that can't insert the entry anymore because the number of elements in the
+            // map reached the limit. See man-pages/bpf.
+            assertEquals(OsConstants.E2BIG, expected.errno);
+        }
+    }
+}
diff --git a/Tethering/tests/unit/Android.bp b/Tethering/tests/unit/Android.bp
index 5e4fe52..d469b37 100644
--- a/Tethering/tests/unit/Android.bp
+++ b/Tethering/tests/unit/Android.bp
@@ -15,6 +15,10 @@
 //
 
 // Tests in this folder are included both in unit tests and CTS.
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 java_library {
     name: "TetheringCommonTests",
     srcs: [
@@ -69,6 +73,7 @@
         // For mockito extended
         "libdexmakerjvmtiagent",
         "libstaticjvmtiagent",
+        "libtetherutilsjni",
     ],
 }
 
diff --git a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index 2eb7589..b45db7e 100644
--- a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -36,6 +36,7 @@
 import static android.net.netlink.StructNdMsg.NUD_FAILED;
 import static android.net.netlink.StructNdMsg.NUD_REACHABLE;
 import static android.net.netlink.StructNdMsg.NUD_STALE;
+import static android.system.OsConstants.ETH_P_IPV6;
 
 import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
 
@@ -98,9 +99,20 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.net.module.util.NetworkStackConstants;
 import com.android.networkstack.tethering.BpfCoordinator;
 import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
+import com.android.networkstack.tethering.BpfMap;
 import com.android.networkstack.tethering.PrivateAddressCoordinator;
+import com.android.networkstack.tethering.Tether4Key;
+import com.android.networkstack.tethering.Tether4Value;
+import com.android.networkstack.tethering.Tether6Value;
+import com.android.networkstack.tethering.TetherDownstream6Key;
+import com.android.networkstack.tethering.TetherLimitKey;
+import com.android.networkstack.tethering.TetherLimitValue;
+import com.android.networkstack.tethering.TetherStatsKey;
+import com.android.networkstack.tethering.TetherStatsValue;
+import com.android.networkstack.tethering.TetherUpstream6Key;
 import com.android.networkstack.tethering.TetheringConfiguration;
 import com.android.testutils.DevSdkIgnoreRule;
 import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
@@ -163,6 +175,13 @@
     @Mock private PrivateAddressCoordinator mAddressCoordinator;
     @Mock private NetworkStatsManager mStatsManager;
     @Mock private TetheringConfiguration mTetherConfig;
+    @Mock private ConntrackMonitor mConntrackMonitor;
+    @Mock private BpfMap<Tether4Key, Tether4Value> mBpfDownstream4Map;
+    @Mock private BpfMap<Tether4Key, Tether4Value> mBpfUpstream4Map;
+    @Mock private BpfMap<TetherDownstream6Key, Tether6Value> mBpfDownstream6Map;
+    @Mock private BpfMap<TetherUpstream6Key, Tether6Value> mBpfUpstream6Map;
+    @Mock private BpfMap<TetherStatsKey, TetherStatsValue> mBpfStatsMap;
+    @Mock private BpfMap<TetherLimitKey, TetherLimitValue> mBpfLimitMap;
 
     @Captor private ArgumentCaptor<DhcpServingParamsParcel> mDhcpParamsCaptor;
 
@@ -173,6 +192,7 @@
     private InterfaceConfigurationParcel mInterfaceConfiguration;
     private NeighborEventConsumer mNeighborEventConsumer;
     private BpfCoordinator mBpfCoordinator;
+    private BpfCoordinator.Dependencies mBpfDeps;
 
     private void initStateMachine(int interfaceType) throws Exception {
         initStateMachine(interfaceType, false /* usingLegacyDhcp */, DEFAULT_USING_BPF_OFFLOAD);
@@ -186,9 +206,6 @@
         when(mDependencies.getInterfaceParams(UPSTREAM_IFACE)).thenReturn(UPSTREAM_IFACE_PARAMS);
         when(mDependencies.getInterfaceParams(UPSTREAM_IFACE2)).thenReturn(UPSTREAM_IFACE_PARAMS2);
 
-        when(mDependencies.getIfindex(eq(UPSTREAM_IFACE))).thenReturn(UPSTREAM_IFINDEX);
-        when(mDependencies.getIfindex(eq(UPSTREAM_IFACE2))).thenReturn(UPSTREAM_IFINDEX2);
-
         mInterfaceConfiguration = new InterfaceConfigurationParcel();
         mInterfaceConfiguration.flags = new String[0];
         if (interfaceType == TETHERING_BLUETOOTH) {
@@ -256,8 +273,7 @@
                 mTestAddress);
         when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(true /* default value */);
 
-        mBpfCoordinator = spy(new BpfCoordinator(
-                new BpfCoordinator.Dependencies() {
+        mBpfDeps = new BpfCoordinator.Dependencies() {
                     @NonNull
                     public Handler getHandler() {
                         return new Handler(mLooper.getLooper());
@@ -282,7 +298,44 @@
                     public TetheringConfiguration getTetherConfig() {
                         return mTetherConfig;
                     }
-                }));
+
+                    @NonNull
+                    public ConntrackMonitor getConntrackMonitor(
+                            ConntrackMonitor.ConntrackEventConsumer consumer) {
+                        return mConntrackMonitor;
+                    }
+
+                    @Nullable
+                    public BpfMap<Tether4Key, Tether4Value> getBpfDownstream4Map() {
+                        return mBpfDownstream4Map;
+                    }
+
+                    @Nullable
+                    public BpfMap<Tether4Key, Tether4Value> getBpfUpstream4Map() {
+                        return mBpfUpstream4Map;
+                    }
+
+                    @Nullable
+                    public BpfMap<TetherDownstream6Key, Tether6Value> getBpfDownstream6Map() {
+                        return mBpfDownstream6Map;
+                    }
+
+                    @Nullable
+                    public BpfMap<TetherUpstream6Key, Tether6Value> getBpfUpstream6Map() {
+                        return mBpfUpstream6Map;
+                    }
+
+                    @Nullable
+                    public BpfMap<TetherStatsKey, TetherStatsValue> getBpfStatsMap() {
+                        return mBpfStatsMap;
+                    }
+
+                    @Nullable
+                    public BpfMap<TetherLimitKey, TetherLimitValue> getBpfLimitMap() {
+                        return mBpfLimitMap;
+                    }
+                };
+        mBpfCoordinator = spy(new BpfCoordinator(mBpfDeps));
 
         setUpDhcpServer();
     }
@@ -742,19 +795,128 @@
     }
 
     @NonNull
+    private static TetherDownstream6Key makeDownstream6Key(int upstreamIfindex,
+            @NonNull final InetAddress dst) {
+        return new TetherDownstream6Key(upstreamIfindex, dst.getAddress());
+    }
+
+    @NonNull
+    private static Tether6Value makeDownstream6Value(@NonNull final MacAddress dstMac) {
+        return new Tether6Value(TEST_IFACE_PARAMS.index, dstMac,
+                TEST_IFACE_PARAMS.macAddr, ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
+    }
+
+    private <T> T verifyWithOrder(@Nullable InOrder inOrder, @NonNull T t) {
+        if (inOrder != null) {
+            return inOrder.verify(t);
+        } else {
+            return verify(t);
+        }
+    }
+
+    private void verifyTetherOffloadRuleAdd(@Nullable InOrder inOrder, int upstreamIfindex,
+            @NonNull final InetAddress dst, @NonNull final MacAddress dstMac) throws Exception {
+        if (mBpfDeps.isAtLeastS()) {
+            verifyWithOrder(inOrder, mBpfDownstream6Map).updateEntry(
+                    makeDownstream6Key(upstreamIfindex, dst), makeDownstream6Value(dstMac));
+        } else {
+            verifyWithOrder(inOrder, mNetd).tetherOffloadRuleAdd(matches(upstreamIfindex, dst,
+                    dstMac));
+        }
+    }
+
+    private void verifyNeverTetherOffloadRuleAdd(int upstreamIfindex,
+            @NonNull final InetAddress dst, @NonNull final MacAddress dstMac) throws Exception {
+        if (mBpfDeps.isAtLeastS()) {
+            verify(mBpfDownstream6Map, never()).updateEntry(
+                    makeDownstream6Key(upstreamIfindex, dst),
+                    makeDownstream6Value(dstMac));
+        } else {
+            verify(mNetd, never()).tetherOffloadRuleAdd(matches(upstreamIfindex, dst, dstMac));
+        }
+    }
+
+    private void verifyNeverTetherOffloadRuleAdd() throws Exception {
+        if (mBpfDeps.isAtLeastS()) {
+            verify(mBpfDownstream6Map, never()).updateEntry(any(), any());
+        } else {
+            verify(mNetd, never()).tetherOffloadRuleAdd(any());
+        }
+    }
+
+    private void verifyTetherOffloadRuleRemove(@Nullable InOrder inOrder, int upstreamIfindex,
+            @NonNull final InetAddress dst, @NonNull final MacAddress dstMac) throws Exception {
+        if (mBpfDeps.isAtLeastS()) {
+            verifyWithOrder(inOrder, mBpfDownstream6Map).deleteEntry(makeDownstream6Key(
+                    upstreamIfindex, dst));
+        } else {
+            // |dstMac| is not required for deleting rules. Used bacause tetherOffloadRuleRemove
+            // uses a whole rule to be a argument.
+            // See system/netd/server/TetherController.cpp/TetherController#removeOffloadRule.
+            verifyWithOrder(inOrder, mNetd).tetherOffloadRuleRemove(matches(upstreamIfindex, dst,
+                    dstMac));
+        }
+    }
+
+    private void verifyNeverTetherOffloadRuleRemove() throws Exception {
+        if (mBpfDeps.isAtLeastS()) {
+            verify(mBpfDownstream6Map, never()).deleteEntry(any());
+        } else {
+            verify(mNetd, never()).tetherOffloadRuleRemove(any());
+        }
+    }
+
+    private void verifyStartUpstreamIpv6Forwarding(@Nullable InOrder inOrder, int upstreamIfindex)
+            throws Exception {
+        if (!mBpfDeps.isAtLeastS()) return;
+        final TetherUpstream6Key key = new TetherUpstream6Key(TEST_IFACE_PARAMS.index);
+        final Tether6Value value = new Tether6Value(upstreamIfindex,
+                MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS,
+                ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
+        verifyWithOrder(inOrder, mBpfUpstream6Map).insertEntry(key, value);
+    }
+
+    private void verifyStopUpstreamIpv6Forwarding(@Nullable InOrder inOrder)
+            throws Exception {
+        if (!mBpfDeps.isAtLeastS()) return;
+        final TetherUpstream6Key key = new TetherUpstream6Key(TEST_IFACE_PARAMS.index);
+        verifyWithOrder(inOrder, mBpfUpstream6Map).deleteEntry(key);
+    }
+
+    private void verifyNoUpstreamIpv6ForwardingChange(@Nullable InOrder inOrder) throws Exception {
+        if (!mBpfDeps.isAtLeastS()) return;
+        if (inOrder != null) {
+            inOrder.verify(mBpfUpstream6Map, never()).deleteEntry(any());
+            inOrder.verify(mBpfUpstream6Map, never()).insertEntry(any(), any());
+            inOrder.verify(mBpfUpstream6Map, never()).updateEntry(any(), any());
+        } else {
+            verify(mBpfUpstream6Map, never()).deleteEntry(any());
+            verify(mBpfUpstream6Map, never()).insertEntry(any(), any());
+            verify(mBpfUpstream6Map, never()).updateEntry(any(), any());
+        }
+    }
+
+    @NonNull
     private static TetherStatsParcel buildEmptyTetherStatsParcel(int ifIndex) {
         TetherStatsParcel parcel = new TetherStatsParcel();
         parcel.ifIndex = ifIndex;
         return parcel;
     }
 
-    private void resetNetdAndBpfCoordinator() throws Exception {
-        reset(mNetd, mBpfCoordinator);
+    private void resetNetdBpfMapAndCoordinator() throws Exception {
+        reset(mNetd, mBpfDownstream6Map, mBpfUpstream6Map, mBpfCoordinator);
+        // When the last rule is removed, tetherOffloadGetAndClearStats will log a WTF (and
+        // potentially crash the test) if the stats map is empty.
         when(mNetd.tetherOffloadGetStats()).thenReturn(new TetherStatsParcel[0]);
         when(mNetd.tetherOffloadGetAndClearStats(UPSTREAM_IFINDEX))
                 .thenReturn(buildEmptyTetherStatsParcel(UPSTREAM_IFINDEX));
         when(mNetd.tetherOffloadGetAndClearStats(UPSTREAM_IFINDEX2))
                 .thenReturn(buildEmptyTetherStatsParcel(UPSTREAM_IFINDEX2));
+        // When the last rule is removed, tetherOffloadGetAndClearStats will log a WTF (and
+        // potentially crash the test) if the stats map is empty.
+        final TetherStatsValue allZeros = new TetherStatsValue(0, 0, 0, 0, 0, 0);
+        when(mBpfStatsMap.getValue(new TetherStatsKey(UPSTREAM_IFINDEX))).thenReturn(allZeros);
+        when(mBpfStatsMap.getValue(new TetherStatsKey(UPSTREAM_IFINDEX2))).thenReturn(allZeros);
     }
 
     @Test
@@ -765,7 +927,6 @@
         final int myIfindex = TEST_IFACE_PARAMS.index;
         final int notMyIfindex = myIfindex - 1;
 
-        final MacAddress myMac = TEST_IFACE_PARAMS.macAddr;
         final InetAddress neighA = InetAddresses.parseNumericAddress("2001:db8::1");
         final InetAddress neighB = InetAddresses.parseNumericAddress("2001:db8::2");
         final InetAddress neighLL = InetAddresses.parseNumericAddress("fe80::1");
@@ -774,65 +935,73 @@
         final MacAddress macA = MacAddress.fromString("00:00:00:00:00:0a");
         final MacAddress macB = MacAddress.fromString("11:22:33:00:00:0b");
 
-        resetNetdAndBpfCoordinator();
-        verifyNoMoreInteractions(mBpfCoordinator, mNetd);
+        resetNetdBpfMapAndCoordinator();
+        verifyNoMoreInteractions(mBpfCoordinator, mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
 
         // TODO: Perhaps verify the interaction of tetherOffloadSetInterfaceQuota and
         // tetherOffloadGetAndClearStats in netd while the rules are changed.
 
         // Events on other interfaces are ignored.
         recvNewNeigh(notMyIfindex, neighA, NUD_REACHABLE, macA);
-        verifyNoMoreInteractions(mBpfCoordinator, mNetd);
+        verifyNoMoreInteractions(mBpfCoordinator, mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
 
         // Events on this interface are received and sent to netd.
         recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
         verify(mBpfCoordinator).tetherOffloadRuleAdd(
                 mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighA, macA));
-        verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighA, macA));
-        resetNetdAndBpfCoordinator();
+        verifyTetherOffloadRuleAdd(null, UPSTREAM_IFINDEX, neighA, macA);
+        verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
+        resetNetdBpfMapAndCoordinator();
 
         recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
         verify(mBpfCoordinator).tetherOffloadRuleAdd(
                 mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighB, macB));
-        verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighB, macB));
-        resetNetdAndBpfCoordinator();
+        verifyTetherOffloadRuleAdd(null, UPSTREAM_IFINDEX, neighB, macB);
+        verifyNoUpstreamIpv6ForwardingChange(null);
+        resetNetdBpfMapAndCoordinator();
 
         // Link-local and multicast neighbors are ignored.
         recvNewNeigh(myIfindex, neighLL, NUD_REACHABLE, macA);
-        verifyNoMoreInteractions(mBpfCoordinator, mNetd);
+        verifyNoMoreInteractions(mBpfCoordinator, mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
         recvNewNeigh(myIfindex, neighMC, NUD_REACHABLE, macA);
-        verifyNoMoreInteractions(mBpfCoordinator, mNetd);
+        verifyNoMoreInteractions(mBpfCoordinator, mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
 
         // A neighbor that is no longer valid causes the rule to be removed.
         // NUD_FAILED events do not have a MAC address.
         recvNewNeigh(myIfindex, neighA, NUD_FAILED, null);
         verify(mBpfCoordinator).tetherOffloadRuleRemove(
                 mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighA, macNull));
-        verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighA, macNull));
-        resetNetdAndBpfCoordinator();
+        verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX, neighA, macNull);
+        verifyNoUpstreamIpv6ForwardingChange(null);
+        resetNetdBpfMapAndCoordinator();
 
         // A neighbor that is deleted causes the rule to be removed.
         recvDelNeigh(myIfindex, neighB, NUD_STALE, macB);
         verify(mBpfCoordinator).tetherOffloadRuleRemove(
                 mIpServer,  makeForwardingRule(UPSTREAM_IFINDEX, neighB, macNull));
-        verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighB, macNull));
-        resetNetdAndBpfCoordinator();
+        verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX, neighB, macNull);
+        verifyStopUpstreamIpv6Forwarding(null);
+        resetNetdBpfMapAndCoordinator();
 
         // Upstream changes result in updating the rules.
         recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
+        verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
         recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
-        resetNetdAndBpfCoordinator();
+        resetNetdBpfMapAndCoordinator();
 
-        InOrder inOrder = inOrder(mNetd);
+        InOrder inOrder = inOrder(mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
         LinkProperties lp = new LinkProperties();
         lp.setInterfaceName(UPSTREAM_IFACE2);
         dispatchTetherConnectionChanged(UPSTREAM_IFACE2, lp, -1);
         verify(mBpfCoordinator).tetherOffloadRuleUpdate(mIpServer, UPSTREAM_IFINDEX2);
-        inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighA, macA));
-        inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX2, neighA, macA));
-        inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighB, macB));
-        inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX2, neighB, macB));
-        resetNetdAndBpfCoordinator();
+        verifyTetherOffloadRuleRemove(inOrder, UPSTREAM_IFINDEX, neighA, macA);
+        verifyTetherOffloadRuleRemove(inOrder, UPSTREAM_IFINDEX, neighB, macB);
+        verifyStopUpstreamIpv6Forwarding(inOrder);
+        verifyTetherOffloadRuleAdd(inOrder, UPSTREAM_IFINDEX2, neighA, macA);
+        verifyStartUpstreamIpv6Forwarding(inOrder, UPSTREAM_IFINDEX2);
+        verifyTetherOffloadRuleAdd(inOrder, UPSTREAM_IFINDEX2, neighB, macB);
+        verifyNoUpstreamIpv6ForwardingChange(inOrder);
+        resetNetdBpfMapAndCoordinator();
 
         // When the upstream is lost, rules are removed.
         dispatchTetherConnectionChanged(null, null, 0);
@@ -841,17 +1010,19 @@
         // - processMessage CMD_IPV6_TETHER_UPDATE for the IPv6 upstream is lost.
         // See dispatchTetherConnectionChanged.
         verify(mBpfCoordinator, times(2)).tetherOffloadRuleClear(mIpServer);
-        verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX2, neighA, macA));
-        verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX2, neighB, macB));
-        resetNetdAndBpfCoordinator();
+        verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX2, neighA, macA);
+        verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX2, neighB, macB);
+        verifyStopUpstreamIpv6Forwarding(inOrder);
+        resetNetdBpfMapAndCoordinator();
 
         // If the upstream is IPv4-only, no rules are added.
         dispatchTetherConnectionChanged(UPSTREAM_IFACE);
-        resetNetdAndBpfCoordinator();
+        resetNetdBpfMapAndCoordinator();
         recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
         // Clear function is called by #updateIpv6ForwardingRules for the IPv6 upstream is lost.
         verify(mBpfCoordinator).tetherOffloadRuleClear(mIpServer);
-        verifyNoMoreInteractions(mBpfCoordinator, mNetd);
+        verifyNoUpstreamIpv6ForwardingChange(null);
+        verifyNoMoreInteractions(mBpfCoordinator, mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
 
         // Rules can be added again once upstream IPv6 connectivity is available.
         lp.setInterfaceName(UPSTREAM_IFACE);
@@ -859,16 +1030,18 @@
         recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
         verify(mBpfCoordinator).tetherOffloadRuleAdd(
                 mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighB, macB));
-        verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighB, macB));
+        verifyTetherOffloadRuleAdd(null, UPSTREAM_IFINDEX, neighB, macB);
+        verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
         verify(mBpfCoordinator, never()).tetherOffloadRuleAdd(
                 mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighA, macA));
-        verify(mNetd, never()).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighA, macA));
+        verifyNeverTetherOffloadRuleAdd(UPSTREAM_IFINDEX, neighA, macA);
 
         // If upstream IPv6 connectivity is lost, rules are removed.
-        resetNetdAndBpfCoordinator();
+        resetNetdBpfMapAndCoordinator();
         dispatchTetherConnectionChanged(UPSTREAM_IFACE, null, 0);
         verify(mBpfCoordinator).tetherOffloadRuleClear(mIpServer);
-        verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighB, macB));
+        verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX, neighB, macB);
+        verifyStopUpstreamIpv6Forwarding(null);
 
         // When the interface goes down, rules are removed.
         lp.setInterfaceName(UPSTREAM_IFACE);
@@ -877,19 +1050,21 @@
         recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
         verify(mBpfCoordinator).tetherOffloadRuleAdd(
                 mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighA, macA));
-        verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighA, macA));
+        verifyTetherOffloadRuleAdd(null, UPSTREAM_IFINDEX, neighA, macA);
+        verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
         verify(mBpfCoordinator).tetherOffloadRuleAdd(
                 mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighB, macB));
-        verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighB, macB));
-        resetNetdAndBpfCoordinator();
+        verifyTetherOffloadRuleAdd(null, UPSTREAM_IFINDEX, neighB, macB);
+        resetNetdBpfMapAndCoordinator();
 
         mIpServer.stop();
         mLooper.dispatchAll();
         verify(mBpfCoordinator).tetherOffloadRuleClear(mIpServer);
-        verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighA, macA));
-        verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighB, macB));
+        verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX, neighA, macA);
+        verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX, neighB, macB);
+        verifyStopUpstreamIpv6Forwarding(null);
         verify(mIpNeighborMonitor).stop();
-        resetNetdAndBpfCoordinator();
+        resetNetdBpfMapAndCoordinator();
     }
 
     @Test
@@ -910,35 +1085,39 @@
         // A neighbor that is added or deleted causes the rule to be added or removed.
         initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */,
                 true /* usingBpfOffload */);
-        resetNetdAndBpfCoordinator();
+        resetNetdBpfMapAndCoordinator();
 
         recvNewNeigh(myIfindex, neigh, NUD_REACHABLE, macA);
         verify(mBpfCoordinator).tetherOffloadRuleAdd(
                 mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neigh, macA));
-        verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neigh, macA));
-        resetNetdAndBpfCoordinator();
+        verifyTetherOffloadRuleAdd(null, UPSTREAM_IFINDEX, neigh, macA);
+        verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
+        resetNetdBpfMapAndCoordinator();
 
         recvDelNeigh(myIfindex, neigh, NUD_STALE, macA);
         verify(mBpfCoordinator).tetherOffloadRuleRemove(
                 mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neigh, macNull));
-        verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neigh, macNull));
-        resetNetdAndBpfCoordinator();
+        verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX, neigh, macNull);
+        verifyStopUpstreamIpv6Forwarding(null);
+        resetNetdBpfMapAndCoordinator();
 
         // [2] Disable BPF offload.
         // A neighbor that is added or deleted doesn’t cause the rule to be added or removed.
         initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */,
                 false /* usingBpfOffload */);
-        resetNetdAndBpfCoordinator();
+        resetNetdBpfMapAndCoordinator();
 
         recvNewNeigh(myIfindex, neigh, NUD_REACHABLE, macA);
         verify(mBpfCoordinator, never()).tetherOffloadRuleAdd(any(), any());
-        verify(mNetd, never()).tetherOffloadRuleAdd(any());
-        resetNetdAndBpfCoordinator();
+        verifyNeverTetherOffloadRuleAdd();
+        verifyNoUpstreamIpv6ForwardingChange(null);
+        resetNetdBpfMapAndCoordinator();
 
         recvDelNeigh(myIfindex, neigh, NUD_STALE, macA);
         verify(mBpfCoordinator, never()).tetherOffloadRuleRemove(any(), any());
-        verify(mNetd, never()).tetherOffloadRuleRemove(any());
-        resetNetdAndBpfCoordinator();
+        verifyNeverTetherOffloadRuleRemove();
+        verifyNoUpstreamIpv6ForwardingChange(null);
+        resetNetdBpfMapAndCoordinator();
     }
 
     @Test
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
index 64242ae..1270e50 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -24,6 +24,7 @@
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.NetworkStats.UID_TETHERING;
 import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
+import static android.system.OsConstants.ETH_P_IPV6;
 
 import static com.android.networkstack.tethering.BpfCoordinator.StatsType;
 import static com.android.networkstack.tethering.BpfCoordinator.StatsType.STATS_PER_IFACE;
@@ -33,6 +34,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
@@ -40,8 +42,10 @@
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.argThat;
 import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -52,17 +56,24 @@
 import android.net.NetworkStats;
 import android.net.TetherOffloadRuleParcel;
 import android.net.TetherStatsParcel;
+import android.net.ip.ConntrackMonitor;
+import android.net.ip.ConntrackMonitor.ConntrackEventConsumer;
 import android.net.ip.IpServer;
 import android.net.util.SharedLog;
+import android.os.Build;
 import android.os.Handler;
 import android.os.test.TestLooper;
+import android.system.ErrnoException;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.net.module.util.NetworkStackConstants;
+import com.android.net.module.util.Struct;
 import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
 import com.android.testutils.TestableNetworkStatsProviderCbBinder;
 
 import org.junit.Before;
@@ -78,7 +89,10 @@
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.BiConsumer;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
@@ -90,10 +104,64 @@
     private static final MacAddress MAC_A = MacAddress.fromString("00:00:00:00:00:0a");
     private static final MacAddress MAC_B = MacAddress.fromString("11:22:33:00:00:0b");
 
+    // The test fake BPF map class is needed because the test has no privilege to access the BPF
+    // map. All member functions which eventually call JNI to access the real native BPF map need
+    // to be overridden.
+    // TODO: consider moving to an individual file.
+    private class TestBpfMap<K extends Struct, V extends Struct> extends BpfMap<K, V> {
+        private final HashMap<K, V> mMap = new HashMap<K, V>();
+
+        TestBpfMap(final Class<K> key, final Class<V> value) {
+            super(key, value);
+        }
+
+        @Override
+        public void forEach(BiConsumer<K, V> action) throws ErrnoException {
+            // TODO: consider using mocked #getFirstKey and #getNextKey to iterate. It helps to
+            // implement the entry deletion in the iteration if required.
+            for (Map.Entry<K, V> entry : mMap.entrySet()) {
+                action.accept(entry.getKey(), entry.getValue());
+            }
+        }
+
+        @Override
+        public void updateEntry(K key, V value) throws ErrnoException {
+            mMap.put(key, value);
+        }
+
+        @Override
+        public void insertEntry(K key, V value) throws ErrnoException,
+                IllegalArgumentException {
+            // The entry is created if and only if it doesn't exist. See BpfMap#insertEntry.
+            if (mMap.get(key) != null) {
+                throw new IllegalArgumentException(key + " already exist");
+            }
+            mMap.put(key, value);
+        }
+
+        @Override
+        public boolean deleteEntry(Struct key) throws ErrnoException {
+            return mMap.remove(key) != null;
+        }
+
+        @Override
+        public V getValue(@NonNull K key) throws ErrnoException {
+            // Return value for a given key. Otherwise, return null without an error ENOENT.
+            // BpfMap#getValue treats that the entry is not found as no error.
+            return mMap.get(key);
+        }
+    };
+
     @Mock private NetworkStatsManager mStatsManager;
     @Mock private INetd mNetd;
     @Mock private IpServer mIpServer;
+    @Mock private IpServer mIpServer2;
     @Mock private TetheringConfiguration mTetherConfig;
+    @Mock private ConntrackMonitor mConntrackMonitor;
+    @Mock private BpfMap<Tether4Key, Tether4Value> mBpfDownstream4Map;
+    @Mock private BpfMap<Tether4Key, Tether4Value> mBpfUpstream4Map;
+    @Mock private BpfMap<TetherDownstream6Key, Tether6Value> mBpfDownstream6Map;
+    @Mock private BpfMap<TetherUpstream6Key, Tether6Value> mBpfUpstream6Map;
 
     // Late init since methods must be called by the thread that created this object.
     private TestableNetworkStatsProviderCbBinder mTetherStatsProviderCb;
@@ -101,33 +169,72 @@
     private final ArgumentCaptor<ArrayList> mStringArrayCaptor =
             ArgumentCaptor.forClass(ArrayList.class);
     private final TestLooper mTestLooper = new TestLooper();
+    private final TestBpfMap<TetherStatsKey, TetherStatsValue> mBpfStatsMap =
+            spy(new TestBpfMap<>(TetherStatsKey.class, TetherStatsValue.class));
+    private final TestBpfMap<TetherLimitKey, TetherLimitValue> mBpfLimitMap =
+            spy(new TestBpfMap<>(TetherLimitKey.class, TetherLimitValue.class));
     private BpfCoordinator.Dependencies mDeps =
-            new BpfCoordinator.Dependencies() {
-            @NonNull
-            public Handler getHandler() {
-                return new Handler(mTestLooper.getLooper());
-            }
+            spy(new BpfCoordinator.Dependencies() {
+                    @NonNull
+                    public Handler getHandler() {
+                        return new Handler(mTestLooper.getLooper());
+                    }
 
-            @NonNull
-            public INetd getNetd() {
-                return mNetd;
-            }
+                    @NonNull
+                    public INetd getNetd() {
+                        return mNetd;
+                    }
 
-            @NonNull
-            public NetworkStatsManager getNetworkStatsManager() {
-                return mStatsManager;
-            }
+                    @NonNull
+                    public NetworkStatsManager getNetworkStatsManager() {
+                        return mStatsManager;
+                    }
 
-            @NonNull
-            public SharedLog getSharedLog() {
-                return new SharedLog("test");
-            }
+                    @NonNull
+                    public SharedLog getSharedLog() {
+                        return new SharedLog("test");
+                    }
 
-            @Nullable
-            public TetheringConfiguration getTetherConfig() {
-                return mTetherConfig;
-            }
-    };
+                    @Nullable
+                    public TetheringConfiguration getTetherConfig() {
+                        return mTetherConfig;
+                    }
+
+                    @NonNull
+                    public ConntrackMonitor getConntrackMonitor(ConntrackEventConsumer consumer) {
+                        return mConntrackMonitor;
+                    }
+
+                    @Nullable
+                    public BpfMap<Tether4Key, Tether4Value> getBpfDownstream4Map() {
+                        return mBpfDownstream4Map;
+                    }
+
+                    @Nullable
+                    public BpfMap<Tether4Key, Tether4Value> getBpfUpstream4Map() {
+                        return mBpfUpstream4Map;
+                    }
+
+                    @Nullable
+                    public BpfMap<TetherDownstream6Key, Tether6Value> getBpfDownstream6Map() {
+                        return mBpfDownstream6Map;
+                    }
+
+                    @Nullable
+                    public BpfMap<TetherUpstream6Key, Tether6Value> getBpfUpstream6Map() {
+                        return mBpfUpstream6Map;
+                    }
+
+                    @Nullable
+                    public BpfMap<TetherStatsKey, TetherStatsValue> getBpfStatsMap() {
+                        return mBpfStatsMap;
+                    }
+
+                    @Nullable
+                    public BpfMap<TetherLimitKey, TetherLimitValue> getBpfLimitMap() {
+                        return mBpfLimitMap;
+                    }
+            });
 
     @Before public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -177,14 +284,279 @@
         return parcel;
     }
 
-    // Set up specific tether stats list and wait for the stats cache is updated by polling thread
+    // Update a stats entry or create if not exists.
+    private void updateStatsEntryToStatsMap(@NonNull TetherStatsParcel stats) throws Exception {
+        final TetherStatsKey key = new TetherStatsKey(stats.ifIndex);
+        final TetherStatsValue value = new TetherStatsValue(stats.rxPackets, stats.rxBytes,
+                0L /* rxErrors */, stats.txPackets, stats.txBytes, 0L /* txErrors */);
+        mBpfStatsMap.updateEntry(key, value);
+    }
+
+    private void updateStatsEntry(@NonNull TetherStatsParcel stats) throws Exception {
+        if (mDeps.isAtLeastS()) {
+            updateStatsEntryToStatsMap(stats);
+        } else {
+            when(mNetd.tetherOffloadGetStats()).thenReturn(new TetherStatsParcel[] {stats});
+        }
+    }
+
+    // Update specific tether stats list and wait for the stats cache is updated by polling thread
     // in the coordinator. Beware of that it is only used for the default polling interval.
-    private void setTetherOffloadStatsList(TetherStatsParcel[] tetherStatsList) throws Exception {
-        when(mNetd.tetherOffloadGetStats()).thenReturn(tetherStatsList);
+    // Note that the mocked tetherOffloadGetStats of netd replaces all stats entries because it
+    // doesn't store the previous entries.
+    private void updateStatsEntriesAndWaitForUpdate(@NonNull TetherStatsParcel[] tetherStatsList)
+            throws Exception {
+        if (mDeps.isAtLeastS()) {
+            for (TetherStatsParcel stats : tetherStatsList) {
+                updateStatsEntry(stats);
+            }
+        } else {
+            when(mNetd.tetherOffloadGetStats()).thenReturn(tetherStatsList);
+        }
+
         mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
         waitForIdle();
     }
 
+    // In tests, the stats need to be set before deleting the last rule.
+    // The reason is that BpfCoordinator#tetherOffloadRuleRemove reads the stats
+    // of the deleting interface after the last rule deleted. #tetherOffloadRuleRemove
+    // does the interface cleanup failed if there is no stats for the deleting interface.
+    // Note that the mocked tetherOffloadGetAndClearStats of netd replaces all stats entries
+    // because it doesn't store the previous entries.
+    private void updateStatsEntryForTetherOffloadGetAndClearStats(TetherStatsParcel stats)
+            throws Exception {
+        if (mDeps.isAtLeastS()) {
+            updateStatsEntryToStatsMap(stats);
+        } else {
+            when(mNetd.tetherOffloadGetAndClearStats(stats.ifIndex)).thenReturn(stats);
+        }
+    }
+
+    private void clearStatsInvocations() {
+        if (mDeps.isAtLeastS()) {
+            clearInvocations(mBpfStatsMap);
+        } else {
+            clearInvocations(mNetd);
+        }
+    }
+
+    private <T> T verifyWithOrder(@Nullable InOrder inOrder, @NonNull T t) {
+        if (inOrder != null) {
+            return inOrder.verify(t);
+        } else {
+            return verify(t);
+        }
+    }
+
+    private void verifyTetherOffloadGetStats() throws Exception {
+        if (mDeps.isAtLeastS()) {
+            verify(mBpfStatsMap).forEach(any());
+        } else {
+            verify(mNetd).tetherOffloadGetStats();
+        }
+    }
+
+    private void verifyNeverTetherOffloadGetStats() throws Exception {
+        if (mDeps.isAtLeastS()) {
+            verify(mBpfStatsMap, never()).forEach(any());
+        } else {
+            verify(mNetd, never()).tetherOffloadGetStats();
+        }
+    }
+
+    private void verifyStartUpstreamIpv6Forwarding(@Nullable InOrder inOrder, int downstreamIfIndex,
+            int upstreamIfindex) throws Exception {
+        if (!mDeps.isAtLeastS()) return;
+        final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex);
+        final Tether6Value value = new Tether6Value(upstreamIfindex,
+                MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS,
+                ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
+        verifyWithOrder(inOrder, mBpfUpstream6Map).insertEntry(key, value);
+    }
+
+    private void verifyStopUpstreamIpv6Forwarding(@Nullable InOrder inOrder, int downstreamIfIndex)
+            throws Exception {
+        if (!mDeps.isAtLeastS()) return;
+        final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex);
+        verifyWithOrder(inOrder, mBpfUpstream6Map).deleteEntry(key);
+    }
+
+    private void verifyNoUpstreamIpv6ForwardingChange(@Nullable InOrder inOrder) throws Exception {
+        if (!mDeps.isAtLeastS()) return;
+        if (inOrder != null) {
+            inOrder.verify(mBpfUpstream6Map, never()).deleteEntry(any());
+            inOrder.verify(mBpfUpstream6Map, never()).insertEntry(any(), any());
+            inOrder.verify(mBpfUpstream6Map, never()).updateEntry(any(), any());
+        } else {
+            verify(mBpfUpstream6Map, never()).deleteEntry(any());
+            verify(mBpfUpstream6Map, never()).insertEntry(any(), any());
+            verify(mBpfUpstream6Map, never()).updateEntry(any(), any());
+        }
+    }
+
+    private void verifyTetherOffloadRuleAdd(@Nullable InOrder inOrder,
+            @NonNull Ipv6ForwardingRule rule) throws Exception {
+        if (mDeps.isAtLeastS()) {
+            verifyWithOrder(inOrder, mBpfDownstream6Map).updateEntry(
+                    rule.makeTetherDownstream6Key(), rule.makeTether6Value());
+        } else {
+            verifyWithOrder(inOrder, mNetd).tetherOffloadRuleAdd(matches(rule));
+        }
+    }
+
+    private void verifyNeverTetherOffloadRuleAdd() throws Exception {
+        if (mDeps.isAtLeastS()) {
+            verify(mBpfDownstream6Map, never()).updateEntry(any(), any());
+        } else {
+            verify(mNetd, never()).tetherOffloadRuleAdd(any());
+        }
+    }
+
+    private void verifyTetherOffloadRuleRemove(@Nullable InOrder inOrder,
+            @NonNull final Ipv6ForwardingRule rule) throws Exception {
+        if (mDeps.isAtLeastS()) {
+            verifyWithOrder(inOrder, mBpfDownstream6Map).deleteEntry(
+                    rule.makeTetherDownstream6Key());
+        } else {
+            verifyWithOrder(inOrder, mNetd).tetherOffloadRuleRemove(matches(rule));
+        }
+    }
+
+    private void verifyNeverTetherOffloadRuleRemove() throws Exception {
+        if (mDeps.isAtLeastS()) {
+            verify(mBpfDownstream6Map, never()).deleteEntry(any());
+        } else {
+            verify(mNetd, never()).tetherOffloadRuleRemove(any());
+        }
+    }
+
+    private void verifyTetherOffloadSetInterfaceQuota(@Nullable InOrder inOrder, int ifIndex,
+            long quotaBytes, boolean isInit) throws Exception {
+        if (mDeps.isAtLeastS()) {
+            final TetherStatsKey key = new TetherStatsKey(ifIndex);
+            verifyWithOrder(inOrder, mBpfStatsMap).getValue(key);
+            if (isInit) {
+                verifyWithOrder(inOrder, mBpfStatsMap).insertEntry(key, new TetherStatsValue(
+                        0L /* rxPackets */, 0L /* rxBytes */, 0L /* rxErrors */,
+                        0L /* txPackets */, 0L /* txBytes */, 0L /* txErrors */));
+            }
+            verifyWithOrder(inOrder, mBpfLimitMap).updateEntry(new TetherLimitKey(ifIndex),
+                    new TetherLimitValue(quotaBytes));
+        } else {
+            verifyWithOrder(inOrder, mNetd).tetherOffloadSetInterfaceQuota(ifIndex, quotaBytes);
+        }
+    }
+
+    private void verifyNeverTetherOffloadSetInterfaceQuota(@Nullable InOrder inOrder)
+            throws Exception {
+        if (mDeps.isAtLeastS()) {
+            inOrder.verify(mBpfStatsMap, never()).getValue(any());
+            inOrder.verify(mBpfStatsMap, never()).insertEntry(any(), any());
+            inOrder.verify(mBpfLimitMap, never()).updateEntry(any(), any());
+        } else {
+            inOrder.verify(mNetd, never()).tetherOffloadSetInterfaceQuota(anyInt(), anyLong());
+        }
+    }
+
+    private void verifyTetherOffloadGetAndClearStats(@Nullable InOrder inOrder, int ifIndex)
+            throws Exception {
+        if (mDeps.isAtLeastS()) {
+            inOrder.verify(mBpfStatsMap).getValue(new TetherStatsKey(ifIndex));
+            inOrder.verify(mBpfStatsMap).deleteEntry(new TetherStatsKey(ifIndex));
+            inOrder.verify(mBpfLimitMap).deleteEntry(new TetherLimitKey(ifIndex));
+        } else {
+            inOrder.verify(mNetd).tetherOffloadGetAndClearStats(ifIndex);
+        }
+    }
+
+    // S+ and R api minimum tests.
+    // The following tests are used to provide minimum checking for the APIs on different flow.
+    // The auto merge is not enabled on mainline prod. The code flow R may be verified at the
+    // late stage by manual cherry pick. It is risky if the R code flow has broken and be found at
+    // the last minute.
+    // TODO: remove once presubmit tests on R even the code is submitted on S.
+    private void checkTetherOffloadRuleAddAndRemove(boolean usingApiS) throws Exception {
+        setupFunctioningNetdInterface();
+
+        // Replace Dependencies#isAtLeastS() for testing R and S+ BPF map apis. Note that |mDeps|
+        // must be mocked before calling #makeBpfCoordinator which use |mDeps| to initialize the
+        // coordinator.
+        doReturn(usingApiS).when(mDeps).isAtLeastS();
+        final BpfCoordinator coordinator = makeBpfCoordinator();
+
+        final String mobileIface = "rmnet_data0";
+        final Integer mobileIfIndex = 100;
+        coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
+
+        // InOrder is required because mBpfStatsMap may be accessed by both
+        // BpfCoordinator#tetherOffloadRuleAdd and BpfCoordinator#tetherOffloadGetAndClearStats.
+        // The #verifyTetherOffloadGetAndClearStats can't distinguish who has ever called
+        // mBpfStatsMap#getValue and get a wrong calling count which counts all.
+        final InOrder inOrder = inOrder(mNetd, mBpfDownstream6Map, mBpfLimitMap, mBpfStatsMap);
+        final Ipv6ForwardingRule rule = buildTestForwardingRule(mobileIfIndex, NEIGH_A, MAC_A);
+        coordinator.tetherOffloadRuleAdd(mIpServer, rule);
+        verifyTetherOffloadRuleAdd(inOrder, rule);
+        verifyTetherOffloadSetInterfaceQuota(inOrder, mobileIfIndex, QUOTA_UNLIMITED,
+                true /* isInit */);
+
+        // Removing the last rule on current upstream immediately sends the cleanup stuff to netd.
+        updateStatsEntryForTetherOffloadGetAndClearStats(
+                buildTestTetherStatsParcel(mobileIfIndex, 0, 0, 0, 0));
+        coordinator.tetherOffloadRuleRemove(mIpServer, rule);
+        verifyTetherOffloadRuleRemove(inOrder, rule);
+        verifyTetherOffloadGetAndClearStats(inOrder, mobileIfIndex);
+    }
+
+    // TODO: remove once presubmit tests on R even the code is submitted on S.
+    @Test
+    public void testTetherOffloadRuleAddAndRemoveSdkR() throws Exception {
+        checkTetherOffloadRuleAddAndRemove(false /* R */);
+    }
+
+    // TODO: remove once presubmit tests on R even the code is submitted on S.
+    @Test
+    public void testTetherOffloadRuleAddAndRemoveAtLeastSdkS() throws Exception {
+        checkTetherOffloadRuleAddAndRemove(true /* S+ */);
+    }
+
+    // TODO: remove once presubmit tests on R even the code is submitted on S.
+    private void checkTetherOffloadGetStats(boolean usingApiS) throws Exception {
+        setupFunctioningNetdInterface();
+
+        doReturn(usingApiS).when(mDeps).isAtLeastS();
+        final BpfCoordinator coordinator = makeBpfCoordinator();
+        coordinator.startPolling();
+
+        final String mobileIface = "rmnet_data0";
+        final Integer mobileIfIndex = 100;
+        coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
+
+        updateStatsEntriesAndWaitForUpdate(new TetherStatsParcel[] {
+                buildTestTetherStatsParcel(mobileIfIndex, 1000, 100, 2000, 200)});
+
+        final NetworkStats expectedIfaceStats = new NetworkStats(0L, 1)
+                .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 1000, 100, 2000, 200));
+
+        final NetworkStats expectedUidStats = new NetworkStats(0L, 1)
+                .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 1000, 100, 2000, 200));
+
+        mTetherStatsProvider.pushTetherStats();
+        mTetherStatsProviderCb.expectNotifyStatsUpdated(expectedIfaceStats, expectedUidStats);
+    }
+
+    // TODO: remove once presubmit tests on R even the code is submitted on S.
+    @Test
+    public void testTetherOffloadGetStatsSdkR() throws Exception {
+        checkTetherOffloadGetStats(false /* R */);
+    }
+
+    // TODO: remove once presubmit tests on R even the code is submitted on S.
+    @Test
+    public void testTetherOffloadGetStatsAtLeastSdkS() throws Exception {
+        checkTetherOffloadGetStats(true /* S+ */);
+    }
+
     @Test
     public void testGetForwardedStats() throws Exception {
         setupFunctioningNetdInterface();
@@ -205,7 +577,7 @@
         // [1] Both interface stats are changed.
         // Setup the tether stats of wlan and mobile interface. Note that move forward the time of
         // the looper to make sure the new tether stats has been updated by polling update thread.
-        setTetherOffloadStatsList(new TetherStatsParcel[] {
+        updateStatsEntriesAndWaitForUpdate(new TetherStatsParcel[] {
                 buildTestTetherStatsParcel(wlanIfIndex, 1000, 100, 2000, 200),
                 buildTestTetherStatsParcel(mobileIfIndex, 3000, 300, 4000, 400)});
 
@@ -226,7 +598,7 @@
         // [2] Only one interface stats is changed.
         // The tether stats of mobile interface is accumulated and The tether stats of wlan
         // interface is the same.
-        setTetherOffloadStatsList(new TetherStatsParcel[] {
+        updateStatsEntriesAndWaitForUpdate(new TetherStatsParcel[] {
                 buildTestTetherStatsParcel(wlanIfIndex, 1000, 100, 2000, 200),
                 buildTestTetherStatsParcel(mobileIfIndex, 3010, 320, 4030, 440)});
 
@@ -247,12 +619,12 @@
         // Shutdown the coordinator and clear the invocation history, especially the
         // tetherOffloadGetStats() calls.
         coordinator.stopPolling();
-        clearInvocations(mNetd);
+        clearStatsInvocations();
 
         // Verify the polling update thread stopped.
         mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
         waitForIdle();
-        verify(mNetd, never()).tetherOffloadGetStats();
+        verifyNeverTetherOffloadGetStats();
     }
 
     @Test
@@ -272,16 +644,14 @@
         mTetherStatsProviderCb.expectNotifyAlertReached();
 
         // Verify that notifyAlertReached never fired if quota is not yet reached.
-        when(mNetd.tetherOffloadGetStats()).thenReturn(
-                new TetherStatsParcel[] {buildTestTetherStatsParcel(mobileIfIndex, 0, 0, 0, 0)});
+        updateStatsEntry(buildTestTetherStatsParcel(mobileIfIndex, 0, 0, 0, 0));
         mTetherStatsProvider.onSetAlert(100);
         mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
         waitForIdle();
         mTetherStatsProviderCb.assertNoCallback();
 
         // Verify that notifyAlertReached fired when quota is reached.
-        when(mNetd.tetherOffloadGetStats()).thenReturn(
-                new TetherStatsParcel[] {buildTestTetherStatsParcel(mobileIfIndex, 50, 0, 50, 0)});
+        updateStatsEntry(buildTestTetherStatsParcel(mobileIfIndex, 50, 0, 50, 0));
         mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
         waitForIdle();
         mTetherStatsProviderCb.expectNotifyAlertReached();
@@ -339,6 +709,33 @@
     }
 
     @Test
+    public void testRuleMakeTetherDownstream6Key() throws Exception {
+        final Integer mobileIfIndex = 100;
+        final Ipv6ForwardingRule rule = buildTestForwardingRule(mobileIfIndex, NEIGH_A, MAC_A);
+
+        final TetherDownstream6Key key = rule.makeTetherDownstream6Key();
+        assertEquals(key.iif, (long) mobileIfIndex);
+        assertTrue(Arrays.equals(key.neigh6, NEIGH_A.getAddress()));
+        // iif (4) + neigh6 (16) = 20.
+        assertEquals(20, key.writeToBytes().length);
+    }
+
+    @Test
+    public void testRuleMakeTether6Value() throws Exception {
+        final Integer mobileIfIndex = 100;
+        final Ipv6ForwardingRule rule = buildTestForwardingRule(mobileIfIndex, NEIGH_A, MAC_A);
+
+        final Tether6Value value = rule.makeTether6Value();
+        assertEquals(value.oif, DOWNSTREAM_IFINDEX);
+        assertEquals(value.ethDstMac, MAC_A);
+        assertEquals(value.ethSrcMac, DOWNSTREAM_MAC);
+        assertEquals(value.ethProto, ETH_P_IPV6);
+        assertEquals(value.pmtu, NetworkStackConstants.ETHER_MTU);
+        // oif (4) + ethDstMac (6) + ethSrcMac (6) + ethProto (2) + pmtu (2) = 20.
+        assertEquals(20, value.writeToBytes().length);
+    }
+
+    @Test
     public void testSetDataLimit() throws Exception {
         setupFunctioningNetdInterface();
 
@@ -352,10 +749,11 @@
         // Set the unlimited quota as default if the service has never applied a data limit for a
         // given upstream. Note that the data limit only be applied on an upstream which has rules.
         final Ipv6ForwardingRule rule = buildTestForwardingRule(mobileIfIndex, NEIGH_A, MAC_A);
-        final InOrder inOrder = inOrder(mNetd);
+        final InOrder inOrder = inOrder(mNetd, mBpfDownstream6Map, mBpfLimitMap, mBpfStatsMap);
         coordinator.tetherOffloadRuleAdd(mIpServer, rule);
-        inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(rule));
-        inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(mobileIfIndex, QUOTA_UNLIMITED);
+        verifyTetherOffloadRuleAdd(inOrder, rule);
+        verifyTetherOffloadSetInterfaceQuota(inOrder, mobileIfIndex, QUOTA_UNLIMITED,
+                true /* isInit */);
         inOrder.verifyNoMoreInteractions();
 
         // [2] Specific limit.
@@ -363,7 +761,8 @@
         for (final long quota : new long[] {0, 1048576000, Long.MAX_VALUE, QUOTA_UNLIMITED}) {
             mTetherStatsProvider.onSetLimit(mobileIface, quota);
             waitForIdle();
-            inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(mobileIfIndex, quota);
+            verifyTetherOffloadSetInterfaceQuota(inOrder, mobileIfIndex, quota,
+                    false /* isInit */);
             inOrder.verifyNoMoreInteractions();
         }
 
@@ -393,35 +792,35 @@
         // Applying a data limit to the current upstream does not take any immediate action.
         // The data limit could be only set on an upstream which has rules.
         final long limit = 12345;
-        final InOrder inOrder = inOrder(mNetd);
+        final InOrder inOrder = inOrder(mNetd, mBpfDownstream6Map, mBpfLimitMap, mBpfStatsMap);
         mTetherStatsProvider.onSetLimit(mobileIface, limit);
         waitForIdle();
-        inOrder.verify(mNetd, never()).tetherOffloadSetInterfaceQuota(anyInt(), anyLong());
+        verifyNeverTetherOffloadSetInterfaceQuota(inOrder);
 
         // Adding the first rule on current upstream immediately sends the quota to netd.
         final Ipv6ForwardingRule ruleA = buildTestForwardingRule(mobileIfIndex, NEIGH_A, MAC_A);
         coordinator.tetherOffloadRuleAdd(mIpServer, ruleA);
-        inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(ruleA));
-        inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(mobileIfIndex, limit);
+        verifyTetherOffloadRuleAdd(inOrder, ruleA);
+        verifyTetherOffloadSetInterfaceQuota(inOrder, mobileIfIndex, limit, true /* isInit */);
         inOrder.verifyNoMoreInteractions();
 
         // Adding the second rule on current upstream does not send the quota to netd.
         final Ipv6ForwardingRule ruleB = buildTestForwardingRule(mobileIfIndex, NEIGH_B, MAC_B);
         coordinator.tetherOffloadRuleAdd(mIpServer, ruleB);
-        inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(ruleB));
-        inOrder.verify(mNetd, never()).tetherOffloadSetInterfaceQuota(anyInt(), anyLong());
+        verifyTetherOffloadRuleAdd(inOrder, ruleB);
+        verifyNeverTetherOffloadSetInterfaceQuota(inOrder);
 
         // Removing the second rule on current upstream does not send the quota to netd.
         coordinator.tetherOffloadRuleRemove(mIpServer, ruleB);
-        inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(ruleB));
-        inOrder.verify(mNetd, never()).tetherOffloadSetInterfaceQuota(anyInt(), anyLong());
+        verifyTetherOffloadRuleRemove(inOrder, ruleB);
+        verifyNeverTetherOffloadSetInterfaceQuota(inOrder);
 
         // Removing the last rule on current upstream immediately sends the cleanup stuff to netd.
-        when(mNetd.tetherOffloadGetAndClearStats(mobileIfIndex))
-                .thenReturn(buildTestTetherStatsParcel(mobileIfIndex, 0, 0, 0, 0));
+        updateStatsEntryForTetherOffloadGetAndClearStats(
+                buildTestTetherStatsParcel(mobileIfIndex, 0, 0, 0, 0));
         coordinator.tetherOffloadRuleRemove(mIpServer, ruleA);
-        inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(ruleA));
-        inOrder.verify(mNetd).tetherOffloadGetAndClearStats(mobileIfIndex);
+        verifyTetherOffloadRuleRemove(inOrder, ruleA);
+        verifyTetherOffloadGetAndClearStats(inOrder, mobileIfIndex);
         inOrder.verifyNoMoreInteractions();
     }
 
@@ -438,7 +837,8 @@
         coordinator.addUpstreamNameToLookupTable(ethIfIndex, ethIface);
         coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
 
-        final InOrder inOrder = inOrder(mNetd);
+        final InOrder inOrder = inOrder(mNetd, mBpfDownstream6Map, mBpfUpstream6Map, mBpfLimitMap,
+                mBpfStatsMap);
 
         // Before the rule test, here are the additional actions while the rules are changed.
         // - After adding the first rule on a given upstream, the coordinator adds a data limit.
@@ -455,37 +855,42 @@
                 ethIfIndex, NEIGH_B, MAC_B);
 
         coordinator.tetherOffloadRuleAdd(mIpServer, ethernetRuleA);
-        inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(ethernetRuleA));
-        inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(ethIfIndex, QUOTA_UNLIMITED);
-
+        verifyTetherOffloadRuleAdd(inOrder, ethernetRuleA);
+        verifyTetherOffloadSetInterfaceQuota(inOrder, ethIfIndex, QUOTA_UNLIMITED,
+                true /* isInit */);
+        verifyStartUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX, ethIfIndex);
         coordinator.tetherOffloadRuleAdd(mIpServer, ethernetRuleB);
-        inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(ethernetRuleB));
+        verifyTetherOffloadRuleAdd(inOrder, ethernetRuleB);
 
         // [2] Update the existing rules from Ethernet to cellular.
         final Ipv6ForwardingRule mobileRuleA = buildTestForwardingRule(
                 mobileIfIndex, NEIGH_A, MAC_A);
         final Ipv6ForwardingRule mobileRuleB = buildTestForwardingRule(
                 mobileIfIndex, NEIGH_B, MAC_B);
-        when(mNetd.tetherOffloadGetAndClearStats(ethIfIndex))
-                .thenReturn(buildTestTetherStatsParcel(ethIfIndex, 10, 20, 30, 40));
+        updateStatsEntryForTetherOffloadGetAndClearStats(
+                buildTestTetherStatsParcel(ethIfIndex, 10, 20, 30, 40));
 
         // Update the existing rules for upstream changes. The rules are removed and re-added one
         // by one for updating upstream interface index by #tetherOffloadRuleUpdate.
         coordinator.tetherOffloadRuleUpdate(mIpServer, mobileIfIndex);
-        inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(ethernetRuleA));
-        inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(mobileRuleA));
-        inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(mobileIfIndex, QUOTA_UNLIMITED);
-        inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(ethernetRuleB));
-        inOrder.verify(mNetd).tetherOffloadGetAndClearStats(ethIfIndex);
-        inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(mobileRuleB));
+        verifyTetherOffloadRuleRemove(inOrder, ethernetRuleA);
+        verifyTetherOffloadRuleRemove(inOrder, ethernetRuleB);
+        verifyStopUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX);
+        verifyTetherOffloadGetAndClearStats(inOrder, ethIfIndex);
+        verifyTetherOffloadRuleAdd(inOrder, mobileRuleA);
+        verifyTetherOffloadSetInterfaceQuota(inOrder, mobileIfIndex, QUOTA_UNLIMITED,
+                true /* isInit */);
+        verifyStartUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX, mobileIfIndex);
+        verifyTetherOffloadRuleAdd(inOrder, mobileRuleB);
 
         // [3] Clear all rules for a given IpServer.
-        when(mNetd.tetherOffloadGetAndClearStats(mobileIfIndex))
-                .thenReturn(buildTestTetherStatsParcel(mobileIfIndex, 50, 60, 70, 80));
+        updateStatsEntryForTetherOffloadGetAndClearStats(
+                buildTestTetherStatsParcel(mobileIfIndex, 50, 60, 70, 80));
         coordinator.tetherOffloadRuleClear(mIpServer);
-        inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(mobileRuleA));
-        inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(mobileRuleB));
-        inOrder.verify(mNetd).tetherOffloadGetAndClearStats(mobileIfIndex);
+        verifyTetherOffloadRuleRemove(inOrder, mobileRuleA);
+        verifyTetherOffloadRuleRemove(inOrder, mobileRuleB);
+        verifyStopUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX);
+        verifyTetherOffloadGetAndClearStats(inOrder, mobileIfIndex);
 
         // [4] Force pushing stats update to verify that the last diff of stats is reported on all
         // upstreams.
@@ -499,18 +904,17 @@
                 .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 50, 60, 70, 80)));
     }
 
-    @Test
-    public void testTetheringConfigDisable() throws Exception {
-        setupFunctioningNetdInterface();
-        when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(false);
-
+    private void checkBpfDisabled() throws Exception {
+        // The caller may mock the global dependencies |mDeps| which is used in
+        // #makeBpfCoordinator for testing.
+        // See #testBpfDisabledbyNoBpfDownstream6Map.
         final BpfCoordinator coordinator = makeBpfCoordinator();
         coordinator.startPolling();
 
         // The tether stats polling task should not be scheduled.
         mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
         waitForIdle();
-        verify(mNetd, never()).tetherOffloadGetStats();
+        verifyNeverTetherOffloadGetStats();
 
         // The interface name lookup table can't be added.
         final String iface = "rmnet_data0";
@@ -523,7 +927,7 @@
         final MacAddress mac = MacAddress.fromString("00:00:00:00:00:0a");
         final Ipv6ForwardingRule rule = buildTestForwardingRule(ifIndex, neigh, mac);
         coordinator.tetherOffloadRuleAdd(mIpServer, rule);
-        verify(mNetd, never()).tetherOffloadRuleAdd(any());
+        verifyNeverTetherOffloadRuleAdd();
         LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules =
                 coordinator.getForwardingRulesForTesting().get(mIpServer);
         assertNull(rules);
@@ -535,28 +939,72 @@
         rules.put(rule.address, rule);
         coordinator.getForwardingRulesForTesting().put(mIpServer, rules);
         coordinator.tetherOffloadRuleRemove(mIpServer, rule);
-        verify(mNetd, never()).tetherOffloadRuleRemove(any());
+        verifyNeverTetherOffloadRuleRemove();
         rules = coordinator.getForwardingRulesForTesting().get(mIpServer);
         assertNotNull(rules);
         assertEquals(1, rules.size());
 
         // The rule can't be cleared.
         coordinator.tetherOffloadRuleClear(mIpServer);
-        verify(mNetd, never()).tetherOffloadRuleRemove(any());
+        verifyNeverTetherOffloadRuleRemove();
         rules = coordinator.getForwardingRulesForTesting().get(mIpServer);
         assertNotNull(rules);
         assertEquals(1, rules.size());
 
         // The rule can't be updated.
         coordinator.tetherOffloadRuleUpdate(mIpServer, rule.upstreamIfindex + 1 /* new */);
-        verify(mNetd, never()).tetherOffloadRuleRemove(any());
-        verify(mNetd, never()).tetherOffloadRuleAdd(any());
+        verifyNeverTetherOffloadRuleRemove();
+        verifyNeverTetherOffloadRuleAdd();
         rules = coordinator.getForwardingRulesForTesting().get(mIpServer);
         assertNotNull(rules);
         assertEquals(1, rules.size());
     }
 
     @Test
+    public void testBpfDisabledbyConfig() throws Exception {
+        setupFunctioningNetdInterface();
+        when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(false);
+
+        checkBpfDisabled();
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.R)
+    public void testBpfDisabledbyNoBpfDownstream6Map() throws Exception {
+        setupFunctioningNetdInterface();
+        doReturn(null).when(mDeps).getBpfDownstream6Map();
+
+        checkBpfDisabled();
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.R)
+    public void testBpfDisabledbyNoBpfUpstream6Map() throws Exception {
+        setupFunctioningNetdInterface();
+        doReturn(null).when(mDeps).getBpfUpstream6Map();
+
+        checkBpfDisabled();
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.R)
+    public void testBpfDisabledbyNoBpfStatsMap() throws Exception {
+        setupFunctioningNetdInterface();
+        doReturn(null).when(mDeps).getBpfStatsMap();
+
+        checkBpfDisabled();
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.R)
+    public void testBpfDisabledbyNoBpfLimitMap() throws Exception {
+        setupFunctioningNetdInterface();
+        doReturn(null).when(mDeps).getBpfLimitMap();
+
+        checkBpfDisabled();
+    }
+
+    @Test
     public void testTetheringConfigSetPollingInterval() throws Exception {
         setupFunctioningNetdInterface();
 
@@ -590,18 +1038,62 @@
         // Start on a new polling time slot.
         mTestLooper.moveTimeForward(pollingInterval);
         waitForIdle();
-        clearInvocations(mNetd);
+        clearStatsInvocations();
 
         // Move time forward to 90% polling interval time. Expect that the polling thread has not
         // scheduled yet.
         mTestLooper.moveTimeForward((long) (pollingInterval * 0.9));
         waitForIdle();
-        verify(mNetd, never()).tetherOffloadGetStats();
+        verifyNeverTetherOffloadGetStats();
 
         // Move time forward to the remaining 10% polling interval time. Expect that the polling
         // thread has scheduled.
         mTestLooper.moveTimeForward((long) (pollingInterval * 0.1));
         waitForIdle();
-        verify(mNetd).tetherOffloadGetStats();
+        verifyTetherOffloadGetStats();
+    }
+
+    @Test
+    public void testStartStopConntrackMonitoring() throws Exception {
+        setupFunctioningNetdInterface();
+
+        final BpfCoordinator coordinator = makeBpfCoordinator();
+
+        // [1] Don't stop monitoring if it has never started.
+        coordinator.stopMonitoring(mIpServer);
+        verify(mConntrackMonitor, never()).start();
+
+        // [2] Start monitoring.
+        coordinator.startMonitoring(mIpServer);
+        verify(mConntrackMonitor).start();
+        clearInvocations(mConntrackMonitor);
+
+        // [3] Stop monitoring.
+        coordinator.stopMonitoring(mIpServer);
+        verify(mConntrackMonitor).stop();
+    }
+
+    @Test
+    public void testStartStopConntrackMonitoringWithTwoDownstreamIfaces() throws Exception {
+        setupFunctioningNetdInterface();
+
+        final BpfCoordinator coordinator = makeBpfCoordinator();
+
+        // [1] Start monitoring at the first IpServer adding.
+        coordinator.startMonitoring(mIpServer);
+        verify(mConntrackMonitor).start();
+        clearInvocations(mConntrackMonitor);
+
+        // [2] Don't start monitoring at the second IpServer adding.
+        coordinator.startMonitoring(mIpServer2);
+        verify(mConntrackMonitor, never()).start();
+
+        // [3] Don't stop monitoring if any downstream interface exists.
+        coordinator.stopMonitoring(mIpServer2);
+        verify(mConntrackMonitor, never()).stop();
+
+        // [4] Stop monitoring if no downstream exists.
+        coordinator.stopMonitoring(mIpServer);
+        verify(mConntrackMonitor).stop();
     }
 }
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index f4b3749..60fddb5 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -586,6 +586,9 @@
                 ArgumentCaptor.forClass(SoftApCallback.class);
         verify(mWifiManager).registerSoftApCallback(any(), softApCallbackCaptor.capture());
         mSoftApCallback = softApCallbackCaptor.getValue();
+
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)).thenReturn(true);
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true);
     }
 
     private void setTetheringSupported(final boolean supported) {
diff --git a/tests/cts/hostside/Android.bp b/tests/cts/hostside/Android.bp
index 47b114b..3185f7e 100644
--- a/tests/cts/hostside/Android.bp
+++ b/tests/cts/hostside/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 java_test_host {
     name: "CtsHostsideNetworkTests",
     defaults: ["cts_defaults"],
diff --git a/tests/cts/hostside/TEST_MAPPING b/tests/cts/hostside/TEST_MAPPING
new file mode 100644
index 0000000..02d2d6e
--- /dev/null
+++ b/tests/cts/hostside/TEST_MAPPING
@@ -0,0 +1,18 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsHostsideNetworkTests",
+      "options": [
+        {
+          "include-filter": "com.android.cts.net.HostsideRestrictBackgroundNetworkTests"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        },
+        {
+          "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/tests/cts/hostside/aidl/Android.bp b/tests/cts/hostside/aidl/Android.bp
index 320a1fa..2751f6f 100644
--- a/tests/cts/hostside/aidl/Android.bp
+++ b/tests/cts/hostside/aidl/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 java_test_helper_library {
     name: "CtsHostsideNetworkTestsAidl",
     sdk_version: "current",
diff --git a/tests/cts/hostside/app/Android.bp b/tests/cts/hostside/app/Android.bp
index 9903756..813e6c7 100644
--- a/tests/cts/hostside/app/Android.bp
+++ b/tests/cts/hostside/app/Android.bp
@@ -14,6 +14,10 @@
 // limitations under the License.
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 android_test_helper_app {
     name: "CtsHostsideNetworkTestsApp",
     defaults: ["cts_support_defaults"],
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index 71f6f2f..f423503 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -234,12 +234,16 @@
     }
 
     protected void assertForegroundNetworkAccess() throws Exception {
+        assertForegroundNetworkAccess(true);
+    }
+
+    protected void assertForegroundNetworkAccess(boolean expectAllowed) throws Exception {
         assertForegroundState();
         // We verified that app is in foreground state but if the screen turns-off while
         // verifying for network access, the app will go into background state (in case app's
         // foreground status was due to top activity). So, turn the screen on when verifying
         // network connectivity.
-        assertNetworkAccess(true /* expectAvailable */, true /* needScreenOn */);
+        assertNetworkAccess(expectAllowed /* expectAvailable */, true /* needScreenOn */);
     }
 
     protected void assertForegroundServiceNetworkAccess() throws Exception {
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java
index 8fadf9e..5c99c67 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java
@@ -15,21 +15,20 @@
  */
 package com.android.cts.net.hostside;
 
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.resetMeteredNetwork;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setupMeteredNetwork;
+import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setupActiveNetworkMeteredness;
 import static com.android.cts.net.hostside.Property.METERED_NETWORK;
 import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK;
 
 import android.util.ArraySet;
-import android.util.Pair;
 
 import com.android.compatibility.common.util.BeforeAfterRule;
+import com.android.compatibility.common.util.ThrowingRunnable;
 
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
 public class MeterednessConfigurationRule extends BeforeAfterRule {
-    private Pair<String, Boolean> mSsidAndInitialMeteredness;
+    private ThrowingRunnable mMeterednessResetter;
 
     @Override
     public void onBefore(Statement base, Description description) throws Throwable {
@@ -48,13 +47,13 @@
     }
 
     public void configureNetworkMeteredness(boolean metered) throws Exception {
-        mSsidAndInitialMeteredness = setupMeteredNetwork(metered);
+        mMeterednessResetter = setupActiveNetworkMeteredness(metered);
     }
 
     public void resetNetworkMeteredness() throws Exception {
-        if (mSsidAndInitialMeteredness != null) {
-            resetMeteredNetwork(mSsidAndInitialMeteredness.first,
-                    mSsidAndInitialMeteredness.second);
+        if (mMeterednessResetter != null) {
+            mMeterednessResetter.run();
+            mMeterednessResetter = null;
         }
     }
 }
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java
index 2ac29e7..955317b 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java
@@ -17,16 +17,13 @@
 package com.android.cts.net.hostside;
 
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+
 import static com.android.cts.net.hostside.NetworkPolicyTestUtils.canChangeActiveNetworkMeteredness;
 import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isActiveNetworkMetered;
 import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE;
 import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeTrue;
 
@@ -186,7 +183,7 @@
     public void setUp() throws Exception {
         super.setUp();
 
-        assumeTrue(isActiveNetworkMetered(true) || canChangeActiveNetworkMeteredness());
+        assumeTrue(canChangeActiveNetworkMeteredness());
 
         registerBroadcastReceiver();
 
@@ -198,13 +195,13 @@
         setBatterySaverMode(false);
         setRestrictBackground(false);
 
-        // Make wifi a metered network.
+        // Mark network as metered.
         mMeterednessConfiguration.configureNetworkMeteredness(true);
 
         // Register callback
         registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback);
-        // Once the wifi is marked as metered, the wifi will reconnect. Wait for onAvailable()
-        // callback to ensure wifi is connected before the test and store the default network.
+        // Wait for onAvailable() callback to ensure network is available before the test
+        // and store the default network.
         mNetwork = mTestNetworkCallback.expectAvailableCallbackAndGetNetwork();
         // Check that the network is metered.
         mTestNetworkCallback.expectCapabilitiesCallbackEventually(mNetwork,
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
index 3807d79..b61535b 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
@@ -20,6 +20,7 @@
 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 
 import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
@@ -28,6 +29,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -40,25 +42,36 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.wifi.WifiManager;
+import android.os.PersistableBundle;
 import android.os.Process;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.data.ApnSetting;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.Pair;
+
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.compatibility.common.util.AppStandbyUtils;
 import com.android.compatibility.common.util.BatteryUtils;
+import com.android.compatibility.common.util.ShellIdentityUtils;
+import com.android.compatibility.common.util.ThrowingRunnable;
 
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-import androidx.test.platform.app.InstrumentationRegistry;
-
 public class NetworkPolicyTestUtils {
 
-    private static final int TIMEOUT_CHANGE_METEREDNESS_MS = 5000;
+    // android.telephony.CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS
+    // TODO: Expose it as a @TestApi instead of copying the constant
+    private static final String KEY_CARRIER_METERED_APN_TYPES_STRINGS =
+            "carrier_metered_apn_types_strings";
+
+    private static final int TIMEOUT_CHANGE_METEREDNESS_MS = 10_000;
 
     private static ConnectivityManager mCm;
     private static WifiManager mWm;
+    private static CarrierConfigManager mCarrierConfigManager;
 
     private static Boolean mBatterySaverSupported;
     private static Boolean mDataSaverSupported;
@@ -135,16 +148,40 @@
     }
 
     public static boolean canChangeActiveNetworkMeteredness() {
-        final Network activeNetwork = getConnectivityManager().getActiveNetwork();
-        final NetworkCapabilities networkCapabilities
-                = getConnectivityManager().getNetworkCapabilities(activeNetwork);
-        return networkCapabilities.hasTransport(TRANSPORT_WIFI);
+        final NetworkCapabilities networkCapabilities = getActiveNetworkCapabilities();
+        return networkCapabilities.hasTransport(TRANSPORT_WIFI)
+                || networkCapabilities.hasTransport(TRANSPORT_CELLULAR);
     }
 
-    public static Pair<String, Boolean> setupMeteredNetwork(boolean metered) throws Exception {
+    /**
+     * Updates the meteredness of the active network. Right now we can only change meteredness
+     * of either Wifi or cellular network, so if the active network is not either of these, this
+     * will throw an exception.
+     *
+     * @return a {@link ThrowingRunnable} object that can used to reset the meteredness change
+     *         made by this method.
+     */
+    public static ThrowingRunnable setupActiveNetworkMeteredness(boolean metered) throws Exception {
         if (isActiveNetworkMetered(metered)) {
             return null;
         }
+        final NetworkCapabilities networkCapabilities = getActiveNetworkCapabilities();
+        if (networkCapabilities.hasTransport(TRANSPORT_WIFI)) {
+            final String ssid = getWifiSsid();
+            setWifiMeteredStatus(ssid, metered);
+            return () -> setWifiMeteredStatus(ssid, !metered);
+        } else if (networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
+            final int subId = SubscriptionManager.getActiveDataSubscriptionId();
+            setCellularMeteredStatus(subId, metered);
+            return () -> setCellularMeteredStatus(subId, !metered);
+        } else {
+            // Right now, we don't have a way to change meteredness of networks other
+            // than Wi-Fi or Cellular, so just throw an exception.
+            throw new IllegalStateException("Can't change meteredness of current active network");
+        }
+    }
+
+    private static String getWifiSsid() {
         final boolean isLocationEnabled = isLocationEnabled();
         try {
             if (!isLocationEnabled) {
@@ -152,8 +189,7 @@
             }
             final String ssid = unquoteSSID(getWifiManager().getConnectionInfo().getSSID());
             assertNotEquals(WifiManager.UNKNOWN_SSID, ssid);
-            setWifiMeteredStatus(ssid, metered);
-            return Pair.create(ssid, !metered);
+            return ssid;
         } finally {
             // Reset the location enabled state
             if (!isLocationEnabled) {
@@ -162,11 +198,13 @@
         }
     }
 
-    public static void resetMeteredNetwork(String ssid, boolean metered) throws Exception {
-        setWifiMeteredStatus(ssid, metered);
+    private static NetworkCapabilities getActiveNetworkCapabilities() {
+        final Network activeNetwork = getConnectivityManager().getActiveNetwork();
+        assertNotNull("No active network available", activeNetwork);
+        return getConnectivityManager().getNetworkCapabilities(activeNetwork);
     }
 
-    public static void setWifiMeteredStatus(String ssid, boolean metered) throws Exception {
+    private static void setWifiMeteredStatus(String ssid, boolean metered) throws Exception {
         assertFalse("SSID should not be empty", TextUtils.isEmpty(ssid));
         final String cmd = "cmd netpolicy set metered-network " + ssid + " " + metered;
         executeShellCommand(cmd);
@@ -174,15 +212,24 @@
         assertActiveNetworkMetered(metered);
     }
 
-    public static void assertWifiMeteredStatus(String ssid, boolean expectedMeteredStatus) {
+    private static void assertWifiMeteredStatus(String ssid, boolean expectedMeteredStatus) {
         final String result = executeShellCommand("cmd netpolicy list wifi-networks");
         final String expectedLine = ssid + ";" + expectedMeteredStatus;
         assertTrue("Expected line: " + expectedLine + "; Actual result: " + result,
                 result.contains(expectedLine));
     }
 
+    private static void setCellularMeteredStatus(int subId, boolean metered) throws Exception {
+        final PersistableBundle bundle = new PersistableBundle();
+        bundle.putStringArray(KEY_CARRIER_METERED_APN_TYPES_STRINGS,
+                new String[] {ApnSetting.TYPE_MMS_STRING});
+        ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(getCarrierConfigManager(),
+                (cm) -> cm.overrideConfig(subId, metered ? null : bundle));
+        assertActiveNetworkMetered(metered);
+    }
+
     // Copied from cts/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
-    public static void assertActiveNetworkMetered(boolean expectedMeteredStatus) throws Exception {
+    private static void assertActiveNetworkMetered(boolean expectedMeteredStatus) throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
         final NetworkCallback networkCallback = new NetworkCallback() {
             @Override
@@ -197,12 +244,15 @@
         // with the current setting. Therefore, if the setting has already been changed,
         // this method will return right away, and if not it will wait for the setting to change.
         getConnectivityManager().registerDefaultNetworkCallback(networkCallback);
-        if (!latch.await(TIMEOUT_CHANGE_METEREDNESS_MS, TimeUnit.MILLISECONDS)) {
-            fail("Timed out waiting for active network metered status to change to "
-                    + expectedMeteredStatus + " ; network = "
-                    + getConnectivityManager().getActiveNetwork());
+        try {
+            if (!latch.await(TIMEOUT_CHANGE_METEREDNESS_MS, TimeUnit.MILLISECONDS)) {
+                fail("Timed out waiting for active network metered status to change to "
+                        + expectedMeteredStatus + "; network = "
+                        + getConnectivityManager().getActiveNetwork());
+            }
+        } finally {
+            getConnectivityManager().unregisterNetworkCallback(networkCallback);
         }
-        getConnectivityManager().unregisterNetworkCallback(networkCallback);
     }
 
     public static void setRestrictBackground(boolean enabled) {
@@ -274,6 +324,14 @@
         return mWm;
     }
 
+    public static CarrierConfigManager getCarrierConfigManager() {
+        if (mCarrierConfigManager == null) {
+            mCarrierConfigManager = (CarrierConfigManager) getContext().getSystemService(
+                    Context.CARRIER_CONFIG_SERVICE);
+        }
+        return mCarrierConfigManager;
+    }
+
     public static Context getContext() {
         return getInstrumentation().getContext();
     }
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RestrictedModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RestrictedModeTest.java
new file mode 100644
index 0000000..29d3c6e
--- /dev/null
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RestrictedModeTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2021 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 com.android.cts.net.hostside;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public final class RestrictedModeTest extends AbstractRestrictBackgroundNetworkTestCase {
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        setRestrictedMode(false);
+        super.tearDown();
+    }
+
+    private void setRestrictedMode(boolean enabled) throws Exception {
+        executeSilentShellCommand(
+                "settings put global restricted_networking_mode " + (enabled ? 1 : 0));
+        assertRestrictedModeState(enabled);
+    }
+
+    private void assertRestrictedModeState(boolean enabled) throws Exception {
+        assertDelayedShellCommand("cmd netpolicy get restricted-mode",
+                "Restricted mode status: " + (enabled ? "enabled" : "disabled"));
+    }
+
+    @Test
+    public void testNetworkAccess() throws Exception {
+        setRestrictedMode(false);
+
+        // go to foreground state and enable restricted mode
+        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
+        setRestrictedMode(true);
+        assertForegroundNetworkAccess(false);
+
+        // go to background state
+        finishActivity();
+        assertBackgroundNetworkAccess(false);
+
+        // disable restricted mode and assert network access in foreground and background states
+        setRestrictedMode(false);
+        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
+        assertForegroundNetworkAccess(true);
+
+        // go to background state
+        finishActivity();
+        assertBackgroundNetworkAccess(true);
+    }
+}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
index 81a431c..a663cd6 100755
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -16,6 +16,8 @@
 
 package com.android.cts.net.hostside;
 
+import static android.Manifest.permission.NETWORK_SETTINGS;
+import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 import static android.os.Process.INVALID_UID;
 import static android.system.OsConstants.AF_INET;
 import static android.system.OsConstants.AF_INET6;
@@ -25,6 +27,9 @@
 import static android.system.OsConstants.IPPROTO_TCP;
 import static android.system.OsConstants.POLLIN;
 import static android.system.OsConstants.SOCK_DGRAM;
+import static android.test.MoreAsserts.assertNotEqual;
+
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
 
 import android.annotation.Nullable;
 import android.app.DownloadManager;
@@ -45,9 +50,14 @@
 import android.net.NetworkRequest;
 import android.net.Proxy;
 import android.net.ProxyInfo;
+import android.net.TransportInfo;
 import android.net.Uri;
+import android.net.VpnManager;
 import android.net.VpnService;
+import android.net.VpnTransportInfo;
 import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.SystemProperties;
@@ -687,6 +697,34 @@
         setAndVerifyPrivateDns(initialMode);
     }
 
+    private class NeverChangeNetworkCallback extends NetworkCallback {
+        private CountDownLatch mLatch = new CountDownLatch(1);
+        private volatile Network mFirstNetwork;
+        private volatile Network mOtherNetwork;
+
+        public void onAvailable(Network n) {
+            // Don't assert here, as it crashes the test with a hard to debug message.
+            if (mFirstNetwork == null) {
+                mFirstNetwork = n;
+                mLatch.countDown();
+            } else if (mOtherNetwork == null) {
+                mOtherNetwork = n;
+            }
+        }
+
+        public Network getFirstNetwork() throws Exception {
+            assertTrue(
+                    "System default callback got no network after " + TIMEOUT_MS + "ms. "
+                    + "Please ensure the device has a working Internet connection.",
+                    mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            return mFirstNetwork;
+        }
+
+        public void assertNeverChanged() {
+            assertNull(mOtherNetwork);
+        }
+    }
+
     public void testDefault() throws Exception {
         if (!supportedHardware()) return;
         // If adb TCP port opened, this test may running by adb over network.
@@ -702,6 +740,14 @@
                 getInstrumentation().getTargetContext(), MyVpnService.ACTION_ESTABLISHED);
         receiver.register();
 
+
+        // Expect the system default network not to change.
+        final NeverChangeNetworkCallback neverChangeCallback = new NeverChangeNetworkCallback();
+        final Network defaultNetwork = mCM.getActiveNetwork();
+        runWithShellPermissionIdentity(() ->
+                mCM.registerSystemDefaultNetworkCallback(neverChangeCallback,
+                        new Handler(Looper.getMainLooper())), NETWORK_SETTINGS);
+
         FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS);
 
         startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
@@ -719,6 +765,20 @@
 
         checkTrafficOnVpn();
 
+        expectVpnTransportInfo(mCM.getActiveNetwork());
+
+        // Check that system default network callback has not seen any network changes, even though
+        // the app's default network changed. This needs to be done before testing private
+        // DNS because checkStrictModePrivateDns will set the private DNS server to a nonexistent
+        // name, which will cause validation to fail and cause the default network to switch (e.g.,
+        // from wifi to cellular).
+        assertEquals(defaultNetwork, neverChangeCallback.getFirstNetwork());
+        assertNotEqual(defaultNetwork, mCM.getActiveNetwork());
+        neverChangeCallback.assertNeverChanged();
+        runWithShellPermissionIdentity(
+                () ->  mCM.unregisterNetworkCallback(neverChangeCallback),
+                NETWORK_SETTINGS);
+
         checkStrictModePrivateDns();
 
         receiver.unregisterQuietly();
@@ -739,6 +799,8 @@
 
         checkTrafficOnVpn();
 
+        expectVpnTransportInfo(mCM.getActiveNetwork());
+
         checkStrictModePrivateDns();
     }
 
@@ -764,6 +826,10 @@
         assertSocketStillOpen(remoteFd, TEST_HOST);
 
         checkNoTrafficOnVpn();
+
+        final Network network = mCM.getActiveNetwork();
+        final NetworkCapabilities nc = mCM.getNetworkCapabilities(network);
+        assertFalse(nc.hasTransport(TRANSPORT_VPN));
     }
 
     public void testGetConnectionOwnerUidSecurity() throws Exception {
@@ -778,8 +844,11 @@
         InetSocketAddress rem = new InetSocketAddress(s.getInetAddress(), s.getPort());
         try {
             int uid = mCM.getConnectionOwnerUid(OsConstants.IPPROTO_TCP, loc, rem);
-            fail("Only an active VPN app may call this API.");
-        } catch (SecurityException expected) {
+            assertEquals("Only an active VPN app should see connection information",
+                    INVALID_UID, uid);
+        } catch (SecurityException acceptable) {
+            // R and below throw SecurityException if a non-active VPN calls this method.
+            // As long as we can't actually get socket information, either behaviour is fine.
             return;
         }
     }
@@ -918,6 +987,8 @@
         // VPN with no underlying networks should be metered by default.
         assertTrue(isNetworkMetered(mNetwork));
         assertTrue(mCM.isActiveNetworkMetered());
+
+        expectVpnTransportInfo(mCM.getActiveNetwork());
     }
 
     public void testVpnMeterednessWithNullUnderlyingNetwork() throws Exception {
@@ -944,6 +1015,8 @@
         assertEquals(isNetworkMetered(underlyingNetwork), isNetworkMetered(mNetwork));
         // Meteredness based on VPN capabilities and CM#isActiveNetworkMetered should be in sync.
         assertEquals(isNetworkMetered(mNetwork), mCM.isActiveNetworkMetered());
+
+        expectVpnTransportInfo(mCM.getActiveNetwork());
     }
 
     public void testVpnMeterednessWithNonNullUnderlyingNetwork() throws Exception {
@@ -971,6 +1044,8 @@
         assertEquals(isNetworkMetered(underlyingNetwork), isNetworkMetered(mNetwork));
         // Meteredness based on VPN capabilities and CM#isActiveNetworkMetered should be in sync.
         assertEquals(isNetworkMetered(mNetwork), mCM.isActiveNetworkMetered());
+
+        expectVpnTransportInfo(mCM.getActiveNetwork());
     }
 
     public void testAlwaysMeteredVpnWithNullUnderlyingNetwork() throws Exception {
@@ -995,6 +1070,8 @@
         // VPN's meteredness does not depend on underlying network since it is always metered.
         assertTrue(isNetworkMetered(mNetwork));
         assertTrue(mCM.isActiveNetworkMetered());
+
+        expectVpnTransportInfo(mCM.getActiveNetwork());
     }
 
     public void testAlwaysMeteredVpnWithNonNullUnderlyingNetwork() throws Exception {
@@ -1020,6 +1097,8 @@
         // VPN's meteredness does not depend on underlying network since it is always metered.
         assertTrue(isNetworkMetered(mNetwork));
         assertTrue(mCM.isActiveNetworkMetered());
+
+        expectVpnTransportInfo(mCM.getActiveNetwork());
     }
 
     public void testB141603906() throws Exception {
@@ -1069,6 +1148,14 @@
         }
     }
 
+    private void expectVpnTransportInfo(Network network) {
+        final NetworkCapabilities vpnNc = mCM.getNetworkCapabilities(network);
+        assertTrue(vpnNc.hasTransport(TRANSPORT_VPN));
+        final TransportInfo ti = vpnNc.getTransportInfo();
+        assertTrue(ti instanceof VpnTransportInfo);
+        assertEquals(VpnManager.TYPE_VPN_SERVICE, ((VpnTransportInfo) ti).type);
+    }
+
     private void assertDefaultProxy(ProxyInfo expected) {
         assertEquals("Incorrect proxy config.", expected, mCM.getDefaultProxy());
         String expectedHost = expected == null ? null : expected.getHost();
diff --git a/tests/cts/hostside/app2/Android.bp b/tests/cts/hostside/app2/Android.bp
index 8e27931..b448459 100644
--- a/tests/cts/hostside/app2/Android.bp
+++ b/tests/cts/hostside/app2/Android.bp
@@ -14,6 +14,10 @@
 // limitations under the License.
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 android_test_helper_app {
     name: "CtsHostsideNetworkTestsApp2",
     defaults: ["cts_support_defaults"],
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java
index 590e17e..1c9ff05 100644
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java
+++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java
@@ -138,7 +138,7 @@
                     }
                 }
             };
-            mCm.registerNetworkCallback(makeWifiNetworkRequest(), mNetworkCallback);
+            mCm.registerNetworkCallback(makeNetworkRequest(), mNetworkCallback);
             try {
                 cb.asBinder().linkToDeath(() -> unregisterNetworkCallback(), 0);
             } catch (RemoteException e) {
@@ -156,9 +156,8 @@
         }
       };
 
-    private NetworkRequest makeWifiNetworkRequest() {
+    private NetworkRequest makeNetworkRequest() {
         return new NetworkRequest.Builder()
-                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .build();
     }
diff --git a/tests/cts/hostside/certs/Android.bp b/tests/cts/hostside/certs/Android.bp
index ab4cf34..60b5476 100644
--- a/tests/cts/hostside/certs/Android.bp
+++ b/tests/cts/hostside/certs/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 android_app_certificate {
     name: "cts-net-app",
     certificate: "cts-net-app",
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
index ac28c7a..a629ccf 100644
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
+++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
@@ -311,6 +311,14 @@
                 "testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists");
     }
 
+    /**************************
+     * Restricted mode tests. *
+     **************************/
+    public void testRestrictedMode_networkAccess() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".RestrictedModeTest",
+                "testNetworkAccess");
+    }
+
     /*******************
      * Helper methods. *
      *******************/
diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp
index 528171a..229633e 100644
--- a/tests/cts/net/Android.bp
+++ b/tests/cts/net/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 java_defaults {
     name: "CtsNetTestCasesDefaults",
     defaults: ["cts_defaults"],
diff --git a/tests/cts/net/api23Test/Android.bp b/tests/cts/net/api23Test/Android.bp
index e43a5e8..5b37294 100644
--- a/tests/cts/net/api23Test/Android.bp
+++ b/tests/cts/net/api23Test/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 android_test {
     name: "CtsNetApi23TestCases",
     defaults: ["cts_defaults"],
diff --git a/tests/cts/net/appForApi23/Android.bp b/tests/cts/net/appForApi23/Android.bp
index cec6d7f..b39690f 100644
--- a/tests/cts/net/appForApi23/Android.bp
+++ b/tests/cts/net/appForApi23/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 android_test {
     name: "CtsNetTestAppForApi23",
     defaults: ["cts_defaults"],
diff --git a/tests/cts/net/jni/Android.bp b/tests/cts/net/jni/Android.bp
index 3953aeb..13f38d7 100644
--- a/tests/cts/net/jni/Android.bp
+++ b/tests/cts/net/jni/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 cc_library_shared {
     name: "libnativedns_jni",
 
diff --git a/tests/cts/net/native/dns/Android.bp b/tests/cts/net/native/dns/Android.bp
index 6defd35..1bc5a86 100644
--- a/tests/cts/net/native/dns/Android.bp
+++ b/tests/cts/net/native/dns/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 cc_defaults {
     name: "dns_async_defaults",
 
diff --git a/tests/cts/net/native/qtaguid/Android.bp b/tests/cts/net/native/qtaguid/Android.bp
index 4861651..68bb14d 100644
--- a/tests/cts/net/native/qtaguid/Android.bp
+++ b/tests/cts/net/native/qtaguid/Android.bp
@@ -14,6 +14,10 @@
 
 // Build the unit tests.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 cc_test {
     name: "CtsNativeNetTestCases",
 
diff --git a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
index eb5048f..a889c41 100644
--- a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
+++ b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
@@ -26,6 +26,9 @@
 import android.net.Network
 import android.net.NetworkCapabilities
 import android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL
+import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
+import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
+import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
 import android.net.NetworkCapabilities.TRANSPORT_WIFI
 import android.net.NetworkRequest
 import android.net.Uri
@@ -44,8 +47,10 @@
 import android.text.TextUtils
 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
 import androidx.test.runner.AndroidJUnit4
+import com.android.testutils.RecorderCallback
 import com.android.testutils.TestHttpServer
 import com.android.testutils.TestHttpServer.Request
+import com.android.testutils.TestableNetworkCallback
 import com.android.testutils.isDevSdkInRange
 import com.android.testutils.runAsShell
 import fi.iki.elonen.NanoHTTPD.Response.Status
@@ -124,7 +129,20 @@
         assumeTrue(pm.hasSystemFeature(FEATURE_TELEPHONY))
         assumeTrue(pm.hasSystemFeature(FEATURE_WIFI))
         utils.ensureWifiConnected()
-        utils.connectToCell()
+        val cellNetwork = utils.connectToCell()
+
+        // Verify cell network is validated
+        val cellReq = NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_CELLULAR)
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .build()
+        val cellCb = TestableNetworkCallback(timeoutMs = TEST_TIMEOUT_MS)
+        cm.registerNetworkCallback(cellReq, cellCb)
+        val cb = cellCb.eventuallyExpectOrNull<RecorderCallback.CallbackEntry.CapabilitiesChanged> {
+            it.network == cellNetwork && it.caps.hasCapability(NET_CAPABILITY_VALIDATED)
+        }
+        assertNotNull(cb, "Mobile network $cellNetwork has no access to the internet. " +
+                "Check the mobile data connection.")
 
         // Have network validation use a local server that serves a HTTPS error / HTTP redirect
         server.addResponse(Request(TEST_PORTAL_URL_PATH), Status.OK,
@@ -135,7 +153,8 @@
         setHttpsUrlDeviceConfig(makeUrl(TEST_HTTPS_URL_PATH))
         setHttpUrlDeviceConfig(makeUrl(TEST_HTTP_URL_PATH))
         // URL expiration needs to be in the next 10 minutes
-        setUrlExpirationDeviceConfig(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(9))
+        assertTrue(WIFI_CONNECT_TIMEOUT_MS < TimeUnit.MINUTES.toMillis(10))
+        setUrlExpirationDeviceConfig(System.currentTimeMillis() + WIFI_CONNECT_TIMEOUT_MS)
 
         // Wait for a captive portal to be detected on the network
         val wifiNetworkFuture = CompletableFuture<Network>()
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index cbf43e7..831810c 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -25,10 +25,12 @@
 import static android.content.pm.PackageManager.FEATURE_WIFI;
 import static android.content.pm.PackageManager.GET_PERMISSIONS;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.TRANSPORT_TEST;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.cts.util.CtsNetUtils.ConnectivityActionReceiver;
 import static android.net.cts.util.CtsNetUtils.HTTP_PORT;
@@ -43,6 +45,7 @@
 
 import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+import static com.android.testutils.MiscAsserts.assertThrows;
 import static com.android.testutils.TestPermissionUtil.runAsShell;
 
 import static org.junit.Assert.assertEquals;
@@ -68,8 +71,10 @@
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
+import android.net.InetAddresses;
 import android.net.IpSecManager;
 import android.net.IpSecManager.UdpEncapsulationSocket;
+import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
@@ -80,11 +85,15 @@
 import android.net.NetworkRequest;
 import android.net.NetworkUtils;
 import android.net.SocketKeepalive;
+import android.net.StringNetworkSpecifier;
+import android.net.TestNetworkInterface;
+import android.net.TestNetworkManager;
 import android.net.cts.util.CtsNetUtils;
 import android.net.util.KeepaliveUtils;
 import android.net.wifi.WifiManager;
 import android.os.Binder;
 import android.os.Build;
+import android.os.Handler;
 import android.os.Looper;
 import android.os.MessageQueue;
 import android.os.SystemClock;
@@ -104,10 +113,10 @@
 import com.android.testutils.SkipPresubmit;
 import com.android.testutils.TestableNetworkCallback;
 
-import libcore.io.Streams;
-
 import junit.framework.AssertionFailedError;
 
+import libcore.io.Streams;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -176,6 +185,9 @@
     private static final String KEEPALIVE_RESERVED_PER_SLOT_RES_NAME =
             "config_reservedPrivilegedKeepaliveSlots";
 
+    private static final LinkAddress TEST_LINKADDR = new LinkAddress(
+            InetAddresses.parseNumericAddress("2001:db8::8"), 64);
+
     private Context mContext;
     private Instrumentation mInstrumentation;
     private ConnectivityManager mCm;
@@ -183,7 +195,6 @@
     private PackageManager mPackageManager;
     private final HashMap<Integer, NetworkConfig> mNetworks =
             new HashMap<Integer, NetworkConfig>();
-    boolean mWifiWasDisabled;
     private UiAutomation mUiAutomation;
     private CtsNetUtils mCtsNetUtils;
 
@@ -195,7 +206,6 @@
         mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
         mPackageManager = mContext.getPackageManager();
         mCtsNetUtils = new CtsNetUtils(mContext);
-        mWifiWasDisabled = false;
 
         // Get com.android.internal.R.array.networkAttributes
         int resId = mContext.getResources().getIdentifier("networkAttributes", "array", "android");
@@ -218,10 +228,7 @@
 
     @After
     public void tearDown() throws Exception {
-        // Return WiFi to its original disabled state after tests that explicitly connect.
-        if (mWifiWasDisabled) {
-            mCtsNetUtils.disconnectFromWifi(null);
-        }
+        // Release any NetworkRequests filed to connect mobile data.
         if (mCtsNetUtils.cellConnectAttempted()) {
             mCtsNetUtils.disconnectFromCell();
         }
@@ -237,17 +244,6 @@
         }
     }
 
-    /**
-     * Make sure WiFi is connected to an access point if it is not already. If
-     * WiFi is enabled as a result of this function, it will be disabled
-     * automatically in tearDown().
-     */
-    private Network ensureWifiConnected() {
-        mWifiWasDisabled = !mWifiManager.isWifiEnabled();
-        // Even if wifi is enabled, the network may not be connected or ready yet
-        return mCtsNetUtils.connectToWifi();
-    }
-
     @Test
     public void testIsNetworkTypeValid() {
         assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE));
@@ -521,25 +517,38 @@
         final TestNetworkCallback defaultTrackingCallback = new TestNetworkCallback();
         mCm.registerDefaultNetworkCallback(defaultTrackingCallback);
 
+        final TestNetworkCallback systemDefaultTrackingCallback = new TestNetworkCallback();
+        runWithShellPermissionIdentity(() ->
+                mCm.registerSystemDefaultNetworkCallback(systemDefaultTrackingCallback,
+                        new Handler(Looper.getMainLooper())),
+                NETWORK_SETTINGS);
+
+
         Network wifiNetwork = null;
 
         try {
-            ensureWifiConnected();
+            mCtsNetUtils.ensureWifiConnected();
 
             // Now we should expect to get a network callback about availability of the wifi
             // network even if it was already connected as a state-based action when the callback
             // is registered.
             wifiNetwork = callback.waitForAvailable();
-            assertNotNull("Did not receive NetworkCallback.onAvailable for TRANSPORT_WIFI",
+            assertNotNull("Did not receive onAvailable for TRANSPORT_WIFI request",
                     wifiNetwork);
 
-            assertNotNull("Did not receive NetworkCallback.onAvailable for any default network",
+            assertNotNull("Did not receive onAvailable on default network callback",
                     defaultTrackingCallback.waitForAvailable());
+
+            assertNotNull("Did not receive onAvailable on system default network callback",
+                    systemDefaultTrackingCallback.waitForAvailable());
         } catch (InterruptedException e) {
             fail("Broadcast receiver or NetworkCallback wait was interrupted.");
         } finally {
             mCm.unregisterNetworkCallback(callback);
             mCm.unregisterNetworkCallback(defaultTrackingCallback);
+            runWithShellPermissionIdentity(
+                    () -> mCm.unregisterNetworkCallback(systemDefaultTrackingCallback),
+                    NETWORK_SETTINGS);
         }
     }
 
@@ -574,7 +583,7 @@
         mCm.registerNetworkCallback(makeWifiNetworkRequest(), pendingIntent);
 
         try {
-            ensureWifiConnected();
+            mCtsNetUtils.ensureWifiConnected();
 
             // Now we expect to get the Intent delivered notifying of the availability of the wifi
             // network even if it was already connected as a state-based action when the callback
@@ -655,6 +664,17 @@
         return null;
     }
 
+    /**
+     * Checks that enabling/disabling wifi causes CONNECTIVITY_ACTION broadcasts.
+     */
+    @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
+    @Test
+    public void testToggleWifiConnectivityAction() {
+        // toggleWifi calls connectToWifi and disconnectFromWifi, which both wait for
+        // CONNECTIVITY_ACTION broadcasts.
+        mCtsNetUtils.toggleWifi();
+    }
+
     /** Verify restricted networks cannot be requested. */
     @AppModeFull(reason = "CHANGE_NETWORK_STATE permission can't be granted to instant apps")
     @Test
@@ -782,7 +802,7 @@
     @Test
     public void testGetMultipathPreference() throws Exception {
         final ContentResolver resolver = mContext.getContentResolver();
-        ensureWifiConnected();
+        mCtsNetUtils.ensureWifiConnected();
         final String ssid = unquoteSSID(mWifiManager.getConnectionInfo().getSSID());
         final String oldMeteredSetting = getWifiMeteredStatus(ssid);
         final String oldMeteredMultipathPreference = Settings.Global.getString(
@@ -796,7 +816,7 @@
             waitForActiveNetworkMetered(TRANSPORT_WIFI, true);
             // Wifi meterness changes from unmetered to metered will disconnect and reconnect since
             // R.
-            final Network network = ensureWifiConnected();
+            final Network network = mCtsNetUtils.ensureWifiConnected();
             assertEquals(ssid, unquoteSSID(mWifiManager.getConnectionInfo().getSSID()));
             assertEquals(mCm.getNetworkCapabilities(network).hasCapability(
                     NET_CAPABILITY_NOT_METERED), false);
@@ -1010,7 +1030,7 @@
             return;
         }
 
-        final Network network = ensureWifiConnected();
+        final Network network = mCtsNetUtils.ensureWifiConnected();
         if (getSupportedKeepalivesForNet(network) != 0) return;
         final InetAddress srcAddr = getFirstV4Address(network);
         assumeTrue("This test requires native IPv4", srcAddr != null);
@@ -1030,7 +1050,7 @@
             return;
         }
 
-        final Network network = ensureWifiConnected();
+        final Network network = mCtsNetUtils.ensureWifiConnected();
         if (getSupportedKeepalivesForNet(network) == 0) return;
         final InetAddress srcAddr = getFirstV4Address(network);
         assumeTrue("This test requires native IPv4", srcAddr != null);
@@ -1241,7 +1261,7 @@
             return;
         }
 
-        final Network network = ensureWifiConnected();
+        final Network network = mCtsNetUtils.ensureWifiConnected();
         final int supported = getSupportedKeepalivesForNet(network);
         if (supported == 0) {
             return;
@@ -1338,7 +1358,7 @@
             return;
         }
 
-        final Network network = ensureWifiConnected();
+        final Network network = mCtsNetUtils.ensureWifiConnected();
         final int supported = getSupportedKeepalivesForNet(network);
         if (supported == 0) {
             return;
@@ -1386,7 +1406,7 @@
 
         // Ensure that NetworkUtils.queryUserAccess always returns false since this package should
         // not have netd system permission to call this function.
-        final Network wifiNetwork = ensureWifiConnected();
+        final Network wifiNetwork = mCtsNetUtils.ensureWifiConnected();
         assertFalse(NetworkUtils.queryUserAccess(Binder.getCallingUid(), wifiNetwork.netId));
 
         // Ensure that this package cannot bind to any restricted network that's currently
@@ -1531,4 +1551,72 @@
             throw new AssertionFailedError("Captive portal server URL is invalid: " + e);
         }
     }
+
+    /**
+     * Verify background request can only be requested when acquiring
+     * {@link android.Manifest.permission.NETWORK_SETTINGS}.
+     */
+    @SkipPresubmit(reason = "Flaky: b/179554972; add to presubmit after fixing")
+    @Test
+    public void testRequestBackgroundNetwork() throws Exception {
+        // Create a tun interface. Use the returned interface name as the specifier to create
+        // a test network request.
+        final TestNetworkInterface testNetworkInterface = runWithShellPermissionIdentity(() -> {
+            final TestNetworkManager tnm =
+                    mContext.getSystemService(TestNetworkManager.class);
+            return tnm.createTunInterface(new LinkAddress[]{TEST_LINKADDR});
+        }, android.Manifest.permission.MANAGE_TEST_NETWORKS,
+                android.Manifest.permission.NETWORK_SETTINGS);
+        assertNotNull(testNetworkInterface);
+
+        final NetworkRequest testRequest = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_TEST)
+                // Test networks do not have NOT_VPN or TRUSTED capabilities by default
+                .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
+                .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+                .setNetworkSpecifier(
+                        new StringNetworkSpecifier(testNetworkInterface.getInterfaceName()))
+                .build();
+
+        // Verify background network cannot be requested without NETWORK_SETTINGS permission.
+        final TestableNetworkCallback callback = new TestableNetworkCallback();
+        assertThrows(SecurityException.class,
+                () -> mCm.requestBackgroundNetwork(testRequest, null, callback));
+
+        try {
+            // Request background test network via Shell identity which has NETWORK_SETTINGS
+            // permission granted.
+            runWithShellPermissionIdentity(
+                    () -> mCm.requestBackgroundNetwork(testRequest, null, callback),
+                    android.Manifest.permission.NETWORK_SETTINGS);
+
+            // Register the test network agent which has no foreground request associated to it.
+            // And verify it can satisfy the background network request just fired.
+            final Binder binder = new Binder();
+            runWithShellPermissionIdentity(() -> {
+                final TestNetworkManager tnm =
+                        mContext.getSystemService(TestNetworkManager.class);
+                tnm.setupTestNetwork(testNetworkInterface.getInterfaceName(), binder);
+            }, android.Manifest.permission.MANAGE_TEST_NETWORKS,
+                    android.Manifest.permission.NETWORK_SETTINGS);
+            waitForAvailable(callback);
+            final Network testNetwork = callback.getLastAvailableNetwork();
+            assertNotNull(testNetwork);
+
+            // The test network that has just connected is a foreground network,
+            // non-listen requests will get available callback before it can be put into
+            // background if no foreground request can be satisfied. Thus, wait for a short
+            // period is needed to let foreground capability go away.
+            callback.eventuallyExpect(CallbackEntry.NETWORK_CAPS_UPDATED,
+                    callback.getDefaultTimeoutMs(),
+                    c -> c instanceof CallbackEntry.CapabilitiesChanged
+                            && !((CallbackEntry.CapabilitiesChanged) c).getCaps()
+                            .hasCapability(NET_CAPABILITY_FOREGROUND));
+            final NetworkCapabilities nc = mCm.getNetworkCapabilities(testNetwork);
+            assertFalse("expected background network, but got " + nc,
+                    nc.hasCapability(NET_CAPABILITY_FOREGROUND));
+        } finally {
+            mCm.unregisterNetworkCallback(callback);
+        }
+    }
 }
diff --git a/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java b/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java
index 9eab024..8f2d93d 100644
--- a/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java
+++ b/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java
@@ -55,7 +55,7 @@
 import androidx.test.InstrumentationRegistry;
 
 import com.android.internal.util.HexDump;
-import com.android.org.bouncycastle.x509.X509V1CertificateGenerator;
+import com.android.internal.org.bouncycastle.x509.X509V1CertificateGenerator;
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
 import com.android.testutils.DevSdkIgnoreRunner;
 
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index 87aa2a3..aea33ca 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -23,15 +23,9 @@
 import android.net.KeepalivePacketData
 import android.net.LinkAddress
 import android.net.LinkProperties
+import android.net.NattKeepalivePacketData
 import android.net.Network
 import android.net.NetworkAgent
-import android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER
-import android.net.NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT
-import android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER
-import android.net.NetworkAgent.CMD_REPORT_NETWORK_STATUS
-import android.net.NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED
-import android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE
-import android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE
 import android.net.NetworkAgent.INVALID_NETWORK
 import android.net.NetworkAgent.VALID_NETWORK
 import android.net.NetworkAgentConfig
@@ -53,6 +47,8 @@
 import android.net.SocketKeepalive
 import android.net.StringNetworkSpecifier
 import android.net.Uri
+import android.net.VpnManager
+import android.net.VpnTransportInfo
 import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAddKeepalivePacketFilter
 import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAutomaticReconnectDisabled
 import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested
@@ -64,27 +60,22 @@
 import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive
 import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnValidationStatus
 import android.os.Build
-import android.os.Bundle
-import android.os.Handler
 import android.os.HandlerThread
 import android.os.Looper
 import android.os.Message
-import android.os.Messenger
 import android.util.DebugUtils.valueToString
 import androidx.test.InstrumentationRegistry
-import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.AsyncChannel
+import com.android.connectivity.aidl.INetworkAgent
+import com.android.connectivity.aidl.INetworkAgentRegistry
 import com.android.net.module.util.ArrayTrackRecord
-import com.android.testutils.DevSdkIgnoreRule
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
+import com.android.testutils.DevSdkIgnoreRunner
 import com.android.testutils.RecorderCallback.CallbackEntry.Available
 import com.android.testutils.RecorderCallback.CallbackEntry.Lost
 import com.android.testutils.TestableNetworkCallback
 import org.junit.After
 import org.junit.Assert.assertArrayEquals
-import org.junit.Assert.fail
 import org.junit.Before
-import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.any
@@ -93,6 +84,7 @@
 import org.mockito.ArgumentMatchers.eq
 import org.mockito.Mockito.doReturn
 import org.mockito.Mockito.mock
+import org.mockito.Mockito.timeout
 import org.mockito.Mockito.verify
 import java.time.Duration
 import java.util.Arrays
@@ -103,6 +95,7 @@
 import kotlin.test.assertNotNull
 import kotlin.test.assertNull
 import kotlin.test.assertTrue
+import kotlin.test.fail
 
 // This test doesn't really have a constraint on how fast the methods should return. If it's
 // going to fail, it will simply wait forever, so setting a high timeout lowers the flake ratio
@@ -130,17 +123,17 @@
     it.obj = obj
 }
 
-@RunWith(AndroidJUnit4::class)
+@RunWith(DevSdkIgnoreRunner::class)
+// NetworkAgent is not updatable in R-, so this test does not need to be compatible with older
+// versions. NetworkAgent was also based on AsyncChannel before S so cannot be tested the same way.
+@IgnoreUpTo(Build.VERSION_CODES.R)
 class NetworkAgentTest {
-    @Rule @JvmField
-    val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.Q)
-
     private val LOCAL_IPV4_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.1")
     private val REMOTE_IPV4_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.2")
 
     private val mCM = realContext.getSystemService(ConnectivityManager::class.java)
     private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread")
-    private val mFakeConnectivityService by lazy { FakeConnectivityService(mHandlerThread.looper) }
+    private val mFakeConnectivityService = FakeConnectivityService()
 
     private class Provider(context: Context, looper: Looper) :
             NetworkProvider(context, looper, "NetworkAgentTest NetworkProvider")
@@ -167,39 +160,30 @@
      * This fake only supports speaking to one harnessed agent at a time because it
      * only keeps track of one async channel.
      */
-    private class FakeConnectivityService(looper: Looper) {
-        private val CMD_EXPECT_DISCONNECT = 1
-        private var disconnectExpected = false
-        private val msgHistory = ArrayTrackRecord<Message>().newReadHead()
-        private val asyncChannel = AsyncChannel()
-        private val handler = object : Handler(looper) {
-            override fun handleMessage(msg: Message) {
-                msgHistory.add(Message.obtain(msg)) // make a copy as the original will be recycled
-                when (msg.what) {
-                    CMD_EXPECT_DISCONNECT -> disconnectExpected = true
-                    AsyncChannel.CMD_CHANNEL_HALF_CONNECTED ->
-                        asyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION)
-                    AsyncChannel.CMD_CHANNEL_DISCONNECTED ->
-                        if (!disconnectExpected) {
-                            fail("Agent unexpectedly disconnected")
-                        } else {
-                            disconnectExpected = false
-                        }
-                }
-            }
+    private class FakeConnectivityService {
+        val mockRegistry = mock(INetworkAgentRegistry::class.java)
+        private var agentField: INetworkAgent? = null
+        private val registry = object : INetworkAgentRegistry.Stub(),
+                INetworkAgentRegistry by mockRegistry {
+            // asBinder has implementations in both INetworkAgentRegistry.Stub and mockRegistry, so
+            // it needs to be disambiguated. Just fail the test as it should be unused here.
+            // asBinder is used when sending the registry in binder transactions, so not in this
+            // test (the test just uses in-process direct calls). If it were used across processes,
+            // using the Stub super.asBinder() implementation would allow sending the registry in
+            // binder transactions, while recording incoming calls on the other mockito-generated
+            // methods.
+            override fun asBinder() = fail("asBinder should be unused in this test")
         }
 
-        fun connect(agentMsngr: Messenger) = asyncChannel.connect(realContext, handler, agentMsngr)
+        val agent: INetworkAgent
+            get() = agentField ?: fail("No INetworkAgent")
 
-        fun disconnect() = asyncChannel.disconnect()
+        fun connect(agent: INetworkAgent) {
+            this.agentField = agent
+            agent.onRegistered(registry)
+        }
 
-        fun sendMessage(what: Int, arg1: Int = 0, arg2: Int = 0, obj: Any? = null) =
-            asyncChannel.sendMessage(Message(what, arg1, arg2, obj))
-
-        fun expectMessage(what: Int) =
-            assertNotNull(msgHistory.poll(DEFAULT_TIMEOUT_MS) { it.what == what })
-
-        fun willExpectDisconnectOnce() = handler.sendEmptyMessage(CMD_EXPECT_DISCONNECT)
+        fun disconnect() = agent.onDisconnected()
     }
 
     private open class TestableNetworkAgent(
@@ -445,17 +429,15 @@
 
     @Test
     fun testSocketKeepalive(): Unit = createNetworkAgentWithFakeCS().let { agent ->
-        val packet = object : KeepalivePacketData(
+        val packet = NattKeepalivePacketData(
                 LOCAL_IPV4_ADDRESS /* srcAddress */, 1234 /* srcPort */,
                 REMOTE_IPV4_ADDRESS /* dstAddress */, 4567 /* dstPort */,
-                ByteArray(100 /* size */) { it.toByte() /* init */ }) {}
+                ByteArray(100 /* size */))
         val slot = 4
         val interval = 37
 
-        mFakeConnectivityService.sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER,
-                arg1 = slot, obj = packet)
-        mFakeConnectivityService.sendMessage(CMD_START_SOCKET_KEEPALIVE,
-                arg1 = slot, arg2 = interval, obj = packet)
+        mFakeConnectivityService.agent.onAddNattKeepalivePacketFilter(slot, packet)
+        mFakeConnectivityService.agent.onStartNattSocketKeepalive(slot, interval, packet)
 
         agent.expectCallback<OnAddKeepalivePacketFilter>().let {
             assertEquals(it.slot, slot)
@@ -472,13 +454,11 @@
         // Check that when the agent sends a keepalive event, ConnectivityService receives the
         // expected message.
         agent.sendSocketKeepaliveEvent(slot, SocketKeepalive.ERROR_UNSUPPORTED)
-        mFakeConnectivityService.expectMessage(NetworkAgent.EVENT_SOCKET_KEEPALIVE).let() {
-            assertEquals(slot, it.arg1)
-            assertEquals(SocketKeepalive.ERROR_UNSUPPORTED, it.arg2)
-        }
+        verify(mFakeConnectivityService.mockRegistry, timeout(DEFAULT_TIMEOUT_MS))
+                .sendSocketKeepaliveEvent(slot, SocketKeepalive.ERROR_UNSUPPORTED)
 
-        mFakeConnectivityService.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, arg1 = slot)
-        mFakeConnectivityService.sendMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, arg1 = slot)
+        mFakeConnectivityService.agent.onStopSocketKeepalive(slot)
+        mFakeConnectivityService.agent.onRemoveKeepalivePacketFilter(slot)
         agent.expectCallback<OnStopSocketKeepalive>().let {
             assertEquals(it.slot, slot)
         }
@@ -563,7 +543,7 @@
 
     @Test
     @IgnoreUpTo(Build.VERSION_CODES.R)
-    fun testSetUnderlyingNetworks() {
+    fun testSetUnderlyingNetworksAndVpnSpecifier() {
         val request = NetworkRequest.Builder()
                 .addTransportType(TRANSPORT_TEST)
                 .addTransportType(TRANSPORT_VPN)
@@ -577,6 +557,7 @@
             addTransportType(TRANSPORT_TEST)
             addTransportType(TRANSPORT_VPN)
             removeCapability(NET_CAPABILITY_NOT_VPN)
+            setTransportInfo(VpnTransportInfo(VpnManager.TYPE_VPN_SERVICE))
         }
         val defaultNetwork = mCM.activeNetwork
         assertNotNull(defaultNetwork)
@@ -591,6 +572,8 @@
         // Check that the default network's transport is propagated to the VPN.
         var vpnNc = mCM.getNetworkCapabilities(agent.network)
         assertNotNull(vpnNc)
+        assertEquals(VpnManager.TYPE_VPN_SERVICE,
+                (vpnNc.transportInfo as VpnTransportInfo).type)
 
         val testAndVpn = intArrayOf(TRANSPORT_TEST, TRANSPORT_VPN)
         assertTrue(hasAllTransports(vpnNc, testAndVpn))
@@ -639,7 +622,7 @@
         val mockCm = mock(ConnectivityManager::class.java)
         doReturn(mockCm).`when`(mockContext).getSystemService(Context.CONNECTIVITY_SERVICE)
         createConnectedNetworkAgent(mockContext)
-        verify(mockCm).registerNetworkAgent(any(Messenger::class.java),
+        verify(mockCm).registerNetworkAgent(any(),
                 argThat<NetworkInfo> { it.detailedState == NetworkInfo.DetailedState.CONNECTING },
                 any(LinkProperties::class.java),
                 any(NetworkCapabilities::class.java),
@@ -651,7 +634,7 @@
     @Test
     fun testSetAcceptUnvalidated() {
         createNetworkAgentWithFakeCS().let { agent ->
-            mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 1)
+            mFakeConnectivityService.agent.onSaveAcceptUnvalidated(true)
             agent.expectCallback<OnSaveAcceptUnvalidated>().let {
                 assertTrue(it.accept)
             }
@@ -662,19 +645,18 @@
     @Test
     fun testSetAcceptUnvalidatedPreventAutomaticReconnect() {
         createNetworkAgentWithFakeCS().let { agent ->
-            mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 0)
-            mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT)
+            mFakeConnectivityService.agent.onSaveAcceptUnvalidated(false)
+            mFakeConnectivityService.agent.onPreventAutomaticReconnect()
             agent.expectCallback<OnSaveAcceptUnvalidated>().let {
                 assertFalse(it.accept)
             }
             agent.expectCallback<OnAutomaticReconnectDisabled>()
             agent.assertNoCallback()
             // When automatic reconnect is turned off, the network is torn down and
-            // ConnectivityService sends a disconnect. This in turn causes the agent
-            // to send a DISCONNECTED message to CS.
-            mFakeConnectivityService.willExpectDisconnectOnce()
+            // ConnectivityService disconnects. As part of the disconnect, ConnectivityService will
+            // also send itself a message to unregister the NetworkAgent from its internal
+            // structure.
             mFakeConnectivityService.disconnect()
-            mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED)
             agent.expectCallback<OnNetworkUnwanted>()
         }
     }
@@ -682,12 +664,10 @@
     @Test
     fun testPreventAutomaticReconnect() {
         createNetworkAgentWithFakeCS().let { agent ->
-            mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT)
+            mFakeConnectivityService.agent.onPreventAutomaticReconnect()
             agent.expectCallback<OnAutomaticReconnectDisabled>()
             agent.assertNoCallback()
-            mFakeConnectivityService.willExpectDisconnectOnce()
             mFakeConnectivityService.disconnect()
-            mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED)
             agent.expectCallback<OnNetworkUnwanted>()
         }
     }
@@ -695,18 +675,14 @@
     @Test
     fun testValidationStatus() = createNetworkAgentWithFakeCS().let { agent ->
         val uri = Uri.parse("http://www.google.com")
-        val bundle = Bundle().apply {
-            putString(NetworkAgent.REDIRECT_URL_KEY, uri.toString())
-        }
-        mFakeConnectivityService.sendMessage(CMD_REPORT_NETWORK_STATUS,
-                arg1 = VALID_NETWORK, obj = bundle)
+        mFakeConnectivityService.agent.onValidationStatusChanged(VALID_NETWORK,
+                uri.toString())
         agent.expectCallback<OnValidationStatus>().let {
             assertEquals(it.status, VALID_NETWORK)
             assertEquals(it.uri, uri)
         }
 
-        mFakeConnectivityService.sendMessage(CMD_REPORT_NETWORK_STATUS,
-                arg1 = INVALID_NETWORK, obj = Bundle())
+        mFakeConnectivityService.agent.onValidationStatusChanged(INVALID_NETWORK, null)
         agent.expectCallback<OnValidationStatus>().let {
             assertEquals(it.status, INVALID_NETWORK)
             assertNull(it.uri)
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.java b/tests/cts/net/src/android/net/cts/NsdManagerTest.java
new file mode 100644
index 0000000..2bcfdc3
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.java
@@ -0,0 +1,594 @@
+/*
+ * 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.net.cts;
+
+import android.content.Context;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.platform.test.annotations.AppModeFull;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.List;
+import java.util.ArrayList;
+
+@AppModeFull(reason = "Socket cannot bind in instant app mode")
+public class NsdManagerTest extends AndroidTestCase {
+
+    private static final String TAG = "NsdManagerTest";
+    private static final String SERVICE_TYPE = "_nmt._tcp";
+    private static final int TIMEOUT = 2000;
+
+    private static final boolean DBG = false;
+
+    NsdManager mNsdManager;
+
+    NsdManager.RegistrationListener mRegistrationListener;
+    NsdManager.DiscoveryListener mDiscoveryListener;
+    NsdManager.ResolveListener mResolveListener;
+    private NsdServiceInfo mResolvedService;
+
+    public NsdManagerTest() {
+        initRegistrationListener();
+        initDiscoveryListener();
+        initResolveListener();
+    }
+
+    private void initRegistrationListener() {
+        mRegistrationListener = new NsdManager.RegistrationListener() {
+            @Override
+            public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
+                setEvent("onRegistrationFailed", errorCode);
+            }
+
+            @Override
+            public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
+                setEvent("onUnregistrationFailed", errorCode);
+            }
+
+            @Override
+            public void onServiceRegistered(NsdServiceInfo serviceInfo) {
+                setEvent("onServiceRegistered", serviceInfo);
+            }
+
+            @Override
+            public void onServiceUnregistered(NsdServiceInfo serviceInfo) {
+                setEvent("onServiceUnregistered", serviceInfo);
+            }
+        };
+    }
+
+    private void initDiscoveryListener() {
+        mDiscoveryListener = new NsdManager.DiscoveryListener() {
+            @Override
+            public void onStartDiscoveryFailed(String serviceType, int errorCode) {
+                setEvent("onStartDiscoveryFailed", errorCode);
+            }
+
+            @Override
+            public void onStopDiscoveryFailed(String serviceType, int errorCode) {
+                setEvent("onStopDiscoveryFailed", errorCode);
+            }
+
+            @Override
+            public void onDiscoveryStarted(String serviceType) {
+                NsdServiceInfo info = new NsdServiceInfo();
+                info.setServiceType(serviceType);
+                setEvent("onDiscoveryStarted", info);
+            }
+
+            @Override
+            public void onDiscoveryStopped(String serviceType) {
+                NsdServiceInfo info = new NsdServiceInfo();
+                info.setServiceType(serviceType);
+                setEvent("onDiscoveryStopped", info);
+            }
+
+            @Override
+            public void onServiceFound(NsdServiceInfo serviceInfo) {
+                setEvent("onServiceFound", serviceInfo);
+            }
+
+            @Override
+            public void onServiceLost(NsdServiceInfo serviceInfo) {
+                setEvent("onServiceLost", serviceInfo);
+            }
+        };
+    }
+
+    private void initResolveListener() {
+        mResolveListener = new NsdManager.ResolveListener() {
+            @Override
+            public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
+                setEvent("onResolveFailed", errorCode);
+            }
+
+            @Override
+            public void onServiceResolved(NsdServiceInfo serviceInfo) {
+                mResolvedService = serviceInfo;
+                setEvent("onServiceResolved", serviceInfo);
+            }
+        };
+    }
+
+
+
+    private final class EventData {
+        EventData(String callbackName, NsdServiceInfo info) {
+            mCallbackName = callbackName;
+            mSucceeded = true;
+            mErrorCode = 0;
+            mInfo = info;
+        }
+        EventData(String callbackName, int errorCode) {
+            mCallbackName = callbackName;
+            mSucceeded = false;
+            mErrorCode = errorCode;
+            mInfo = null;
+        }
+        private final String mCallbackName;
+        private final boolean mSucceeded;
+        private final int mErrorCode;
+        private final NsdServiceInfo mInfo;
+    }
+
+    private final List<EventData> mEventCache = new ArrayList<EventData>();
+
+    private void setEvent(String callbackName, int errorCode) {
+        if (DBG) Log.d(TAG, callbackName + " failed with " + String.valueOf(errorCode));
+        EventData eventData = new EventData(callbackName, errorCode);
+        synchronized (mEventCache) {
+            mEventCache.add(eventData);
+            mEventCache.notify();
+        }
+    }
+
+    private void setEvent(String callbackName, NsdServiceInfo info) {
+        if (DBG) Log.d(TAG, "Received event " + callbackName + " for " + info.getServiceName());
+        EventData eventData = new EventData(callbackName, info);
+        synchronized (mEventCache) {
+            mEventCache.add(eventData);
+            mEventCache.notify();
+        }
+    }
+
+    void clearEventCache() {
+        synchronized(mEventCache) {
+            mEventCache.clear();
+        }
+    }
+
+    int eventCacheSize() {
+        synchronized(mEventCache) {
+            return mEventCache.size();
+        }
+    }
+
+    private int mWaitId = 0;
+    private EventData waitForCallback(String callbackName) {
+
+        synchronized(mEventCache) {
+
+            mWaitId ++;
+            if (DBG) Log.d(TAG, "Waiting for " + callbackName + ", id=" + String.valueOf(mWaitId));
+
+            try {
+                long startTime = android.os.SystemClock.uptimeMillis();
+                long elapsedTime = 0;
+                int index = 0;
+                while (elapsedTime < TIMEOUT ) {
+                    // first check if we've received that event
+                    for (; index < mEventCache.size(); index++) {
+                        EventData e = mEventCache.get(index);
+                        if (e.mCallbackName.equals(callbackName)) {
+                            if (DBG) Log.d(TAG, "exiting wait id=" + String.valueOf(mWaitId));
+                            return e;
+                        }
+                    }
+
+                    // Not yet received, just wait
+                    mEventCache.wait(TIMEOUT - elapsedTime);
+                    elapsedTime = android.os.SystemClock.uptimeMillis() - startTime;
+                }
+                // we exited the loop because of TIMEOUT; fail the call
+                if (DBG) Log.d(TAG, "timed out waiting id=" + String.valueOf(mWaitId));
+                return null;
+            } catch (InterruptedException e) {
+                return null;                       // wait timed out!
+            }
+        }
+    }
+
+    private EventData waitForNewEvents() throws InterruptedException {
+        if (DBG) Log.d(TAG, "Waiting for a bit, id=" + String.valueOf(mWaitId));
+
+        long startTime = android.os.SystemClock.uptimeMillis();
+        long elapsedTime = 0;
+        synchronized (mEventCache) {
+            int index = mEventCache.size();
+            while (elapsedTime < TIMEOUT ) {
+                // first check if we've received that event
+                for (; index < mEventCache.size(); index++) {
+                    EventData e = mEventCache.get(index);
+                    return e;
+                }
+
+                // Not yet received, just wait
+                mEventCache.wait(TIMEOUT - elapsedTime);
+                elapsedTime = android.os.SystemClock.uptimeMillis() - startTime;
+            }
+        }
+
+        return null;
+    }
+
+    private String mServiceName;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        if (DBG) Log.d(TAG, "Setup test ...");
+        mNsdManager = (NsdManager) getContext().getSystemService(Context.NSD_SERVICE);
+
+        Random rand = new Random();
+        mServiceName = new String("NsdTest");
+        for (int i = 0; i < 4; i++) {
+            mServiceName = mServiceName + String.valueOf(rand.nextInt(10));
+        }
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        if (DBG) Log.d(TAG, "Tear down test ...");
+        super.tearDown();
+    }
+
+    public void testNDSManager() throws Exception {
+        EventData lastEvent = null;
+
+        if (DBG) Log.d(TAG, "Starting test ...");
+
+        NsdServiceInfo si = new NsdServiceInfo();
+        si.setServiceType(SERVICE_TYPE);
+        si.setServiceName(mServiceName);
+
+        byte testByteArray[] = new byte[] {-128, 127, 2, 1, 0, 1, 2};
+        String String256 = "1_________2_________3_________4_________5_________6_________" +
+                 "7_________8_________9_________10________11________12________13________" +
+                 "14________15________16________17________18________19________20________" +
+                 "21________22________23________24________25________123456";
+
+        // Illegal attributes
+        try {
+            si.setAttribute(null, (String) null);
+            fail("Could set null key");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute("", (String) null);
+            fail("Could set empty key");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute(String256, (String) null);
+            fail("Could set key with 255 characters");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute("key", String256.substring(3));
+            fail("Could set key+value combination with more than 255 characters");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute("key", String256.substring(4));
+            fail("Could set key+value combination with 255 characters");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute(new String(new byte[]{0x19}), (String) null);
+            fail("Could set key with invalid character");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute("=", (String) null);
+            fail("Could set key with invalid character");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute(new String(new byte[]{0x7F}), (String) null);
+            fail("Could set key with invalid character");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        // Allowed attributes
+        si.setAttribute("booleanAttr", (String) null);
+        si.setAttribute("keyValueAttr", "value");
+        si.setAttribute("keyEqualsAttr", "=");
+        si.setAttribute(" whiteSpaceKeyValueAttr ", " value ");
+        si.setAttribute("binaryDataAttr", testByteArray);
+        si.setAttribute("nullBinaryDataAttr", (byte[]) null);
+        si.setAttribute("emptyBinaryDataAttr", new byte[]{});
+        si.setAttribute("longkey", String256.substring(9));
+
+        ServerSocket socket;
+        int localPort;
+
+        try {
+            socket = new ServerSocket(0);
+            localPort = socket.getLocalPort();
+            si.setPort(localPort);
+        } catch (IOException e) {
+            if (DBG) Log.d(TAG, "Could not open a local socket");
+            assertTrue(false);
+            return;
+        }
+
+        if (DBG) Log.d(TAG, "Port = " + String.valueOf(localPort));
+
+        clearEventCache();
+
+        mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
+        lastEvent = waitForCallback("onServiceRegistered");                 // id = 1
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+        assertTrue(eventCacheSize() == 1);
+
+        // We may not always get the name that we tried to register;
+        // This events tells us the name that was registered.
+        String registeredName = lastEvent.mInfo.getServiceName();
+        si.setServiceName(registeredName);
+
+        clearEventCache();
+
+        mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD,
+                mDiscoveryListener);
+
+        // Expect discovery started
+        lastEvent = waitForCallback("onDiscoveryStarted");                  // id = 2
+
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+
+        // Remove this event, so accounting becomes easier later
+        synchronized (mEventCache) {
+            mEventCache.remove(lastEvent);
+        }
+
+        // Expect a service record to be discovered (and filter the ones
+        // that are unrelated to this test)
+        boolean found = false;
+        for (int i = 0; i < 32; i++) {
+
+            lastEvent = waitForCallback("onServiceFound");                  // id = 3
+            if (lastEvent == null) {
+                // no more onServiceFound events are being reported!
+                break;
+            }
+
+            assertTrue(lastEvent.mSucceeded);
+
+            if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " +
+                    lastEvent.mInfo.getServiceName());
+
+            if (lastEvent.mInfo.getServiceName().equals(registeredName)) {
+                // Save it, as it will get overwritten with new serviceFound events
+                si = lastEvent.mInfo;
+                found = true;
+            }
+
+            // Remove this event from the event cache, so it won't be found by subsequent
+            // calls to waitForCallback
+            synchronized (mEventCache) {
+                mEventCache.remove(lastEvent);
+            }
+        }
+
+        assertTrue(found);
+
+        // We've removed all serviceFound events, and we've removed the discoveryStarted
+        // event as well, so now the event cache should be empty!
+        assertTrue(eventCacheSize() == 0);
+
+        // Resolve the service
+        clearEventCache();
+        mNsdManager.resolveService(si, mResolveListener);
+        lastEvent = waitForCallback("onServiceResolved");                   // id = 4
+
+        assertNotNull(mResolvedService);
+
+        // Check Txt attributes
+        assertEquals(8, mResolvedService.getAttributes().size());
+        assertTrue(mResolvedService.getAttributes().containsKey("booleanAttr"));
+        assertNull(mResolvedService.getAttributes().get("booleanAttr"));
+        assertEquals("value", new String(mResolvedService.getAttributes().get("keyValueAttr")));
+        assertEquals("=", new String(mResolvedService.getAttributes().get("keyEqualsAttr")));
+        assertEquals(" value ", new String(mResolvedService.getAttributes()
+                .get(" whiteSpaceKeyValueAttr ")));
+        assertEquals(String256.substring(9), new String(mResolvedService.getAttributes()
+                .get("longkey")));
+        assertTrue(Arrays.equals(testByteArray,
+                mResolvedService.getAttributes().get("binaryDataAttr")));
+        assertTrue(mResolvedService.getAttributes().containsKey("nullBinaryDataAttr"));
+        assertNull(mResolvedService.getAttributes().get("nullBinaryDataAttr"));
+        assertTrue(mResolvedService.getAttributes().containsKey("emptyBinaryDataAttr"));
+        assertNull(mResolvedService.getAttributes().get("emptyBinaryDataAttr"));
+
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+
+        if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": Port = " +
+                String.valueOf(lastEvent.mInfo.getPort()));
+
+        assertTrue(lastEvent.mInfo.getPort() == localPort);
+        assertTrue(eventCacheSize() == 1);
+
+        checkForAdditionalEvents();
+        clearEventCache();
+
+        // Unregister the service
+        mNsdManager.unregisterService(mRegistrationListener);
+        lastEvent = waitForCallback("onServiceUnregistered");               // id = 5
+
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+
+        // Expect a callback for service lost
+        lastEvent = waitForCallback("onServiceLost");                       // id = 6
+
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName));
+
+        // Register service again to see if we discover it
+        checkForAdditionalEvents();
+        clearEventCache();
+
+        si = new NsdServiceInfo();
+        si.setServiceType(SERVICE_TYPE);
+        si.setServiceName(mServiceName);
+        si.setPort(localPort);
+
+        // Create a new registration listener and register same service again
+        initRegistrationListener();
+
+        mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
+
+        lastEvent = waitForCallback("onServiceRegistered");                 // id = 7
+
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+
+        registeredName = lastEvent.mInfo.getServiceName();
+
+        // Expect a record to be discovered
+        // Expect a service record to be discovered (and filter the ones
+        // that are unrelated to this test)
+        found = false;
+        for (int i = 0; i < 32; i++) {
+
+            lastEvent = waitForCallback("onServiceFound");                  // id = 8
+            if (lastEvent == null) {
+                // no more onServiceFound events are being reported!
+                break;
+            }
+
+            assertTrue(lastEvent.mSucceeded);
+
+            if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " +
+                    lastEvent.mInfo.getServiceName());
+
+            if (lastEvent.mInfo.getServiceName().equals(registeredName)) {
+                // Save it, as it will get overwritten with new serviceFound events
+                si = lastEvent.mInfo;
+                found = true;
+            }
+
+            // Remove this event from the event cache, so it won't be found by subsequent
+            // calls to waitForCallback
+            synchronized (mEventCache) {
+                mEventCache.remove(lastEvent);
+            }
+        }
+
+        assertTrue(found);
+
+        // Resolve the service
+        clearEventCache();
+        mNsdManager.resolveService(si, mResolveListener);
+        lastEvent = waitForCallback("onServiceResolved");                   // id = 9
+
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+
+        if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " +
+                lastEvent.mInfo.getServiceName());
+
+        assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName));
+
+        assertNotNull(mResolvedService);
+
+        // Check that we don't have any TXT records
+        assertEquals(0, mResolvedService.getAttributes().size());
+
+        checkForAdditionalEvents();
+        clearEventCache();
+
+        mNsdManager.stopServiceDiscovery(mDiscoveryListener);
+        lastEvent = waitForCallback("onDiscoveryStopped");                  // id = 10
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+        assertTrue(checkCacheSize(1));
+
+        checkForAdditionalEvents();
+        clearEventCache();
+
+        mNsdManager.unregisterService(mRegistrationListener);
+
+        lastEvent =  waitForCallback("onServiceUnregistered");              // id = 11
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+        assertTrue(checkCacheSize(1));
+    }
+
+    boolean checkCacheSize(int size) {
+        synchronized (mEventCache) {
+            int cacheSize = mEventCache.size();
+            if (cacheSize != size) {
+                Log.d(TAG, "id = " + mWaitId + ": event cache size = " + cacheSize);
+                for (int i = 0; i < cacheSize; i++) {
+                    EventData e = mEventCache.get(i);
+                    String sname = (e.mInfo != null) ? "(" + e.mInfo.getServiceName() + ")" : "";
+                    Log.d(TAG, "eventName is " + e.mCallbackName + sname);
+                }
+            }
+            return (cacheSize == size);
+        }
+    }
+
+    boolean checkForAdditionalEvents() {
+        try {
+            EventData e = waitForNewEvents();
+            if (e != null) {
+                String sname = (e.mInfo != null) ? "(" + e.mInfo.getServiceName() + ")" : "";
+                Log.d(TAG, "ignoring unexpected event " + e.mCallbackName + sname);
+            }
+            return (e == null);
+        }
+        catch (InterruptedException ex) {
+            return false;
+        }
+    }
+}
+
diff --git a/tests/cts/net/util/Android.bp b/tests/cts/net/util/Android.bp
index c36d976..88a2068 100644
--- a/tests/cts/net/util/Android.bp
+++ b/tests/cts/net/util/Android.bp
@@ -15,6 +15,10 @@
 //
 
 // Common utilities for cts net tests.
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 java_library {
     name: "cts-net-utils",
     srcs: ["java/**/*.java", "java/**/*.kt"],
@@ -23,4 +27,4 @@
         "junit",
         "net-tests-utils",
     ],
-}
\ No newline at end of file
+}
diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
index 0527011..88172d7 100644
--- a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
+++ b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
@@ -212,7 +212,7 @@
         mContext.registerReceiver(receiver, filter);
 
         boolean connected = false;
-        final String err = "Wifi must be configured to connect to an access point for this test.";
+        final String err = "Wifi must be configured to connect to an access point for this test";
         try {
             clearWifiBlacklist();
             SystemUtil.runShellCommand("svc wifi enable");
@@ -235,7 +235,7 @@
             }
             // Ensure we get an onAvailable callback and possibly a CONNECTIVITY_ACTION.
             wifiNetwork = callback.waitForAvailable();
-            assertNotNull(err, wifiNetwork);
+            assertNotNull(err + ": onAvailable callback not received", wifiNetwork);
             connected = !expectLegacyBroadcast || receiver.waitForState();
         } catch (InterruptedException ex) {
             fail("connectToWifi was interrupted");
@@ -244,7 +244,7 @@
             mContext.unregisterReceiver(receiver);
         }
 
-        assertTrue(err, connected);
+        assertTrue(err + ": CONNECTIVITY_ACTION not received", connected);
         return wifiNetwork;
     }
 
diff --git a/tests/cts/tethering/Android.bp b/tests/cts/tethering/Android.bp
index b1d4a60..824c874 100644
--- a/tests/cts/tethering/Android.bp
+++ b/tests/cts/tethering/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 android_test {
     name: "CtsTetheringTest",
     defaults: ["cts_defaults"],