Merge "Enforce permission check in NearbyService" 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 b7479ac..9073f78 100644
--- a/nearby/framework/java/android/nearby/NearbyManager.java
+++ b/nearby/framework/java/android/nearby/NearbyManager.java
@@ -114,6 +114,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/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/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index eb7d1ea..e4a9ebe 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
@@ -916,7 +916,7 @@
final Intent intent = new Intent();
if (type == TYPE_COMPONENT_ACTIVTIY) {
intent.setComponent(new ComponentName(TEST_APP2_PKG, TEST_APP2_ACTIVITY_CLASS))
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
} else if (type == TYPE_COMPONENT_FOREGROUND_SERVICE) {
intent.setComponent(new ComponentName(TEST_APP2_PKG, TEST_APP2_SERVICE_CLASS))
.setFlags(1);
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnOnActivityStartTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnOnActivityStartTest.java
new file mode 100644
index 0000000..098f295
--- /dev/null
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnOnActivityStartTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 static com.android.cts.net.hostside.NetworkPolicyTestUtils.getUiDevice;
+import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground;
+import static com.android.cts.net.hostside.Property.APP_STANDBY_MODE;
+import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE;
+import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE;
+import static com.android.cts.net.hostside.Property.DOZE_MODE;
+import static com.android.cts.net.hostside.Property.METERED_NETWORK;
+import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK;
+
+import android.util.Log;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+@RequiredProperties({NON_METERED_NETWORK})
+public class ConnOnActivityStartTest extends AbstractRestrictBackgroundNetworkTestCase {
+ private static final int TEST_ITERATION_COUNT = 5;
+
+ @Before
+ public final void setUp() throws Exception {
+ super.setUp();
+ resetDeviceState();
+ }
+
+ @After
+ public final void tearDown() throws Exception {
+ super.tearDown();
+ resetDeviceState();
+ }
+
+ private void resetDeviceState() throws Exception {
+ resetBatteryState();
+ setBatterySaverMode(false);
+ setRestrictBackground(false);
+ setAppIdle(false);
+ setDozeMode(false);
+ }
+
+
+ @Test
+ @RequiredProperties({BATTERY_SAVER_MODE})
+ public void testStartActivity_batterySaver() throws Exception {
+ setBatterySaverMode(true);
+ assertLaunchedActivityHasNetworkAccess("testStartActivity_batterySaver");
+ }
+
+ @Test
+ @RequiredProperties({DATA_SAVER_MODE, METERED_NETWORK})
+ public void testStartActivity_dataSaver() throws Exception {
+ setRestrictBackground(true);
+ assertLaunchedActivityHasNetworkAccess("testStartActivity_dataSaver");
+ }
+
+ @Test
+ @RequiredProperties({DOZE_MODE})
+ public void testStartActivity_doze() throws Exception {
+ setDozeMode(true);
+ assertLaunchedActivityHasNetworkAccess("testStartActivity_doze");
+ }
+
+ @Test
+ @RequiredProperties({APP_STANDBY_MODE})
+ public void testStartActivity_appStandby() throws Exception {
+ turnBatteryOn();
+ setAppIdle(true);
+ assertLaunchedActivityHasNetworkAccess("testStartActivity_appStandby");
+ }
+
+ private void assertLaunchedActivityHasNetworkAccess(String testName) throws Exception {
+ for (int i = 0; i < TEST_ITERATION_COUNT; ++i) {
+ Log.i(TAG, testName + " start #" + i);
+ launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
+ getUiDevice().pressHome();
+ assertBackgroundState();
+ Log.i(TAG, testName + " end #" + i);
+ }
+ }
+}
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 0a0f24b..7842eec 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
@@ -57,6 +57,7 @@
import android.util.Log;
import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.uiautomator.UiDevice;
import com.android.compatibility.common.util.AppStandbyUtils;
import com.android.compatibility.common.util.BatteryUtils;
@@ -438,6 +439,10 @@
return InstrumentationRegistry.getInstrumentation();
}
+ public static UiDevice getUiDevice() {
+ return UiDevice.getInstance(getInstrumentation());
+ }
+
// When power saver mode or restrict background enabled or adding any white/black list into
// those modes, NetworkPolicy may need to take some time to update the rules of uids. So having
// this function and using PollingCheck to try to make sure the uid has updated and reduce the
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
index eb7dca7..a337fe2 100644
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
+++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
@@ -39,6 +39,33 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "MyActivity.onCreate()");
+ }
+
+ @Override
+ public void finish() {
+ if (finishCommandReceiver != null) {
+ unregisterReceiver(finishCommandReceiver);
+ }
+ super.finish();
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ Log.d(TAG, "MyActivity.onStart()");
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ Log.d(TAG, "MyActivity.onNewIntent()");
+ setIntent(intent);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ Log.d(TAG, "MyActivity.onResume(): " + getIntent());
Common.notifyNetworkStateObserver(this, getIntent(), TYPE_COMPONENT_ACTIVTY);
finishCommandReceiver = new BroadcastReceiver() {
@Override
@@ -57,20 +84,6 @@
}
@Override
- public void finish() {
- if (finishCommandReceiver != null) {
- unregisterReceiver(finishCommandReceiver);
- }
- super.finish();
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- Log.d(TAG, "MyActivity.onStart()");
- }
-
- @Override
protected void onDestroy() {
Log.d(TAG, "MyActivity.onDestroy()");
super.onDestroy();
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideConnOnActivityStartTest.java b/tests/cts/hostside/src/com/android/cts/net/HostsideConnOnActivityStartTest.java
new file mode 100644
index 0000000..3387fd7
--- /dev/null
+++ b/tests/cts/hostside/src/com/android/cts/net/HostsideConnOnActivityStartTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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;
+
+public class HostsideConnOnActivityStartTest extends HostsideNetworkTestCase {
+ private static final String TEST_CLASS = TEST_PKG + ".ConnOnActivityStartTest";
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ uninstallPackage(TEST_APP2_PKG, false);
+ installPackage(TEST_APP2_APK);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ uninstallPackage(TEST_APP2_PKG, true);
+ }
+
+ public void testStartActivity_batterySaver() throws Exception {
+ runDeviceTests(TEST_PKG, TEST_CLASS, "testStartActivity_batterySaver");
+ }
+
+ public void testStartActivity_dataSaver() throws Exception {
+ runDeviceTests(TEST_PKG, TEST_CLASS, "testStartActivity_dataSaver");
+ }
+
+ public void testStartActivity_doze() throws Exception {
+ runDeviceTests(TEST_PKG, TEST_CLASS, "testStartActivity_doze");
+ }
+
+ public void testStartActivity_appStandby() throws Exception {
+ runDeviceTests(TEST_PKG, TEST_CLASS, "testStartActivity_appStandby");
+ }
+}