Merge "Tethering shouldn't indicates on when SIM without tethering option"
diff --git a/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java b/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java
index 695a714..e557847 100644
--- a/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java
+++ b/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java
@@ -57,26 +57,24 @@
         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)) {
-                    functions |= UsbManager.FUNCTION_MTP;
-                }
-                if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_PTP)
-                        && intent.getExtras().getBoolean(UsbManager.USB_DATA_UNLOCKED, false)) {
-                    functions |= UsbManager.FUNCTION_PTP;
-                }
-                if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_MIDI)) {
-                    functions |= UsbManager.FUNCTION_MIDI;
-                }
-                if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_RNDIS)) {
-                    functions |= UsbManager.FUNCTION_RNDIS;
-                }
-                mFunctions = functions;
-                mDataRole = mUsbBackend.getDataRole();
-                mPowerRole = mUsbBackend.getPowerRole();
+            long functions = UsbManager.FUNCTION_NONE;
+            if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_MTP)
+                    && intent.getExtras().getBoolean(UsbManager.USB_DATA_UNLOCKED, false)) {
+                functions |= UsbManager.FUNCTION_MTP;
             }
+            if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_PTP)
+                    && intent.getExtras().getBoolean(UsbManager.USB_DATA_UNLOCKED, false)) {
+                functions |= UsbManager.FUNCTION_PTP;
+            }
+            if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_MIDI)) {
+                functions |= UsbManager.FUNCTION_MIDI;
+            }
+            if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_RNDIS)) {
+                functions |= UsbManager.FUNCTION_RNDIS;
+            }
+            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);
diff --git a/src/com/android/settings/connecteddevice/usb/UsbDefaultFragment.java b/src/com/android/settings/connecteddevice/usb/UsbDefaultFragment.java
index d4f1283..12e978f 100644
--- a/src/com/android/settings/connecteddevice/usb/UsbDefaultFragment.java
+++ b/src/com/android/settings/connecteddevice/usb/UsbDefaultFragment.java
@@ -26,12 +26,14 @@
 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;
 
@@ -49,12 +51,31 @@
     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
@@ -118,9 +139,12 @@
             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);
             }
 
@@ -128,6 +152,12 @@
         return true;
     }
 
+    @Override
+    public void onPause() {
+        super.onPause();
+        mUsbBackend.setDefaultUsbFunctions(mCurrentFunctions);
+    }
+
     @VisibleForTesting
     final class OnStartTetheringCallback extends
             ConnectivityManager.OnStartTetheringCallback {
@@ -136,6 +166,7 @@
         public void onTetheringStarted() {
             super.onTetheringStarted();
             // Set default usb functions again to make internal data persistent
+            mCurrentFunctions = UsbManager.FUNCTION_RNDIS;
             mUsbBackend.setDefaultUsbFunctions(UsbManager.FUNCTION_RNDIS);
         }
 
@@ -146,4 +177,19 @@
             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
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDefaultFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDefaultFragmentTest.java
index d8663fc..4afe22a 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDefaultFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDefaultFragmentTest.java
@@ -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;
@@ -29,6 +32,8 @@
 import android.hardware.usb.UsbManager;
 import android.net.ConnectivityManager;
 
+import androidx.preference.PreferenceScreen;
+
 import com.android.settings.testutils.shadow.ShadowUtils;
 
 import org.junit.Before;
@@ -52,7 +57,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mFragment = new UsbDefaultFragment();
+        mFragment = new TestFragment();
         mFragment.mUsbBackend = mUsbBackend;
         mFragment.mConnectivityManager = mConnectivityManager;
     }
@@ -156,4 +161,77 @@
 
         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;
+        }
+    }
 }