diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java b/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java index 8cec9a68221..61195c99c83 100644 --- a/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java +++ b/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java @@ -51,23 +51,37 @@ public class ConnectedDeviceGroupController extends BasePreferenceController private BluetoothDeviceUpdater mBluetoothDeviceUpdater; private ConnectedUsbDeviceUpdater mConnectedUsbDeviceUpdater; private DockUpdater mConnectedDockUpdater; + private final PackageManager mPackageManager; public ConnectedDeviceGroupController(Context context) { super(context, KEY); + mPackageManager = context.getPackageManager(); } @Override public void onStart() { - mBluetoothDeviceUpdater.registerCallback(); - mConnectedUsbDeviceUpdater.registerCallback(); + if (mBluetoothDeviceUpdater != null) { + mBluetoothDeviceUpdater.registerCallback(); + mBluetoothDeviceUpdater.refreshPreference(); + } + + if (mConnectedUsbDeviceUpdater != null) { + mConnectedUsbDeviceUpdater.registerCallback(); + } + mConnectedDockUpdater.registerCallback(); - mBluetoothDeviceUpdater.refreshPreference(); } @Override public void onStop() { - mConnectedUsbDeviceUpdater.unregisterCallback(); - mBluetoothDeviceUpdater.unregisterCallback(); + if (mBluetoothDeviceUpdater != null) { + mBluetoothDeviceUpdater.unregisterCallback(); + } + + if (mConnectedUsbDeviceUpdater != null) { + mConnectedUsbDeviceUpdater.unregisterCallback(); + } + mConnectedDockUpdater.unregisterCallback(); } @@ -80,9 +94,15 @@ public class ConnectedDeviceGroupController extends BasePreferenceController if (isAvailable()) { final Context context = screen.getContext(); - mBluetoothDeviceUpdater.setPrefContext(context); - mBluetoothDeviceUpdater.forceUpdate(); - mConnectedUsbDeviceUpdater.initUsbPreference(context); + if (mBluetoothDeviceUpdater != null) { + mBluetoothDeviceUpdater.setPrefContext(context); + mBluetoothDeviceUpdater.forceUpdate(); + } + + if (mConnectedUsbDeviceUpdater != null) { + mConnectedUsbDeviceUpdater.initUsbPreference(context); + } + mConnectedDockUpdater.setPreferenceContext(context); mConnectedDockUpdater.forceUpdate(); } @@ -90,10 +110,8 @@ public class ConnectedDeviceGroupController extends BasePreferenceController @Override public int getAvailabilityStatus() { - final PackageManager packageManager = mContext.getPackageManager(); - return (packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH) - || packageManager.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY) - || packageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST) + return (hasBluetoothFeature() + || hasUsbFeature() || mConnectedDockUpdater != null) ? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE; @@ -121,7 +139,7 @@ public class ConnectedDeviceGroupController extends BasePreferenceController } @VisibleForTesting - public void init(BluetoothDeviceUpdater bluetoothDeviceUpdater, + void init(BluetoothDeviceUpdater bluetoothDeviceUpdater, ConnectedUsbDeviceUpdater connectedUsbDeviceUpdater, DockUpdater connectedDockUpdater) { @@ -136,8 +154,21 @@ public class ConnectedDeviceGroupController extends BasePreferenceController FeatureFactory.getFactory(context).getDockUpdaterFeatureProvider(); final DockUpdater connectedDockUpdater = dockUpdaterFeatureProvider.getConnectedDockUpdater(context, this); - init(new ConnectedBluetoothDeviceUpdater(context, fragment, this), - new ConnectedUsbDeviceUpdater(context, fragment, this), + init(hasBluetoothFeature() + ? new ConnectedBluetoothDeviceUpdater(context, fragment, this) + : null, + hasUsbFeature() + ? new ConnectedUsbDeviceUpdater(context, fragment, this) + : null, connectedDockUpdater); } + + private boolean hasBluetoothFeature() { + return mPackageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH); + } + + private boolean hasUsbFeature() { + return mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY) + || mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST); + } } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java index 4c857133b68..40e6494522d 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java @@ -22,6 +22,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -38,6 +39,7 @@ import com.android.settings.bluetooth.ConnectedBluetoothDeviceUpdater; import com.android.settings.connecteddevice.dock.DockUpdater; import com.android.settings.connecteddevice.usb.ConnectedUsbDeviceUpdater; import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import org.junit.Before; import org.junit.Test; @@ -52,7 +54,7 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplicationPackageManager; @RunWith(RobolectricTestRunner.class) -@Config(shadows = ShadowApplicationPackageManager.class) +@Config(shadows = {ShadowApplicationPackageManager.class, ShadowBluetoothAdapter.class}) public class ConnectedDeviceGroupControllerTest { private static final String PREFERENCE_KEY_1 = "pref_key_1"; @@ -203,4 +205,18 @@ public class ConnectedDeviceGroupControllerTest { AVAILABLE_UNSEARCHABLE); } + @Test + public void init_noBluetoothAndUsbFeature_doesNotCrash() { + DashboardFragment fragment = mock(DashboardFragment.class); + when(fragment.getContext()).thenReturn(mContext); + when(mPreferenceScreen.findPreference(anyString())).thenReturn(mPreferenceGroup); + mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, false); + mPackageManager.setSystemFeature(PackageManager.FEATURE_USB_ACCESSORY, false); + mPackageManager.setSystemFeature(PackageManager.FEATURE_USB_HOST, false); + + mConnectedDeviceGroupController.init(fragment); + mConnectedDeviceGroupController.displayPreference(mPreferenceScreen); + mConnectedDeviceGroupController.onStart(); + mConnectedDeviceGroupController.onStop(); + } }