diff --git a/res/xml/stylus_usi_details_fragment.xml b/res/xml/stylus_usi_details_fragment.xml index 8a1d036c80e..639c2846792 100644 --- a/res/xml/stylus_usi_details_fragment.xml +++ b/res/xml/stylus_usi_details_fragment.xml @@ -30,4 +30,7 @@ + \ No newline at end of file diff --git a/src/com/android/settings/connecteddevice/stylus/StylusFeatureProvider.java b/src/com/android/settings/connecteddevice/stylus/StylusFeatureProvider.java new file mode 100644 index 00000000000..43337c85127 --- /dev/null +++ b/src/com/android/settings/connecteddevice/stylus/StylusFeatureProvider.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2023 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.settings.connecteddevice.stylus; + +import android.content.Context; +import android.hardware.usb.UsbDevice; + +import androidx.preference.Preference; + +import java.util.List; + +import javax.annotation.Nullable; + +/** FeatureProvider for USB settings */ +public interface StylusFeatureProvider { + + /** + * Returns whether the current attached USB device allows firmware updates. + * + * @param usbDevice The USB device to check + */ + boolean isUsbFirmwareUpdateEnabled(UsbDevice usbDevice); + + /** + * Returns a list of preferences for the connected USB device if exists. If not, returns + * null. If an update is not available but firmware update feature is enabled for the device, + * the list will contain only the preference showing the current firmware version. + * + * @param context The context + */ + @Nullable + List getUsbFirmwareUpdatePreferences(Context context); +} diff --git a/src/com/android/settings/connecteddevice/stylus/StylusFeatureProviderImpl.java b/src/com/android/settings/connecteddevice/stylus/StylusFeatureProviderImpl.java new file mode 100644 index 00000000000..dba569b7959 --- /dev/null +++ b/src/com/android/settings/connecteddevice/stylus/StylusFeatureProviderImpl.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2023 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.settings.connecteddevice.stylus; + +import android.content.Context; +import android.hardware.usb.UsbDevice; + +import androidx.preference.Preference; + +import java.util.List; + +/** Default implementation for StylusFeatureProvider */ +public class StylusFeatureProviderImpl implements StylusFeatureProvider { + @Override + public boolean isUsbFirmwareUpdateEnabled(UsbDevice usbDevice) { + return false; + } + + @Override + public List getUsbFirmwareUpdatePreferences(Context context) { + return null; + } +} diff --git a/src/com/android/settings/connecteddevice/stylus/StylusUsbFirmwareController.java b/src/com/android/settings/connecteddevice/stylus/StylusUsbFirmwareController.java new file mode 100644 index 00000000000..4a4dfa271a8 --- /dev/null +++ b/src/com/android/settings/connecteddevice/stylus/StylusUsbFirmwareController.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2023 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.settings.connecteddevice.stylus; + +import android.content.Context; +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbManager; + +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; +import androidx.preference.PreferenceScreen; + +import com.android.settings.core.BasePreferenceController; +import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnStart; +import com.android.settingslib.core.lifecycle.events.OnStop; + +import java.util.ArrayList; +import java.util.List; + +/** Preference controller for stylus firmware updates via USB */ +public class StylusUsbFirmwareController extends BasePreferenceController + implements LifecycleObserver, OnStart, OnStop { + private static final String TAG = StylusUsbFirmwareController.class.getSimpleName(); + @Nullable + private UsbDevice mStylusUsbDevice; + private final UsbStylusBroadcastReceiver mUsbStylusBroadcastReceiver; + + private PreferenceScreen mPreferenceScreen; + private PreferenceCategory mPreference; + + @VisibleForTesting + UsbStylusBroadcastReceiver.UsbStylusConnectionListener mUsbConnectionListener = + (stylusUsbDevice, attached) -> { + refresh(); + }; + + public StylusUsbFirmwareController(Context context, String key) { + super(context, key); + mUsbStylusBroadcastReceiver = new UsbStylusBroadcastReceiver(context, + mUsbConnectionListener); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + mPreferenceScreen = screen; + refresh(); + super.displayPreference(screen); + } + + @Override + public int getAvailabilityStatus() { + // always available, preferences will be added or + // removed according to the connected usb device + return AVAILABLE; + } + + private void refresh() { + if (mPreferenceScreen == null) return; + + UsbDevice device = getStylusUsbDevice(); + if (device == mStylusUsbDevice) { + return; + } + mStylusUsbDevice = device; + mPreference = mPreferenceScreen.findPreference(getPreferenceKey()); + if (mPreference != null) { + mPreferenceScreen.removePreference(mPreference); + } + if (hasUsbStylusFirmwareUpdateFeature(mStylusUsbDevice)) { + StylusFeatureProvider featureProvider = FeatureFactory.getFactory( + mContext).getStylusFeatureProvider(); + List preferences = + featureProvider.getUsbFirmwareUpdatePreferences(mContext); + + if (preferences != null) { + mPreference = new PreferenceCategory(mContext); + mPreference.setKey(getPreferenceKey()); + mPreferenceScreen.addPreference(mPreference); + + for (Preference preference : preferences) { + mPreference.addPreference(preference); + } + } + } + } + + @Override + public void onStart() { + mUsbStylusBroadcastReceiver.register(); + } + + @Override + public void onStop() { + mUsbStylusBroadcastReceiver.unregister(); + } + + private UsbDevice getStylusUsbDevice() { + UsbManager usbManager = mContext.getSystemService(UsbManager.class); + + if (usbManager == null) { + return null; + } + + List devices = new ArrayList<>(usbManager.getDeviceList().values()); + if (devices.isEmpty()) { + return null; + } + + UsbDevice usbDevice = devices.get(0); + if (hasUsbStylusFirmwareUpdateFeature(usbDevice)) { + return usbDevice; + } + return null; + } + + static boolean hasUsbStylusFirmwareUpdateFeature(UsbDevice usbDevice) { + if (usbDevice == null) return false; + + StylusFeatureProvider featureProvider = FeatureFactory.getFactory( + FeatureFactory.getAppContext()).getStylusFeatureProvider(); + + return featureProvider.isUsbFirmwareUpdateEnabled(usbDevice); + } +} diff --git a/src/com/android/settings/connecteddevice/stylus/StylusUsiDetailsFragment.java b/src/com/android/settings/connecteddevice/stylus/StylusUsiDetailsFragment.java index 5e68a537e5d..ea9781e3ce7 100644 --- a/src/com/android/settings/connecteddevice/stylus/StylusUsiDetailsFragment.java +++ b/src/com/android/settings/connecteddevice/stylus/StylusUsiDetailsFragment.java @@ -54,7 +54,6 @@ public class StylusUsiDetailsFragment extends DashboardFragment { } } - @Override public int getMetricsCategory() { return SettingsEnums.USI_DEVICE_DETAILS; diff --git a/src/com/android/settings/connecteddevice/stylus/UsbStylusBroadcastReceiver.java b/src/com/android/settings/connecteddevice/stylus/UsbStylusBroadcastReceiver.java new file mode 100644 index 00000000000..01662500443 --- /dev/null +++ b/src/com/android/settings/connecteddevice/stylus/UsbStylusBroadcastReceiver.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2023 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.settings.connecteddevice.stylus; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbManager; + +/** Broadcast receiver for styluses connected via USB */ +public class UsbStylusBroadcastReceiver extends BroadcastReceiver { + private Context mContext; + private UsbStylusConnectionListener mUsbConnectionListener; + private boolean mListeningToUsbEvents; + + public UsbStylusBroadcastReceiver(Context context, + UsbStylusConnectionListener usbConnectionListener) { + mContext = context; + mUsbConnectionListener = usbConnectionListener; + } + + /** Registers the receiver. */ + public void register() { + if (!mListeningToUsbEvents) { + final IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); + intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); + final Intent intent = mContext.registerReceiver(this, intentFilter); + if (intent != null) { + onReceive(mContext, intent); + } + mListeningToUsbEvents = true; + } + } + + /** Unregisters the receiver. */ + public void unregister() { + if (mListeningToUsbEvents) { + mContext.unregisterReceiver(this); + mListeningToUsbEvents = false; + } + } + + @Override + public void onReceive(Context context, Intent intent) { + UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE, UsbDevice.class); + if (StylusUsbFirmwareController.hasUsbStylusFirmwareUpdateFeature(usbDevice)) { + mUsbConnectionListener.onUsbStylusConnectionChanged(usbDevice, + intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)); + } + } + + /** + * Interface definition for a callback to be invoked when stylus usb connection is changed. + */ + interface UsbStylusConnectionListener { + void onUsbStylusConnectionChanged(UsbDevice device, boolean connected); + } +} diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java index 249caa111fb..97fc343bdac 100644 --- a/src/com/android/settings/overlay/FeatureFactory.java +++ b/src/com/android/settings/overlay/FeatureFactory.java @@ -31,6 +31,7 @@ import com.android.settings.aware.AwareFeatureProvider; import com.android.settings.biometrics.face.FaceFeatureProvider; import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider; import com.android.settings.bluetooth.BluetoothFeatureProvider; +import com.android.settings.connecteddevice.stylus.StylusFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider; @@ -209,6 +210,11 @@ public abstract class FeatureFactory { */ public abstract KeyboardSettingsFeatureProvider getKeyboardSettingsFeatureProvider(); + /** + * Retrieves implementation for stylus settings feature. + */ + public abstract StylusFeatureProvider getStylusFeatureProvider(); + public static final class FactoryNotFoundException extends RuntimeException { public FactoryNotFoundException(Throwable throwable) { super("Unable to create factory. Did you misconfigure Proguard?", throwable); diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java index 60adf958545..8c92792e1e2 100644 --- a/src/com/android/settings/overlay/FeatureFactoryImpl.java +++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java @@ -42,6 +42,8 @@ import com.android.settings.biometrics2.factory.BiometricsRepositoryProviderImpl import com.android.settings.bluetooth.BluetoothFeatureProvider; import com.android.settings.bluetooth.BluetoothFeatureProviderImpl; import com.android.settings.connecteddevice.dock.DockUpdaterFeatureProviderImpl; +import com.android.settings.connecteddevice.stylus.StylusFeatureProvider; +import com.android.settings.connecteddevice.stylus.StylusFeatureProviderImpl; import com.android.settings.core.instrumentation.SettingsMetricsFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProviderImpl; @@ -119,6 +121,7 @@ public class FeatureFactoryImpl extends FeatureFactory { private AdvancedVpnFeatureProvider mAdvancedVpnFeatureProvider; private WifiFeatureProvider mWifiFeatureProvider; private KeyboardSettingsFeatureProvider mKeyboardSettingsFeatureProvider; + private StylusFeatureProvider mStylusFeatureProvider; @Override public HardwareInfoFeatureProvider getHardwareInfoFeatureProvider() { @@ -383,4 +386,12 @@ public class FeatureFactoryImpl extends FeatureFactory { } return mKeyboardSettingsFeatureProvider; } + + @Override + public StylusFeatureProvider getStylusFeatureProvider() { + if (mStylusFeatureProvider == null) { + mStylusFeatureProvider = new StylusFeatureProviderImpl(); + } + return mStylusFeatureProvider; + } } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusUsbFirmwareControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusUsbFirmwareControllerTest.java new file mode 100644 index 00000000000..59220164a62 --- /dev/null +++ b/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusUsbFirmwareControllerTest.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2023 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.settings.connecteddevice.stylus; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbManager; + +import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; +import androidx.preference.PreferenceManager; +import androidx.preference.PreferenceScreen; + +import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settingslib.core.lifecycle.Lifecycle; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +import java.util.Collections; +import java.util.HashMap; + +@RunWith(RobolectricTestRunner.class) +public class StylusUsbFirmwareControllerTest { + + private Context mContext; + private FakeFeatureFactory mFeatureFactory; + private Lifecycle mLifecycle; + private PreferenceScreen mScreen; + + private StylusUsbFirmwareController mController; + @Mock + private StylusUsiDetailsFragment mFragment; + @Mock + private UsbManager mUsbManager; + private PreferenceCategory mPreferenceCategory; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mContext = spy(RuntimeEnvironment.application); + mLifecycle = new Lifecycle(() -> mLifecycle); + + when(mFragment.getContext()).thenReturn(mContext); + + mFeatureFactory = FakeFeatureFactory.setupForTest(); + mController = new StylusUsbFirmwareController(mContext, "stylus_usb_firmware"); + + PreferenceManager preferenceManager = new PreferenceManager(mContext); + mScreen = preferenceManager.createPreferenceScreen(mContext); + + mPreferenceCategory = new PreferenceCategory(mContext); + mPreferenceCategory.setKey(mController.getPreferenceKey()); + } + + @Test + public void displayPreference_featurePresentUsbStylusAttached_preferenceAdded() { + attachUsbDevice(); + enableFullStylusFeature(); + + mController.displayPreference(mScreen); + + assertNotNull(mScreen.findPreference("stylus_usb_firmware")); + } + + @Test + public void displayPreference_featureAbsentUsbStylusAttached_preferenceNotAdded() { + attachUsbDevice(); + mController.mUsbConnectionListener.onUsbStylusConnectionChanged( + mock(UsbDevice.class), true); + + mController.displayPreference(mScreen); + + assertNull(mScreen.findPreference(mController.getPreferenceKey())); + } + + @Test + public void onUsbStylusConnectionChanged_featurePresentUsbStylusAttached_preferenceAdded() { + mController.displayPreference(mScreen); + + attachUsbDevice(); + enableFullStylusFeature(); + mController.mUsbConnectionListener.onUsbStylusConnectionChanged( + mock(UsbDevice.class), true); + + assertNotNull(mScreen.findPreference(mController.getPreferenceKey())); + } + + @Test + public void onUsbStylusConnectionChanged_featureAbsentUsbStylusAttached_preferenceRemoved() { + mController.displayPreference(mScreen); + + attachUsbDevice(); + mController.mUsbConnectionListener.onUsbStylusConnectionChanged( + mock(UsbDevice.class), true); + + assertNull(mScreen.findPreference(mController.getPreferenceKey())); + } + + @Test + public void hasUsbStylusFirmwareUpdateFeature_featurePresent_true() { + when(mFeatureFactory.getStylusFeatureProvider() + .isUsbFirmwareUpdateEnabled(any())).thenReturn(true); + attachUsbDevice(); + + assertTrue(StylusUsbFirmwareController + .hasUsbStylusFirmwareUpdateFeature(mock(UsbDevice.class))); + } + + @Test + public void hasUsbStylusFirmwareUpdateFeature_featureNotPresent_false() { + when(mFeatureFactory.getStylusFeatureProvider() + .isUsbFirmwareUpdateEnabled(any())).thenReturn(false); + attachUsbDevice(); + + assertFalse(StylusUsbFirmwareController + .hasUsbStylusFirmwareUpdateFeature(mock(UsbDevice.class))); + } + + private void attachUsbDevice() { + when(mContext.getSystemService(UsbManager.class)).thenReturn(mUsbManager); + HashMap deviceList = new HashMap<>(); + deviceList.put("0", mock(UsbDevice.class)); + when(mUsbManager.getDeviceList()).thenReturn(deviceList); + } + + private void enableFullStylusFeature() { + when(mFeatureFactory.getStylusFeatureProvider() + .isUsbFirmwareUpdateEnabled(any())).thenReturn(true); + when(mFeatureFactory.getStylusFeatureProvider() + .getUsbFirmwareUpdatePreferences(any())) + .thenReturn(Collections.singletonList(mock(Preference.class))); + } +} diff --git a/tests/robotests/src/com/android/settings/connecteddevice/stylus/UsbStylusBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/connecteddevice/stylus/UsbStylusBroadcastReceiverTest.java new file mode 100644 index 00000000000..ccaefb25523 --- /dev/null +++ b/tests/robotests/src/com/android/settings/connecteddevice/stylus/UsbStylusBroadcastReceiverTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2023 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.settings.connecteddevice.stylus; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.content.Intent; +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbManager; + +import com.android.settings.testutils.FakeFeatureFactory; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class UsbStylusBroadcastReceiverTest { + private Context mContext; + private UsbStylusBroadcastReceiver mReceiver; + private FakeFeatureFactory mFeatureFactory; + @Mock + private UsbStylusBroadcastReceiver.UsbStylusConnectionListener mListener; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mContext = RuntimeEnvironment.application; + mReceiver = new UsbStylusBroadcastReceiver(mContext, mListener); + mFeatureFactory = FakeFeatureFactory.setupForTest(); + } + + @Test + public void onReceive_usbDeviceAttachedStylus_invokeCallback() { + when(mFeatureFactory.mStylusFeatureProvider.isUsbFirmwareUpdateEnabled(any())) + .thenReturn(true); + final UsbDevice usbDevice = mock(UsbDevice.class); + final Intent intent = new Intent(); + intent.setAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); + intent.putExtra(UsbManager.EXTRA_DEVICE, usbDevice); + + mReceiver.onReceive(mContext, intent); + + verify(mListener).onUsbStylusConnectionChanged(usbDevice, true); + } + + @Test + public void onReceive_usbDeviceDetachedStylus_invokeCallback() { + when(mFeatureFactory.mStylusFeatureProvider.isUsbFirmwareUpdateEnabled(any())) + .thenReturn(true); + final UsbDevice usbDevice = mock(UsbDevice.class); + final Intent intent = new Intent(); + intent.setAction(UsbManager.ACTION_USB_DEVICE_DETACHED); + intent.putExtra(UsbManager.EXTRA_DEVICE, usbDevice); + + mReceiver.onReceive(mContext, intent); + + verify(mListener).onUsbStylusConnectionChanged(usbDevice, false); + } + + @Test + public void onReceive_usbDeviceAttachedNotStylus_doesNotInvokeCallback() { + when(mFeatureFactory.mStylusFeatureProvider.isUsbFirmwareUpdateEnabled(any())) + .thenReturn(false); + final UsbDevice usbDevice = mock(UsbDevice.class); + final Intent intent = new Intent(); + intent.setAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); + intent.putExtra(UsbManager.EXTRA_DEVICE, usbDevice); + + mReceiver.onReceive(mContext, intent); + + verifyNoMoreInteractions(mListener); + } +} diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java index fcb01b4649e..5891aa19255 100644 --- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java +++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java @@ -29,6 +29,7 @@ import com.android.settings.aware.AwareFeatureProvider; import com.android.settings.biometrics.face.FaceFeatureProvider; import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider; import com.android.settings.bluetooth.BluetoothFeatureProvider; +import com.android.settings.connecteddevice.stylus.StylusFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider; @@ -97,6 +98,7 @@ public class FakeFeatureFactory extends FeatureFactory { public AdvancedVpnFeatureProvider mAdvancedVpnFeatureProvider; public WifiFeatureProvider mWifiFeatureProvider; public KeyboardSettingsFeatureProvider mKeyboardSettingsFeatureProvider; + public StylusFeatureProvider mStylusFeatureProvider; /** * Call this in {@code @Before} method of the test class to use fake factory. @@ -150,6 +152,7 @@ public class FakeFeatureFactory extends FeatureFactory { mAdvancedVpnFeatureProvider = mock(AdvancedVpnFeatureProvider.class); mWifiFeatureProvider = mock(WifiFeatureProvider.class); mKeyboardSettingsFeatureProvider = mock(KeyboardSettingsFeatureProvider.class); + mStylusFeatureProvider = mock(StylusFeatureProvider.class); } @Override @@ -311,4 +314,9 @@ public class FakeFeatureFactory extends FeatureFactory { public KeyboardSettingsFeatureProvider getKeyboardSettingsFeatureProvider() { return mKeyboardSettingsFeatureProvider; } + + @Override + public StylusFeatureProvider getStylusFeatureProvider() { + return mStylusFeatureProvider; + } } diff --git a/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt b/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt index 68078f8ba56..6320fc7074a 100644 --- a/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt +++ b/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt @@ -25,6 +25,7 @@ import com.android.settings.aware.AwareFeatureProvider import com.android.settings.biometrics.face.FaceFeatureProvider import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider import com.android.settings.bluetooth.BluetoothFeatureProvider +import com.android.settings.connecteddevice.stylus.StylusFeatureProvider import com.android.settings.dashboard.DashboardFeatureProvider import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider @@ -190,4 +191,8 @@ class FakeFeatureFactory : FeatureFactory() { override fun getKeyboardSettingsFeatureProvider(): KeyboardSettingsFeatureProvider { TODO("Not yet implemented") } + + override fun getStylusFeatureProvider(): StylusFeatureProvider { + TODO("Not yet implemented") + } } diff --git a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java index 7a498652a5d..49ce2cc761e 100644 --- a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java +++ b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java @@ -27,6 +27,7 @@ import com.android.settings.aware.AwareFeatureProvider; import com.android.settings.biometrics.face.FaceFeatureProvider; import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider; import com.android.settings.bluetooth.BluetoothFeatureProvider; +import com.android.settings.connecteddevice.stylus.StylusFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider; @@ -92,6 +93,7 @@ public class FakeFeatureFactory extends FeatureFactory { public AdvancedVpnFeatureProvider mAdvancedVpnFeatureProvider; public WifiFeatureProvider mWifiFeatureProvider; public KeyboardSettingsFeatureProvider mKeyboardSettingsFeatureProvider; + public StylusFeatureProvider mStylusFeatureProvider; /** * Call this in {@code @Before} method of the test class to use fake factory. @@ -136,6 +138,7 @@ public class FakeFeatureFactory extends FeatureFactory { mAdvancedVpnFeatureProvider = mock(AdvancedVpnFeatureProvider.class); mWifiFeatureProvider = mock(WifiFeatureProvider.class); mKeyboardSettingsFeatureProvider = mock(KeyboardSettingsFeatureProvider.class); + mStylusFeatureProvider = mock(StylusFeatureProvider.class); } @Override @@ -297,4 +300,9 @@ public class FakeFeatureFactory extends FeatureFactory { public KeyboardSettingsFeatureProvider getKeyboardSettingsFeatureProvider() { return mKeyboardSettingsFeatureProvider; } + + @Override + public StylusFeatureProvider getStylusFeatureProvider() { + return mStylusFeatureProvider; + } }