Merge "Add tests to verify app has network access in onResume." into tm-dev
diff --git a/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java b/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java
index 1ad3571..a9d7cf7 100644
--- a/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java
+++ b/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java
@@ -20,7 +20,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.bluetooth.le.ScanRecord;
-import android.bluetooth.le.ScanResult;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -89,6 +88,7 @@
     @Nullable private final String mBluetoothAddress;
     @Nullable private final String mFastPairModelId;
     @Nullable private final byte[] mData;
+    @Nullable private final byte[] mSalt;
 
     private NearbyDeviceParcelable(
             @ScanRequest.ScanType int scanType,
@@ -100,7 +100,8 @@
             PublicCredential publicCredential,
             @Nullable String fastPairModelId,
             @Nullable String bluetoothAddress,
-            @Nullable byte[] data) {
+            @Nullable byte[] data,
+            @Nullable byte[] salt) {
         mScanType = scanType;
         mName = name;
         mMedium = medium;
@@ -111,6 +112,7 @@
         mFastPairModelId = fastPairModelId;
         mBluetoothAddress = bluetoothAddress;
         mData = data;
+        mSalt = salt;
     }
 
     /** No special parcel contents. */
@@ -149,6 +151,11 @@
             dest.writeInt(mData.length);
             dest.writeByteArray(mData);
         }
+        dest.writeInt(mSalt == null ? 0 : 1);
+        if (mSalt != null) {
+            dest.writeInt(mSalt.length);
+            dest.writeByteArray(mSalt);
+        }
     }
 
     /** Returns a string representation of this ScanRequest. */
@@ -171,6 +178,8 @@
                 + mFastPairModelId
                 + ", data="
                 + Arrays.toString(mData)
+                + ", salt="
+                + Arrays.toString(mSalt)
                 + "]";
     }
 
@@ -189,7 +198,8 @@
                             mBluetoothAddress, otherNearbyDeviceParcelable.mBluetoothAddress))
                     && (Objects.equals(
                             mFastPairModelId, otherNearbyDeviceParcelable.mFastPairModelId))
-                    && (Arrays.equals(mData, otherNearbyDeviceParcelable.mData));
+                    && (Arrays.equals(mData, otherNearbyDeviceParcelable.mData))
+                    && (Arrays.equals(mSalt, otherNearbyDeviceParcelable.mSalt));
         }
         return false;
     }
@@ -204,7 +214,8 @@
                 mPublicCredential.hashCode(),
                 mBluetoothAddress,
                 mFastPairModelId,
-                Arrays.hashCode(mData));
+                Arrays.hashCode(mData),
+                Arrays.hashCode(mSalt));
     }
 
     /**
@@ -217,7 +228,11 @@
         return mScanType;
     }
 
-    /** Gets the name of the NearbyDeviceParcelable. Returns {@code null} If there is no name. */
+    /**
+     * Gets the name of the NearbyDeviceParcelable. Returns {@code null} If there is no name.
+     *
+     * Used in Fast Pair.
+     */
     @Nullable
     public String getName() {
         return mName;
@@ -226,6 +241,8 @@
     /**
      * Gets the {@link android.nearby.NearbyDevice.Medium} of the NearbyDeviceParcelable over which
      * it is discovered.
+     *
+     * Used in Fast Pair and Nearby Presence.
      */
     @NearbyDevice.Medium
     public int getMedium() {
@@ -235,6 +252,8 @@
     /**
      * Gets the transmission power in dBm.
      *
+     * Used in Fast Pair.
+     *
      * @hide
      */
     @IntRange(from = -127, to = 126)
@@ -242,7 +261,11 @@
         return mTxPower;
     }
 
-    /** Gets the received signal strength in dBm. */
+    /**
+     * Gets the received signal strength in dBm.
+     *
+     * Used in Fast Pair and Nearby Presence.
+     */
     @IntRange(from = -127, to = 126)
     public int getRssi() {
         return mRssi;
@@ -251,6 +274,8 @@
     /**
      * Gets the Action.
      *
+     * Used in Nearby Presence.
+     *
      * @hide
      */
     @IntRange(from = -127, to = 126)
@@ -261,6 +286,8 @@
     /**
      * Gets the public credential.
      *
+     * Used in Nearby Presence.
+     *
      * @hide
      */
     @NonNull
@@ -271,6 +298,8 @@
     /**
      * Gets the Fast Pair identifier. Returns {@code null} if there is no Model ID or this is not a
      * Fast Pair device.
+     *
+     * Used in Fast Pair.
      */
     @Nullable
     public String getFastPairModelId() {
@@ -280,18 +309,36 @@
     /**
      * Gets the Bluetooth device hardware address. Returns {@code null} if the device is not
      * discovered by Bluetooth.
+     *
+     * Used in Fast Pair.
      */
     @Nullable
     public String getBluetoothAddress() {
         return mBluetoothAddress;
     }
 
-    /** Gets the raw data from the scanning. Returns {@code null} if there is no extra data. */
+    /**
+     * Gets the raw data from the scanning.
+     * Returns {@code null} if there is no extra data or this is not a Fast Pair device.
+     *
+     * Used in Fast Pair.
+     */
     @Nullable
     public byte[] getData() {
         return mData;
     }
 
+    /**
+     * Gets the salt in the advertisement from the Nearby Presence device.
+     * Returns {@code null} if this is not a Nearby Presence device.
+     *
+     * Used in Nearby Presence.
+     */
+    @Nullable
+    public byte[] getSalt() {
+        return mSalt;
+    }
+
     /** Builder class for {@link NearbyDeviceParcelable}. */
     public static final class Builder {
         @Nullable private String mName;
@@ -304,6 +351,7 @@
         @Nullable private String mFastPairModelId;
         @Nullable private String mBluetoothAddress;
         @Nullable private byte[] mData;
+        @Nullable private byte[] mSalt;
 
         /**
          * Sets the scan type of the NearbyDeviceParcelable.
@@ -410,7 +458,7 @@
          * Sets the scanned raw data.
          *
          * @param data Data the scan. For example, {@link ScanRecord#getServiceData()} if scanned by
-         *     Bluetooth.
+         *             Bluetooth.
          */
         @NonNull
         public Builder setData(@Nullable byte[] data) {
@@ -418,6 +466,17 @@
             return this;
         }
 
+        /**
+         * Sets the slat in the advertisement from the Nearby Presence device.
+         *
+         * @param salt in the advertisement from the Nearby Presence device.
+         */
+        @NonNull
+        public Builder setSalt(@Nullable byte[] salt) {
+            mSalt = salt;
+            return this;
+        }
+
         /** Builds a ScanResult. */
         @NonNull
         public NearbyDeviceParcelable build() {
@@ -431,7 +490,8 @@
                     mPublicCredential,
                     mFastPairModelId,
                     mBluetoothAddress,
-                    mData);
+                    mData,
+                    mSalt);
         }
     }
 }
diff --git a/nearby/framework/java/android/nearby/NearbyManager.java b/nearby/framework/java/android/nearby/NearbyManager.java
index 3dd08da..4177f6a 100644
--- a/nearby/framework/java/android/nearby/NearbyManager.java
+++ b/nearby/framework/java/android/nearby/NearbyManager.java
@@ -109,6 +109,26 @@
                     .setBluetoothAddress(nearbyDeviceParcelable.getBluetoothAddress())
                     .setData(nearbyDeviceParcelable.getData()).build();
         }
+
+        if (scanType == ScanRequest.SCAN_TYPE_NEARBY_PRESENCE) {
+            PublicCredential publicCredential = nearbyDeviceParcelable.getPublicCredential();
+            if (publicCredential == null) {
+                return null;
+            }
+            byte[] salt = nearbyDeviceParcelable.getSalt();
+            if (salt == null) {
+                salt = new byte[0];
+            }
+            return new PresenceDevice.Builder(
+                    // Use the public credential hash as the device Id.
+                    String.valueOf(publicCredential.hashCode()),
+                    salt,
+                    publicCredential.getSecretId(),
+                    publicCredential.getEncryptedMetadata())
+                    .setRssi(nearbyDeviceParcelable.getRssi())
+                    .addMedium(nearbyDeviceParcelable.getMedium())
+                    .build();
+        }
         return null;
     }
 
diff --git a/nearby/framework/java/android/nearby/PresenceDevice.java b/nearby/framework/java/android/nearby/PresenceDevice.java
index 12fc2a3..cb406e4 100644
--- a/nearby/framework/java/android/nearby/PresenceDevice.java
+++ b/nearby/framework/java/android/nearby/PresenceDevice.java
@@ -268,6 +268,11 @@
          */
         public Builder(@NonNull String deviceId, @NonNull byte[] salt, @NonNull byte[] secretId,
                 @NonNull byte[] encryptedIdentity) {
+            Objects.requireNonNull(deviceId);
+            Objects.requireNonNull(salt);
+            Objects.requireNonNull(secretId);
+            Objects.requireNonNull(encryptedIdentity);
+
             mDeviceId = deviceId;
             mSalt = salt;
             mSecretId = secretId;
diff --git a/nearby/service/java/com/android/server/nearby/presence/PresenceDiscoveryResult.java b/nearby/service/java/com/android/server/nearby/presence/PresenceDiscoveryResult.java
index 80ad88d..d1c72ae 100644
--- a/nearby/service/java/com/android/server/nearby/presence/PresenceDiscoveryResult.java
+++ b/nearby/service/java/com/android/server/nearby/presence/PresenceDiscoveryResult.java
@@ -30,9 +30,14 @@
 
     /** Creates a {@link PresenceDiscoveryResult} from the scan data. */
     public static PresenceDiscoveryResult fromDevice(NearbyDeviceParcelable device) {
+        byte[] salt = device.getSalt();
+        if (salt == null) {
+            salt = new byte[0];
+        }
         return new PresenceDiscoveryResult.Builder()
                 .setTxPower(device.getTxPower())
                 .setRssi(device.getRssi())
+                .setSalt(salt)
                 .addPresenceAction(device.getAction())
                 .setPublicCredential(device.getPublicCredential())
                 .build();
diff --git a/nearby/service/java/com/android/server/nearby/provider/BleBroadcastProvider.java b/nearby/service/java/com/android/server/nearby/provider/BleBroadcastProvider.java
index 3602787..67392ad 100644
--- a/nearby/service/java/com/android/server/nearby/provider/BleBroadcastProvider.java
+++ b/nearby/service/java/com/android/server/nearby/provider/BleBroadcastProvider.java
@@ -25,8 +25,8 @@
 import android.os.ParcelUuid;
 
 import com.android.server.nearby.injector.Injector;
-import com.android.server.nearby.presence.PresenceConstants;
 
+import java.util.UUID;
 import java.util.concurrent.Executor;
 
 /**
@@ -69,11 +69,13 @@
                                 .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM)
                                 .setConnectable(true)
                                 .build();
+
+                // TODO(b/230538655) Use empty data until Presence V1 protocol is implemented.
+                ParcelUuid emptyParcelUuid = new ParcelUuid(new UUID(0L, 0L));
+                byte[] emptyAdvertisementPackets = new byte[0];
                 AdvertiseData advertiseData =
                         new AdvertiseData.Builder()
-                                .addServiceData(new ParcelUuid(PresenceConstants.PRESENCE_UUID),
-                                        advertisementPackets).build();
-
+                                .addServiceData(emptyParcelUuid, emptyAdvertisementPackets).build();
                 try {
                     mBroadcastListener = listener;
                     bluetoothLeAdvertiser.startAdvertising(settings, advertiseData, this);
diff --git a/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java b/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java
index a70ef13..f20c6d8 100644
--- a/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java
+++ b/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java
@@ -33,11 +33,11 @@
 
 import com.google.protobuf.InvalidProtocolBufferException;
 
-import service.proto.Blefilter;
-
 import java.util.Collections;
 import java.util.concurrent.Executor;
 
+import service.proto.Blefilter;
+
 /** Discovery provider that uses CHRE Nearby Nanoapp to do scanning. */
 public class ChreDiscoveryProvider extends AbstractDiscoveryProvider {
     // Nanoapp ID reserved for Nearby Presence.
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
index b9ab95f..6b9bce9 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
@@ -80,7 +80,7 @@
                         "NearbyDeviceParcelable[name=testDevice, medium=BLE, txPower=0, rssi=-60,"
                                 + " action=0, bluetoothAddress="
                                 + BLUETOOTH_ADDRESS
-                                + ", fastPairModelId=null, data=null]");
+                                + ", fastPairModelId=null, data=null, salt=null]");
     }
 
     @Test
diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java
index c6fc38f..0c53411 100644
--- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java
+++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java
@@ -49,6 +49,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.platform.test.annotations.AppModeFull;
+import android.provider.Settings;
 import android.system.ErrnoException;
 import android.util.Log;
 
@@ -727,6 +728,18 @@
 
     @Test
     public void testPrivateDnsBypass() throws InterruptedException {
+        final String dataStallSetting = Settings.Global.getString(mCR,
+                Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK);
+        Settings.Global.putInt(mCR, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
+        try {
+            doTestPrivateDnsBypass();
+        } finally {
+            Settings.Global.putString(mCR, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK,
+                    dataStallSetting);
+        }
+    }
+
+    private void doTestPrivateDnsBypass() throws InterruptedException {
         final Network[] testNetworks = getTestableNetworks();
 
         // Set an invalid private DNS server