Loading src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java +17 −19 Original line number Diff line number Diff line Loading @@ -57,7 +57,6 @@ public class UsbConnectionBroadcastReceiver extends BroadcastReceiver implements if (UsbManager.ACTION_USB_STATE.equals(intent.getAction())) { mConnected = intent.getExtras().getBoolean(UsbManager.USB_CONNECTED) || intent.getExtras().getBoolean(UsbManager.USB_HOST_CONNECTED); if (mConnected) { long functions = UsbManager.FUNCTION_NONE; if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_MTP) && intent.getExtras().getBoolean(UsbManager.USB_DATA_UNLOCKED, false)) { Loading @@ -76,7 +75,6 @@ public class UsbConnectionBroadcastReceiver extends BroadcastReceiver implements mFunctions = functions; mDataRole = mUsbBackend.getDataRole(); mPowerRole = mUsbBackend.getPowerRole(); } } else if (UsbManager.ACTION_USB_PORT_CHANGED.equals(intent.getAction())) { UsbPortStatus portStatus = intent.getExtras() .getParcelable(UsbManager.EXTRA_PORT_STATUS); Loading src/com/android/settings/connecteddevice/usb/UsbDefaultFragment.java +46 −0 Original line number Diff line number Diff line Loading @@ -26,12 +26,14 @@ import android.net.ConnectivityManager; import android.os.Bundle; import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.widget.RadioButtonPickerFragment; import com.android.settingslib.widget.CandidateInfo; import com.android.settingslib.widget.FooterPreference; import com.android.settingslib.widget.RadioButtonPreference; import com.google.android.collect.Lists; Loading @@ -49,12 +51,31 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment { OnStartTetheringCallback mOnStartTetheringCallback = new OnStartTetheringCallback(); @VisibleForTesting long mPreviousFunctions; @VisibleForTesting long mCurrentFunctions; @VisibleForTesting boolean mIsStartTethering = false; private UsbConnectionBroadcastReceiver mUsbReceiver; @VisibleForTesting UsbConnectionBroadcastReceiver.UsbConnectionListener mUsbConnectionListener = (connected, functions, powerRole, dataRole) -> { if (mIsStartTethering) { mCurrentFunctions = functions; refresh(functions); } }; @Override public void onAttach(Context context) { super.onAttach(context); mUsbBackend = new UsbBackend(context); mConnectivityManager = context.getSystemService(ConnectivityManager.class); mUsbReceiver = new UsbConnectionBroadcastReceiver(context, mUsbConnectionListener, mUsbBackend); getSettingsLifecycle().addObserver(mUsbReceiver); mCurrentFunctions = mUsbBackend.getDefaultUsbFunctions(); } @Override Loading Loading @@ -118,9 +139,12 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment { if (functions == UsbManager.FUNCTION_RNDIS) { // We need to have entitlement check for usb tethering, so use API in // ConnectivityManager. mIsStartTethering = true; mConnectivityManager.startTethering(TETHERING_USB, true /* showProvisioningUi */, mOnStartTetheringCallback); } else { mIsStartTethering = false; mCurrentFunctions = functions; mUsbBackend.setDefaultUsbFunctions(functions); } Loading @@ -128,6 +152,12 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment { return true; } @Override public void onPause() { super.onPause(); mUsbBackend.setDefaultUsbFunctions(mCurrentFunctions); } @VisibleForTesting final class OnStartTetheringCallback extends ConnectivityManager.OnStartTetheringCallback { Loading @@ -136,6 +166,7 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment { public void onTetheringStarted() { super.onTetheringStarted(); // Set default usb functions again to make internal data persistent mCurrentFunctions = UsbManager.FUNCTION_RNDIS; mUsbBackend.setDefaultUsbFunctions(UsbManager.FUNCTION_RNDIS); } Loading @@ -146,4 +177,19 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment { updateCandidates(); } } private void refresh(long functions) { final PreferenceScreen screen = getPreferenceScreen(); for (long option : UsbDetailsFunctionsController.FUNCTIONS_MAP.keySet()) { final RadioButtonPreference pref = screen.findPreference(UsbBackend.usbFunctionsToString(option)); if (pref != null) { final boolean isSupported = mUsbBackend.areFunctionsSupported(option); pref.setEnabled(isSupported); if (isSupported) { pref.setChecked(functions == option); } } } } } No newline at end of file tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDefaultFragmentTest.java +79 −1 Original line number Diff line number Diff line Loading @@ -16,12 +16,15 @@ package com.android.settings.connecteddevice.usb; import static android.hardware.usb.UsbPortStatus.DATA_ROLE_DEVICE; import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SINK; import static android.net.ConnectivityManager.TETHERING_USB; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading @@ -29,6 +32,8 @@ import static org.mockito.Mockito.when; import android.hardware.usb.UsbManager; import android.net.ConnectivityManager; import androidx.preference.PreferenceScreen; import com.android.settings.testutils.shadow.ShadowUtils; import org.junit.Before; Loading @@ -52,7 +57,7 @@ public class UsbDefaultFragmentTest { @Before public void setUp() { MockitoAnnotations.initMocks(this); mFragment = new UsbDefaultFragment(); mFragment = new TestFragment(); mFragment.mUsbBackend = mUsbBackend; mFragment.mConnectivityManager = mConnectivityManager; } Loading Loading @@ -156,4 +161,77 @@ public class UsbDefaultFragmentTest { verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_RNDIS); } @Test public void onPause_receivedRndis_shouldSetRndis() { mFragment.mIsStartTethering = true; mFragment.mUsbConnectionListener.onUsbConnectionChanged(true /* connected */, UsbManager.FUNCTION_RNDIS, POWER_ROLE_SINK, DATA_ROLE_DEVICE); mFragment.onPause(); verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_RNDIS); assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_RNDIS); } @Test public void onPause_receivedNone_shouldSetNone() { mFragment.mIsStartTethering = true; mFragment.mUsbConnectionListener.onUsbConnectionChanged(true /* connected */, UsbManager.FUNCTION_NONE, POWER_ROLE_SINK, DATA_ROLE_DEVICE); mFragment.onPause(); verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_NONE); assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_NONE); } @Test public void onPause_receivedMtp_shouldSetMtp() { mFragment.mIsStartTethering = true; mFragment.mUsbConnectionListener.onUsbConnectionChanged(true /* connected */, UsbManager.FUNCTION_MTP, POWER_ROLE_SINK, DATA_ROLE_DEVICE); mFragment.onPause(); verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_MTP); assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_MTP); } @Test public void onPause_receivedPtp_shouldSetPtp() { mFragment.mIsStartTethering = true; mFragment.mUsbConnectionListener.onUsbConnectionChanged(true /* connected */, UsbManager.FUNCTION_PTP, POWER_ROLE_SINK, DATA_ROLE_DEVICE); mFragment.onPause(); verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_PTP); assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_PTP); } @Test public void onPause_receivedMidi_shouldSetMidi() { mFragment.mIsStartTethering = true; mFragment.mUsbConnectionListener.onUsbConnectionChanged(true /* connected */, UsbManager.FUNCTION_MIDI, POWER_ROLE_SINK, DATA_ROLE_DEVICE); mFragment.onPause(); verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_MIDI); assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_MIDI); } public static class TestFragment extends UsbDefaultFragment { public final PreferenceScreen mScreen; public TestFragment() { mScreen = mock(PreferenceScreen.class); } @Override public PreferenceScreen getPreferenceScreen() { return mScreen; } } } Loading
src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java +17 −19 Original line number Diff line number Diff line Loading @@ -57,7 +57,6 @@ public class UsbConnectionBroadcastReceiver extends BroadcastReceiver implements if (UsbManager.ACTION_USB_STATE.equals(intent.getAction())) { mConnected = intent.getExtras().getBoolean(UsbManager.USB_CONNECTED) || intent.getExtras().getBoolean(UsbManager.USB_HOST_CONNECTED); if (mConnected) { long functions = UsbManager.FUNCTION_NONE; if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_MTP) && intent.getExtras().getBoolean(UsbManager.USB_DATA_UNLOCKED, false)) { Loading @@ -76,7 +75,6 @@ public class UsbConnectionBroadcastReceiver extends BroadcastReceiver implements mFunctions = functions; mDataRole = mUsbBackend.getDataRole(); mPowerRole = mUsbBackend.getPowerRole(); } } else if (UsbManager.ACTION_USB_PORT_CHANGED.equals(intent.getAction())) { UsbPortStatus portStatus = intent.getExtras() .getParcelable(UsbManager.EXTRA_PORT_STATUS); Loading
src/com/android/settings/connecteddevice/usb/UsbDefaultFragment.java +46 −0 Original line number Diff line number Diff line Loading @@ -26,12 +26,14 @@ import android.net.ConnectivityManager; import android.os.Bundle; import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.widget.RadioButtonPickerFragment; import com.android.settingslib.widget.CandidateInfo; import com.android.settingslib.widget.FooterPreference; import com.android.settingslib.widget.RadioButtonPreference; import com.google.android.collect.Lists; Loading @@ -49,12 +51,31 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment { OnStartTetheringCallback mOnStartTetheringCallback = new OnStartTetheringCallback(); @VisibleForTesting long mPreviousFunctions; @VisibleForTesting long mCurrentFunctions; @VisibleForTesting boolean mIsStartTethering = false; private UsbConnectionBroadcastReceiver mUsbReceiver; @VisibleForTesting UsbConnectionBroadcastReceiver.UsbConnectionListener mUsbConnectionListener = (connected, functions, powerRole, dataRole) -> { if (mIsStartTethering) { mCurrentFunctions = functions; refresh(functions); } }; @Override public void onAttach(Context context) { super.onAttach(context); mUsbBackend = new UsbBackend(context); mConnectivityManager = context.getSystemService(ConnectivityManager.class); mUsbReceiver = new UsbConnectionBroadcastReceiver(context, mUsbConnectionListener, mUsbBackend); getSettingsLifecycle().addObserver(mUsbReceiver); mCurrentFunctions = mUsbBackend.getDefaultUsbFunctions(); } @Override Loading Loading @@ -118,9 +139,12 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment { if (functions == UsbManager.FUNCTION_RNDIS) { // We need to have entitlement check for usb tethering, so use API in // ConnectivityManager. mIsStartTethering = true; mConnectivityManager.startTethering(TETHERING_USB, true /* showProvisioningUi */, mOnStartTetheringCallback); } else { mIsStartTethering = false; mCurrentFunctions = functions; mUsbBackend.setDefaultUsbFunctions(functions); } Loading @@ -128,6 +152,12 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment { return true; } @Override public void onPause() { super.onPause(); mUsbBackend.setDefaultUsbFunctions(mCurrentFunctions); } @VisibleForTesting final class OnStartTetheringCallback extends ConnectivityManager.OnStartTetheringCallback { Loading @@ -136,6 +166,7 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment { public void onTetheringStarted() { super.onTetheringStarted(); // Set default usb functions again to make internal data persistent mCurrentFunctions = UsbManager.FUNCTION_RNDIS; mUsbBackend.setDefaultUsbFunctions(UsbManager.FUNCTION_RNDIS); } Loading @@ -146,4 +177,19 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment { updateCandidates(); } } private void refresh(long functions) { final PreferenceScreen screen = getPreferenceScreen(); for (long option : UsbDetailsFunctionsController.FUNCTIONS_MAP.keySet()) { final RadioButtonPreference pref = screen.findPreference(UsbBackend.usbFunctionsToString(option)); if (pref != null) { final boolean isSupported = mUsbBackend.areFunctionsSupported(option); pref.setEnabled(isSupported); if (isSupported) { pref.setChecked(functions == option); } } } } } No newline at end of file
tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDefaultFragmentTest.java +79 −1 Original line number Diff line number Diff line Loading @@ -16,12 +16,15 @@ package com.android.settings.connecteddevice.usb; import static android.hardware.usb.UsbPortStatus.DATA_ROLE_DEVICE; import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SINK; import static android.net.ConnectivityManager.TETHERING_USB; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading @@ -29,6 +32,8 @@ import static org.mockito.Mockito.when; import android.hardware.usb.UsbManager; import android.net.ConnectivityManager; import androidx.preference.PreferenceScreen; import com.android.settings.testutils.shadow.ShadowUtils; import org.junit.Before; Loading @@ -52,7 +57,7 @@ public class UsbDefaultFragmentTest { @Before public void setUp() { MockitoAnnotations.initMocks(this); mFragment = new UsbDefaultFragment(); mFragment = new TestFragment(); mFragment.mUsbBackend = mUsbBackend; mFragment.mConnectivityManager = mConnectivityManager; } Loading Loading @@ -156,4 +161,77 @@ public class UsbDefaultFragmentTest { verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_RNDIS); } @Test public void onPause_receivedRndis_shouldSetRndis() { mFragment.mIsStartTethering = true; mFragment.mUsbConnectionListener.onUsbConnectionChanged(true /* connected */, UsbManager.FUNCTION_RNDIS, POWER_ROLE_SINK, DATA_ROLE_DEVICE); mFragment.onPause(); verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_RNDIS); assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_RNDIS); } @Test public void onPause_receivedNone_shouldSetNone() { mFragment.mIsStartTethering = true; mFragment.mUsbConnectionListener.onUsbConnectionChanged(true /* connected */, UsbManager.FUNCTION_NONE, POWER_ROLE_SINK, DATA_ROLE_DEVICE); mFragment.onPause(); verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_NONE); assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_NONE); } @Test public void onPause_receivedMtp_shouldSetMtp() { mFragment.mIsStartTethering = true; mFragment.mUsbConnectionListener.onUsbConnectionChanged(true /* connected */, UsbManager.FUNCTION_MTP, POWER_ROLE_SINK, DATA_ROLE_DEVICE); mFragment.onPause(); verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_MTP); assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_MTP); } @Test public void onPause_receivedPtp_shouldSetPtp() { mFragment.mIsStartTethering = true; mFragment.mUsbConnectionListener.onUsbConnectionChanged(true /* connected */, UsbManager.FUNCTION_PTP, POWER_ROLE_SINK, DATA_ROLE_DEVICE); mFragment.onPause(); verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_PTP); assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_PTP); } @Test public void onPause_receivedMidi_shouldSetMidi() { mFragment.mIsStartTethering = true; mFragment.mUsbConnectionListener.onUsbConnectionChanged(true /* connected */, UsbManager.FUNCTION_MIDI, POWER_ROLE_SINK, DATA_ROLE_DEVICE); mFragment.onPause(); verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_MIDI); assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_MIDI); } public static class TestFragment extends UsbDefaultFragment { public final PreferenceScreen mScreen; public TestFragment() { mScreen = mock(PreferenceScreen.class); } @Override public PreferenceScreen getPreferenceScreen() { return mScreen; } } }