Loading aconfig/settings_connecteddevice_flag_declarations.aconfig +11 −0 Original line number Diff line number Diff line Loading @@ -14,3 +14,14 @@ flag { description: "Gates whether to require an auth challenge for changing USB preferences" bug: "317367746" } flag { name: "enable_bonded_bluetooth_device_searchable" namespace: "pixel_cross_device_control" description: "Set bonded bluetooth devices under connected devices page to be searchable by Settings search." bug: "319056077" metadata { purpose: PURPOSE_BUGFIX } } No newline at end of file src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java +41 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import android.content.Context; import android.content.pm.PackageManager; import android.hardware.input.InputManager; import android.util.FeatureFlagUtils; import android.util.Log; import android.view.InputDevice; import androidx.annotation.VisibleForTesting; Loading @@ -26,19 +27,29 @@ import androidx.preference.Preference; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.bluetooth.BluetoothDeviceUpdater; import com.android.settings.bluetooth.ConnectedBluetoothDeviceUpdater; import com.android.settings.bluetooth.Utils; import com.android.settings.connecteddevice.dock.DockUpdater; import com.android.settings.connecteddevice.stylus.StylusDeviceUpdater; import com.android.settings.connecteddevice.usb.ConnectedUsbDeviceUpdater; import com.android.settings.core.BasePreferenceController; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.flags.Flags; import com.android.settings.overlay.DockUpdaterFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.bluetooth.BluetoothDeviceFilter; import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; import com.android.settingslib.search.SearchIndexableRaw; import java.util.List; /** * Controller to maintain the {@link androidx.preference.PreferenceGroup} for all Loading @@ -49,6 +60,7 @@ public class ConnectedDeviceGroupController extends BasePreferenceController DevicePreferenceCallback { private static final String KEY = "connected_device_list"; private static final String TAG = "ConnectedDeviceGroupController"; @VisibleForTesting PreferenceGroup mPreferenceGroup; Loading @@ -58,11 +70,13 @@ public class ConnectedDeviceGroupController extends BasePreferenceController private StylusDeviceUpdater mStylusDeviceUpdater; private final PackageManager mPackageManager; private final InputManager mInputManager; private final LocalBluetoothManager mLocalBluetoothManager; public ConnectedDeviceGroupController(Context context) { super(context, KEY); mPackageManager = context.getPackageManager(); mInputManager = context.getSystemService(InputManager.class); mLocalBluetoothManager = Utils.getLocalBluetoothManager(context); } @Override Loading Loading @@ -221,4 +235,31 @@ public class ConnectedDeviceGroupController extends BasePreferenceController } return false; } @Override public void updateDynamicRawDataToIndex(List<SearchIndexableRaw> rawData) { if (!Flags.enableBondedBluetoothDeviceSearchable()) { return; } if (mLocalBluetoothManager == null) { Log.d(TAG, "Bluetooth is not supported"); return; } for (CachedBluetoothDevice cachedDevice : mLocalBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy()) { if (!BluetoothDeviceFilter.BONDED_DEVICE_FILTER.matches(cachedDevice.getDevice())) { continue; } if (BluetoothUtils.isExclusivelyManagedBluetoothDevice(mContext, cachedDevice.getDevice())) { continue; } SearchIndexableRaw data = new SearchIndexableRaw(mContext); // Include the identity address as well to ensure the key is unique. data.key = cachedDevice.getName() + cachedDevice.getIdentityAddress(); data.title = cachedDevice.getName(); data.summaryOn = mContext.getString(R.string.connected_devices_dashboard_title); rawData.add(data); } } } tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java +62 −1 Original line number Diff line number Diff line Loading @@ -27,9 +27,12 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.input.InputManager; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.util.FeatureFlagUtils; import android.view.InputDevice; Loading @@ -39,13 +42,23 @@ import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; import com.android.settings.bluetooth.ConnectedBluetoothDeviceUpdater; import com.android.settings.bluetooth.Utils; import com.android.settings.connecteddevice.dock.DockUpdater; import com.android.settings.connecteddevice.stylus.StylusDeviceUpdater; import com.android.settings.connecteddevice.usb.ConnectedUsbDeviceUpdater; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.flags.Flags; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowBluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.search.SearchIndexableRaw; import com.google.common.collect.ImmutableList; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; Loading @@ -57,11 +70,16 @@ import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplicationPackageManager; import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) @Config(shadows = {ShadowApplicationPackageManager.class, ShadowBluetoothAdapter.class}) @Config(shadows = {ShadowApplicationPackageManager.class, ShadowBluetoothUtils.class, ShadowBluetoothAdapter.class}) public class ConnectedDeviceGroupControllerTest { private static final String PREFERENCE_KEY_1 = "pref_key_1"; private static final String DEVICE_NAME = "device"; @Mock private DashboardFragment mDashboardFragment; Loading @@ -79,6 +97,14 @@ public class ConnectedDeviceGroupControllerTest { private PreferenceManager mPreferenceManager; @Mock private InputManager mInputManager; @Mock private CachedBluetoothDeviceManager mCachedDeviceManager; @Mock private LocalBluetoothManager mLocalBluetoothManager; @Mock private CachedBluetoothDevice mCachedDevice; @Mock private BluetoothDevice mDevice; private ShadowApplicationPackageManager mPackageManager; private PreferenceGroup mPreferenceGroup; Loading @@ -86,6 +112,9 @@ public class ConnectedDeviceGroupControllerTest { private Preference mPreference; private ConnectedDeviceGroupController mConnectedDeviceGroupController; @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Before public void setUp() { MockitoAnnotations.initMocks(this); Loading @@ -102,11 +131,20 @@ public class ConnectedDeviceGroupControllerTest { when(mContext.getSystemService(InputManager.class)).thenReturn(mInputManager); when(mInputManager.getInputDeviceIds()).thenReturn(new int[]{}); ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager; mLocalBluetoothManager = Utils.getLocalBtManager(mContext); when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager); mConnectedDeviceGroupController = new ConnectedDeviceGroupController(mContext); mConnectedDeviceGroupController.init(mConnectedBluetoothDeviceUpdater, mConnectedUsbDeviceUpdater, mConnectedDockUpdater, mStylusDeviceUpdater); mConnectedDeviceGroupController.mPreferenceGroup = mPreferenceGroup; when(mCachedDevice.getName()).thenReturn(DEVICE_NAME); when(mCachedDevice.getDevice()).thenReturn(mDevice); when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn( ImmutableList.of(mCachedDevice)); FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES, true); } Loading Loading @@ -267,4 +305,27 @@ public class ConnectedDeviceGroupControllerTest { mConnectedDeviceGroupController.onStart(); mConnectedDeviceGroupController.onStop(); } @Test @EnableFlags(Flags.FLAG_ENABLE_BONDED_BLUETOOTH_DEVICE_SEARCHABLE) public void updateDynamicRawDataToIndex_deviceNotBonded_deviceIsNotSearchable() { when(mDevice.getBondState()).thenReturn(BluetoothDevice.BOND_NONE); List<SearchIndexableRaw> searchData = new ArrayList<>(); mConnectedDeviceGroupController.updateDynamicRawDataToIndex(searchData); assertThat(searchData).isEmpty(); } @Test @EnableFlags(Flags.FLAG_ENABLE_BONDED_BLUETOOTH_DEVICE_SEARCHABLE) public void updateDynamicRawDataToIndex_deviceBonded_deviceIsSearchable() { when(mDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); List<SearchIndexableRaw> searchData = new ArrayList<>(); mConnectedDeviceGroupController.updateDynamicRawDataToIndex(searchData); assertThat(searchData).isNotEmpty(); assertThat(searchData.get(0).key).contains(DEVICE_NAME); } } Loading
aconfig/settings_connecteddevice_flag_declarations.aconfig +11 −0 Original line number Diff line number Diff line Loading @@ -14,3 +14,14 @@ flag { description: "Gates whether to require an auth challenge for changing USB preferences" bug: "317367746" } flag { name: "enable_bonded_bluetooth_device_searchable" namespace: "pixel_cross_device_control" description: "Set bonded bluetooth devices under connected devices page to be searchable by Settings search." bug: "319056077" metadata { purpose: PURPOSE_BUGFIX } } No newline at end of file
src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java +41 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import android.content.Context; import android.content.pm.PackageManager; import android.hardware.input.InputManager; import android.util.FeatureFlagUtils; import android.util.Log; import android.view.InputDevice; import androidx.annotation.VisibleForTesting; Loading @@ -26,19 +27,29 @@ import androidx.preference.Preference; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.bluetooth.BluetoothDeviceUpdater; import com.android.settings.bluetooth.ConnectedBluetoothDeviceUpdater; import com.android.settings.bluetooth.Utils; import com.android.settings.connecteddevice.dock.DockUpdater; import com.android.settings.connecteddevice.stylus.StylusDeviceUpdater; import com.android.settings.connecteddevice.usb.ConnectedUsbDeviceUpdater; import com.android.settings.core.BasePreferenceController; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.flags.Flags; import com.android.settings.overlay.DockUpdaterFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.bluetooth.BluetoothDeviceFilter; import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; import com.android.settingslib.search.SearchIndexableRaw; import java.util.List; /** * Controller to maintain the {@link androidx.preference.PreferenceGroup} for all Loading @@ -49,6 +60,7 @@ public class ConnectedDeviceGroupController extends BasePreferenceController DevicePreferenceCallback { private static final String KEY = "connected_device_list"; private static final String TAG = "ConnectedDeviceGroupController"; @VisibleForTesting PreferenceGroup mPreferenceGroup; Loading @@ -58,11 +70,13 @@ public class ConnectedDeviceGroupController extends BasePreferenceController private StylusDeviceUpdater mStylusDeviceUpdater; private final PackageManager mPackageManager; private final InputManager mInputManager; private final LocalBluetoothManager mLocalBluetoothManager; public ConnectedDeviceGroupController(Context context) { super(context, KEY); mPackageManager = context.getPackageManager(); mInputManager = context.getSystemService(InputManager.class); mLocalBluetoothManager = Utils.getLocalBluetoothManager(context); } @Override Loading Loading @@ -221,4 +235,31 @@ public class ConnectedDeviceGroupController extends BasePreferenceController } return false; } @Override public void updateDynamicRawDataToIndex(List<SearchIndexableRaw> rawData) { if (!Flags.enableBondedBluetoothDeviceSearchable()) { return; } if (mLocalBluetoothManager == null) { Log.d(TAG, "Bluetooth is not supported"); return; } for (CachedBluetoothDevice cachedDevice : mLocalBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy()) { if (!BluetoothDeviceFilter.BONDED_DEVICE_FILTER.matches(cachedDevice.getDevice())) { continue; } if (BluetoothUtils.isExclusivelyManagedBluetoothDevice(mContext, cachedDevice.getDevice())) { continue; } SearchIndexableRaw data = new SearchIndexableRaw(mContext); // Include the identity address as well to ensure the key is unique. data.key = cachedDevice.getName() + cachedDevice.getIdentityAddress(); data.title = cachedDevice.getName(); data.summaryOn = mContext.getString(R.string.connected_devices_dashboard_title); rawData.add(data); } } }
tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java +62 −1 Original line number Diff line number Diff line Loading @@ -27,9 +27,12 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.input.InputManager; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.util.FeatureFlagUtils; import android.view.InputDevice; Loading @@ -39,13 +42,23 @@ import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; import com.android.settings.bluetooth.ConnectedBluetoothDeviceUpdater; import com.android.settings.bluetooth.Utils; import com.android.settings.connecteddevice.dock.DockUpdater; import com.android.settings.connecteddevice.stylus.StylusDeviceUpdater; import com.android.settings.connecteddevice.usb.ConnectedUsbDeviceUpdater; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.flags.Flags; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowBluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.search.SearchIndexableRaw; import com.google.common.collect.ImmutableList; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; Loading @@ -57,11 +70,16 @@ import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplicationPackageManager; import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) @Config(shadows = {ShadowApplicationPackageManager.class, ShadowBluetoothAdapter.class}) @Config(shadows = {ShadowApplicationPackageManager.class, ShadowBluetoothUtils.class, ShadowBluetoothAdapter.class}) public class ConnectedDeviceGroupControllerTest { private static final String PREFERENCE_KEY_1 = "pref_key_1"; private static final String DEVICE_NAME = "device"; @Mock private DashboardFragment mDashboardFragment; Loading @@ -79,6 +97,14 @@ public class ConnectedDeviceGroupControllerTest { private PreferenceManager mPreferenceManager; @Mock private InputManager mInputManager; @Mock private CachedBluetoothDeviceManager mCachedDeviceManager; @Mock private LocalBluetoothManager mLocalBluetoothManager; @Mock private CachedBluetoothDevice mCachedDevice; @Mock private BluetoothDevice mDevice; private ShadowApplicationPackageManager mPackageManager; private PreferenceGroup mPreferenceGroup; Loading @@ -86,6 +112,9 @@ public class ConnectedDeviceGroupControllerTest { private Preference mPreference; private ConnectedDeviceGroupController mConnectedDeviceGroupController; @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Before public void setUp() { MockitoAnnotations.initMocks(this); Loading @@ -102,11 +131,20 @@ public class ConnectedDeviceGroupControllerTest { when(mContext.getSystemService(InputManager.class)).thenReturn(mInputManager); when(mInputManager.getInputDeviceIds()).thenReturn(new int[]{}); ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager; mLocalBluetoothManager = Utils.getLocalBtManager(mContext); when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager); mConnectedDeviceGroupController = new ConnectedDeviceGroupController(mContext); mConnectedDeviceGroupController.init(mConnectedBluetoothDeviceUpdater, mConnectedUsbDeviceUpdater, mConnectedDockUpdater, mStylusDeviceUpdater); mConnectedDeviceGroupController.mPreferenceGroup = mPreferenceGroup; when(mCachedDevice.getName()).thenReturn(DEVICE_NAME); when(mCachedDevice.getDevice()).thenReturn(mDevice); when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn( ImmutableList.of(mCachedDevice)); FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES, true); } Loading Loading @@ -267,4 +305,27 @@ public class ConnectedDeviceGroupControllerTest { mConnectedDeviceGroupController.onStart(); mConnectedDeviceGroupController.onStop(); } @Test @EnableFlags(Flags.FLAG_ENABLE_BONDED_BLUETOOTH_DEVICE_SEARCHABLE) public void updateDynamicRawDataToIndex_deviceNotBonded_deviceIsNotSearchable() { when(mDevice.getBondState()).thenReturn(BluetoothDevice.BOND_NONE); List<SearchIndexableRaw> searchData = new ArrayList<>(); mConnectedDeviceGroupController.updateDynamicRawDataToIndex(searchData); assertThat(searchData).isEmpty(); } @Test @EnableFlags(Flags.FLAG_ENABLE_BONDED_BLUETOOTH_DEVICE_SEARCHABLE) public void updateDynamicRawDataToIndex_deviceBonded_deviceIsSearchable() { when(mDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); List<SearchIndexableRaw> searchData = new ArrayList<>(); mConnectedDeviceGroupController.updateDynamicRawDataToIndex(searchData); assertThat(searchData).isNotEmpty(); assertThat(searchData.get(0).key).contains(DEVICE_NAME); } }