summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Haijie Hong <hahong@google.com> 2025-03-16 20:26:14 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2025-03-16 20:26:14 -0700
commit77bd5555fb8c1ed269139449a4893cbb293c24a6 (patch)
tree1259c6e5ee3513446f210546506d1e6cf870d353
parent084f6ced41f860f06e50e316f9e8d2bce1df5388 (diff)
parentc96ee67020cad6a52276bc6ba400cde2ca927cbc (diff)
Merge "Send opp uri information to device picker and nearby component" into main
-rw-r--r--android/app/src/com/android/bluetooth/BluetoothMethodProxy.java5
-rw-r--r--android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java15
-rw-r--r--android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java31
-rw-r--r--android/app/tests/instrumentation/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java25
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java19
-rw-r--r--flags/opp.aconfig17
-rw-r--r--framework/api/system-current.txt1
-rw-r--r--framework/java/android/bluetooth/BluetoothDevicePicker.java11
8 files changed, 124 insertions, 0 deletions
diff --git a/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java b/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java
index d4fc9d54e8..a4c265adf7 100644
--- a/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java
+++ b/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java
@@ -306,4 +306,9 @@ public class BluetoothMethodProxy {
ComponentCaller caller, Uri uri, int modeFlags) {
return caller.checkContentUriPermission(uri, modeFlags);
}
+
+ /** Proxies {@link Context#grantUriPermission(String, Uri, int)}. } */
+ public void grantUriPermission(Context context, String packageName, Uri uri, int modeFlags) {
+ context.grantUriPermission(packageName, uri, modeFlags);
+ }
}
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
index 048c134848..73cba4e954 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
@@ -248,6 +248,12 @@ public class BluetoothOppLauncherActivity extends Activity {
permittedUris,
false /* isHandover */,
true /* fromExternal */);
+ if (Flags.sendOppDevicePickerExtraIntent()) {
+ BluetoothOppUtility
+ .grantPermissionToNearbyComponent(
+ BluetoothOppLauncherActivity.this,
+ uris);
+ }
// Done getting file info..Launch device picker
// and finish this activity
launchDevicePicker();
@@ -322,6 +328,11 @@ public class BluetoothOppLauncherActivity extends Activity {
in1.putExtra(BluetoothDevicePicker.EXTRA_LAUNCH_PACKAGE, getPackageName());
in1.putExtra(
BluetoothDevicePicker.EXTRA_LAUNCH_CLASS, BluetoothOppReceiver.class.getName());
+ if (Flags.sendOppDevicePickerExtraIntent()) {
+ in1.putExtra(
+ BluetoothDevicePicker.EXTRA_DEVICE_PICKER_ORIGINAL_SEND_INTENT,
+ getIntent());
+ }
Log.v(TAG, "Launching " + BluetoothDevicePicker.ACTION_LAUNCH);
startActivity(in1);
}
@@ -555,6 +566,10 @@ public class BluetoothOppLauncherActivity extends Activity {
void sendFileInfo(String mimeType, String uriString, boolean isHandover, boolean fromExternal) {
BluetoothOppManager manager = BluetoothOppManager.getInstance(getApplicationContext());
try {
+ if (Flags.sendOppDevicePickerExtraIntent()) {
+ BluetoothOppUtility.grantPermissionToNearbyComponent(
+ this, List.of(Uri.parse(uriString)));
+ }
manager.saveSendingFileInfo(mimeType, uriString, isHandover, fromExternal);
launchDevicePicker();
finish();
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java
index d7b75bfde2..4e8892ab35 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java
@@ -38,6 +38,7 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProtoEnums;
import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
@@ -50,6 +51,7 @@ import android.net.Uri;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.os.SystemProperties;
+import android.provider.Settings;
import android.util.EventLog;
import android.util.Log;
@@ -77,6 +79,9 @@ import java.util.concurrent.ConcurrentHashMap;
public class BluetoothOppUtility {
private static final String TAG = BluetoothOppUtility.class.getSimpleName();
+ // TODO(b/398120192): use API instead of a hardcode string.
+ private static final String NEARBY_SHARING_COMPONENT = "nearby_sharing_component";
+
/** Whether the device has the "nosdcard" characteristic, or null if not-yet-known. */
private static Boolean sNoSdCard = null;
@@ -572,4 +577,30 @@ public class BluetoothOppUtility {
NotificationManager nm = ctx.getSystemService(NotificationManager.class);
nm.cancel(BluetoothOppNotification.NOTIFICATION_ID_PROGRESS);
}
+
+ /** Grants uri read permission to nearby sharing component. */
+ static void grantPermissionToNearbyComponent(Context context, List<Uri> uris) {
+ String packageName = getNearbyComponentPackageName(context);
+ if (packageName == null) {
+ return;
+ }
+ for (Uri uri : uris) {
+ BluetoothMethodProxy.getInstance()
+ .grantUriPermission(
+ context, packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ }
+ }
+
+ private static String getNearbyComponentPackageName(Context context) {
+ String componentString =
+ Settings.Secure.getString(context.getContentResolver(), NEARBY_SHARING_COMPONENT);
+ if (componentString == null) {
+ return null;
+ }
+ ComponentName componentName = ComponentName.unflattenFromString(componentString);
+ if (componentName == null) {
+ return null;
+ }
+ return componentName.getPackageName();
+ }
}
diff --git a/android/app/tests/instrumentation/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java b/android/app/tests/instrumentation/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java
index fd9531105b..7bb7bbfbc3 100644
--- a/android/app/tests/instrumentation/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java
+++ b/android/app/tests/instrumentation/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java
@@ -46,6 +46,7 @@ import android.net.Uri;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
+import android.provider.Settings;
import android.sysprop.BluetoothProperties;
import androidx.lifecycle.Lifecycle;
@@ -382,6 +383,30 @@ public class BluetoothOppLauncherActivityTest {
assertThat(argument.getValue().getData()).isEqualTo(Uri.EMPTY);
}
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_SEND_OPP_DEVICE_PICKER_EXTRA_INTENT)
+ public void onCreate_withActionSend_grantUriPermissionToNearbyComponent() {
+ doReturn(true).when(mMethodProxy).bluetoothAdapterIsEnabled(any());
+ doReturn(PackageManager.PERMISSION_GRANTED)
+ .when(mMethodProxy)
+ .componentCallerCheckContentUriPermission(any(), any(), anyInt());
+ String uriString = "content://test.provider/1";
+ Settings.Secure.putString(
+ mTargetContext.getContentResolver(),
+ "nearby_sharing_component",
+ "com.example/.BComponent");
+
+ ActivityScenario<BluetoothOppLauncherActivity> unused =
+ ActivityScenario.launch(createSendIntent(uriString));
+
+ verify(mMethodProxy)
+ .grantUriPermission(
+ any(),
+ eq("com.example"),
+ eq(Uri.parse(uriString)),
+ eq(Intent.FLAG_GRANT_READ_URI_PERMISSION));
+ }
+
@Ignore("b/263724420")
@Test
public void launchDevicePicker_bluetoothNotEnabled_launchEnableActivity() throws Exception {
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java
index 705c91d518..cadff94862 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java
@@ -44,6 +44,7 @@ import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
+import android.provider.Settings;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -432,4 +433,22 @@ public class BluetoothOppUtilityTest {
assertWithMessage("Exception should not happen. " + e).fail();
}
}
+
+ @Test
+ public void grantPermissionToNearbyComponent() {
+ Uri originalUri = Uri.parse("content://test.provider/1");
+ Settings.Secure.putString(
+ mContext.getContentResolver(),
+ "nearby_sharing_component",
+ "com.example/.BComponent");
+ Context spiedContext = spy(new ContextWrapper(mContext));
+
+ BluetoothOppUtility.grantPermissionToNearbyComponent(spiedContext, List.of(originalUri));
+
+ verify(spiedContext)
+ .grantUriPermission(
+ eq("com.example"),
+ eq(originalUri),
+ eq(Intent.FLAG_GRANT_READ_URI_PERMISSION));
+ }
}
diff --git a/flags/opp.aconfig b/flags/opp.aconfig
index 73604961fe..6d1a13bf21 100644
--- a/flags/opp.aconfig
+++ b/flags/opp.aconfig
@@ -41,3 +41,20 @@ flag {
}
}
+flag {
+ name: "opp_device_picker_extra_intent_apis"
+ is_exported: true
+ namespace: "bluetooth"
+ description: "New API to get the original intent in Bluetooth Device Picker"
+ bug: "395796600"
+}
+
+flag {
+ name: "send_opp_device_picker_extra_intent"
+ namespace: "bluetooth"
+ description: "Send the original intent when opening Bluetooth device picker"
+ bug: "397852103"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index cdb9bf0670..ef922c92e1 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -369,6 +369,7 @@ package android.bluetooth {
public interface BluetoothDevicePicker {
field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_DEVICE_SELECTED = "android.bluetooth.devicepicker.action.DEVICE_SELECTED";
field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_LAUNCH = "android.bluetooth.devicepicker.action.LAUNCH";
+ field @FlaggedApi("com.android.bluetooth.flags.opp_device_picker_extra_intent_apis") public static final String EXTRA_DEVICE_PICKER_ORIGINAL_SEND_INTENT = "android.bluetooth.extra.DEVICE_PICKER_ORIGINAL_SEND_INTENT";
field public static final String EXTRA_FILTER_TYPE = "android.bluetooth.devicepicker.extra.FILTER_TYPE";
field public static final String EXTRA_LAUNCH_CLASS = "android.bluetooth.devicepicker.extra.DEVICE_PICKER_LAUNCH_CLASS";
field public static final String EXTRA_LAUNCH_PACKAGE = "android.bluetooth.devicepicker.extra.LAUNCH_PACKAGE";
diff --git a/framework/java/android/bluetooth/BluetoothDevicePicker.java b/framework/java/android/bluetooth/BluetoothDevicePicker.java
index ee788dae18..7e7cd6d6b7 100644
--- a/framework/java/android/bluetooth/BluetoothDevicePicker.java
+++ b/framework/java/android/bluetooth/BluetoothDevicePicker.java
@@ -18,6 +18,7 @@ package android.bluetooth;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import android.annotation.FlaggedApi;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
@@ -25,6 +26,8 @@ import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
+import com.android.bluetooth.flags.Flags;
+
/**
* A helper to show a system "Device Picker" activity to the user.
*
@@ -64,6 +67,14 @@ public interface BluetoothDevicePicker {
String EXTRA_LAUNCH_CLASS = "android.bluetooth.devicepicker.extra.DEVICE_PICKER_LAUNCH_CLASS";
/**
+ * Extra for the original ACTION_SEND or ACTION_SEND_MULTIPLE intent that triggered the BT
+ * sharing.
+ */
+ @FlaggedApi(Flags.FLAG_OPP_DEVICE_PICKER_EXTRA_INTENT_APIS)
+ String EXTRA_DEVICE_PICKER_ORIGINAL_SEND_INTENT =
+ "android.bluetooth.extra.DEVICE_PICKER_ORIGINAL_SEND_INTENT";
+
+ /**
* Broadcast when one BT device is selected from BT device picker screen. Selected {@link
* BluetoothDevice} is returned in extra data named {@link BluetoothDevice#EXTRA_DEVICE}.
*/