RESTRICT AUTOMERGE Fix unable to send file via OPP

Bluetooth app will indicate BluetoothOppReceiver to receive
device picker intent. But for fix the security issue we
removed the setClassName() method in ag/14111132 to avoid attack.
It causes BluetoothOppReceiver cannot receive the intent.

This CL will compare to calling package name with launch package name.
If they are not equal, the setClassName() will not invoke.

Bug: 186490534
Bug: 179386960
Bug: 179386068

Test: make RunSettingsRoboTests -j56
Change-Id: Ia51528f2a44ab73edbc86899ca0846d3262fe1f0
(cherry picked from commit bb5be240c0982f2e098978fec187fc735c0e7ad9)
(cherry picked from commit c556938807b440c54ce3c4e949460a8ac9e67753)
diff --git a/src/com/android/settings/bluetooth/DevicePickerFragment.java b/src/com/android/settings/bluetooth/DevicePickerFragment.java
index f60183b..02b5d5c 100644
--- a/src/com/android/settings/bluetooth/DevicePickerFragment.java
+++ b/src/com/android/settings/bluetooth/DevicePickerFragment.java
@@ -27,12 +27,15 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.UserManager;
+import android.util.Log;
+import android.text.TextUtils;
 import android.view.Menu;
 import android.view.MenuInflater;
 
 import androidx.annotation.VisibleForTesting;
 
 import com.android.settings.R;
+import com.android.settings.password.PasswordUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.core.AbstractPreferenceController;
 
@@ -50,6 +53,12 @@
     BluetoothProgressCategory mAvailableDevicesCategory;
     @VisibleForTesting
     Context mContext;
+    @VisibleForTesting
+    String mLaunchPackage;
+    @VisibleForTesting
+    String mLaunchClass;
+    @VisibleForTesting
+    String mCallingAppPackageName;
 
     private boolean mNeedAuth;
     private boolean mScanAllowed;
@@ -64,6 +73,8 @@
         mNeedAuth = intent.getBooleanExtra(BluetoothDevicePicker.EXTRA_NEED_AUTH, false);
         setFilter(intent.getIntExtra(BluetoothDevicePicker.EXTRA_FILTER_TYPE,
                 BluetoothDevicePicker.FILTER_TYPE_ALL));
+        mLaunchPackage = intent.getStringExtra(BluetoothDevicePicker.EXTRA_LAUNCH_PACKAGE);
+        mLaunchClass = intent.getStringExtra(BluetoothDevicePicker.EXTRA_LAUNCH_CLASS);
         mAvailableDevicesCategory = (BluetoothProgressCategory) findPreference(KEY_BT_DEVICE_LIST);
     }
 
@@ -83,6 +94,12 @@
         getActivity().setTitle(getString(R.string.device_picker));
         UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
         mScanAllowed = !um.hasUserRestriction(DISALLOW_CONFIG_BLUETOOTH);
+        mCallingAppPackageName = PasswordUtils.getCallingAppPackageName(
+                getActivity().getActivityToken());
+        if (!TextUtils.equals(mCallingAppPackageName, mLaunchPackage)) {
+            Log.w(TAG, "sendDevicePickedIntent() launch package name is not equivalent to"
+                    + " calling package name!");
+        }
         mContext = getContext();
         setHasOptionsMenu(true);
     }
@@ -189,6 +206,11 @@
     private void sendDevicePickedIntent(BluetoothDevice device) {
         Intent intent = new Intent(BluetoothDevicePicker.ACTION_DEVICE_SELECTED);
         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+        if (mLaunchPackage != null && mLaunchClass != null) {
+            if (TextUtils.equals(mCallingAppPackageName, mLaunchPackage)) {
+                intent.setClassName(mLaunchPackage, mLaunchClass);
+            }
+        }
 
         mContext.sendBroadcast(intent, Manifest.permission.BLUETOOTH_ADMIN);
     }
diff --git a/tests/robotests/src/com/android/settings/bluetooth/DevicePickerFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/DevicePickerFragmentTest.java
index d9e054d..a05ec87 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/DevicePickerFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/DevicePickerFragmentTest.java
@@ -16,8 +16,11 @@
 
 package com.android.settings.bluetooth;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -66,16 +69,37 @@
     }
 
     @Test
-    public void sendBroadcastWithPermission() {
+    public void callingPackageIsEqualToLaunchPackage_sendBroadcastToLaunchPackage() {
         final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
         final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
         final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
         when(cachedDevice.getDevice()).thenReturn(bluetoothDevice);
         mFragment.mSelectedDevice = bluetoothDevice;
+        mFragment.mLaunchPackage = "com.android.settings";
+        mFragment.mLaunchClass = "com.android.settings.bluetooth.BluetoothPermissionActivity";
+        mFragment.mCallingAppPackageName = "com.android.settings";
 
         mFragment.onDeviceBondStateChanged(cachedDevice, BluetoothDevice.BOND_BONDED);
 
         verify(mContext).sendBroadcast(intentCaptor.capture(),
                 eq("android.permission.BLUETOOTH_ADMIN"));
+        assertThat(intentCaptor.getValue().getComponent().getPackageName())
+                .isEqualTo(mFragment.mLaunchPackage);
+    }
+
+    @Test
+    public void callingPackageIsNotEqualToLaunchPackage_broadcastNotSend() {
+        final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
+        final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
+        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        when(cachedDevice.getDevice()).thenReturn(bluetoothDevice);
+        mFragment.mSelectedDevice = bluetoothDevice;
+        mFragment.mLaunchPackage = "com.fake.settings";
+        mFragment.mLaunchClass = "com.android.settings.bluetooth.BluetoothPermissionActivity";
+        mFragment.mCallingAppPackageName = "com.android.settings";
+
+        mFragment.onDeviceBondStateChanged(cachedDevice, BluetoothDevice.BOND_BONDED);
+
+        verify(mContext, never()).sendBroadcast(intentCaptor.capture());
     }
 }