diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index 67d857fdfd8..7827180da4c 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -135,7 +135,7 @@ android:title="@string/debug_debugging_category" android:order="200"> - @@ -294,7 +294,7 @@ android:title="@string/tethering_hardware_offload" android:summary="@string/tethering_hardware_offload_summary" /> - - diff --git a/res/xml/tether_prefs.xml b/res/xml/tether_prefs.xml index cca4e5f8fe0..37194d9fd12 100644 --- a/res/xml/tether_prefs.xml +++ b/res/xml/tether_prefs.xml @@ -31,7 +31,7 @@ settings:allowDividerAbove="true" settings:summaryLineCount="2"/> - { mMetricsFeatureProvider.logClickedPreference(p, mFragment.getMetricsCategory()); // New version - uses a separate screen. diff --git a/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java b/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java index bc7656815b0..8d14cf9f8c3 100644 --- a/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java +++ b/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java @@ -16,9 +16,12 @@ package com.android.settings.connecteddevice.usb; +import static com.android.settingslib.RestrictedLockUtilsInternal.checkIfUsbDataSignalingIsDisabled; + import android.app.settings.SettingsEnums; import android.content.Context; import android.os.Bundle; +import android.os.UserHandle; import android.view.View; import androidx.annotation.VisibleForTesting; @@ -101,6 +104,11 @@ public class UsbDetailsFragment extends DashboardFragment { */ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = new BaseSearchIndexProvider(R.xml.usb_details_fragment) { + @Override + protected boolean isPageSearchEnabled(Context context) { + return checkIfUsbDataSignalingIsDisabled( + context, UserHandle.myUserId()) != null; + } @Override public List createPreferenceControllers( diff --git a/src/com/android/settings/development/DefaultUsbConfigurationPreferenceController.java b/src/com/android/settings/development/DefaultUsbConfigurationPreferenceController.java new file mode 100644 index 00000000000..905c552e02f --- /dev/null +++ b/src/com/android/settings/development/DefaultUsbConfigurationPreferenceController.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2021 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.development; + +import static com.android.settingslib.RestrictedLockUtilsInternal.checkIfUsbDataSignalingIsDisabled; + +import android.content.Context; +import android.os.UserHandle; + +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settingslib.RestrictedSwitchPreference; +import com.android.settingslib.development.DeveloperOptionsPreferenceController; + +public class DefaultUsbConfigurationPreferenceController extends + DeveloperOptionsPreferenceController { + + private static final String PREFERENCE_KEY = "default_usb_configuration"; + + private RestrictedSwitchPreference mPreference; + + public DefaultUsbConfigurationPreferenceController(Context context) { + super(context); + } + + @Override + public String getPreferenceKey() { + return PREFERENCE_KEY; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(getPreferenceKey()); + } + + @Override + public void updateState(Preference preference) { + mPreference.setDisabledByAdmin( + checkIfUsbDataSignalingIsDisabled(mContext, UserHandle.myUserId())); + } +} diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index e9dd9fd72b0..367e7c5086a 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -560,8 +560,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra controllers.add(new DefaultLaunchPreferenceController(context, "demo_mode")); controllers.add(new DefaultLaunchPreferenceController(context, "quick_settings_tiles")); controllers.add(new DefaultLaunchPreferenceController(context, "feature_flags_dashboard")); - controllers.add( - new DefaultLaunchPreferenceController(context, "default_usb_configuration")); + controllers.add(new DefaultUsbConfigurationPreferenceController(context)); controllers.add(new DefaultLaunchPreferenceController(context, "density")); controllers.add(new DefaultLaunchPreferenceController(context, "background_check")); controllers.add(new DefaultLaunchPreferenceController(context, "inactive_apps")); diff --git a/src/com/android/settings/development/UsbAudioRoutingPreferenceController.java b/src/com/android/settings/development/UsbAudioRoutingPreferenceController.java index 335a48de82a..8aa4f3c3be5 100644 --- a/src/com/android/settings/development/UsbAudioRoutingPreferenceController.java +++ b/src/com/android/settings/development/UsbAudioRoutingPreferenceController.java @@ -16,14 +16,19 @@ package com.android.settings.development; +import static com.android.settingslib.RestrictedLockUtilsInternal.checkIfUsbDataSignalingIsDisabled; + import android.content.Context; +import android.os.UserHandle; import android.provider.Settings; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.RestrictedSwitchPreference; import com.android.settingslib.development.DeveloperOptionsPreferenceController; public class UsbAudioRoutingPreferenceController extends DeveloperOptionsPreferenceController @@ -36,6 +41,8 @@ public class UsbAudioRoutingPreferenceController extends DeveloperOptionsPrefere @VisibleForTesting static final int SETTING_VALUE_OFF = 0; + private RestrictedSwitchPreference mPreference; + public UsbAudioRoutingPreferenceController(Context context) { super(context); } @@ -45,6 +52,12 @@ public class UsbAudioRoutingPreferenceController extends DeveloperOptionsPrefere return USB_AUDIO_KEY; } + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(getPreferenceKey()); + } + @Override public boolean onPreferenceChange(Preference preference, Object newValue) { final boolean isEnabled = (Boolean) newValue; @@ -58,7 +71,9 @@ public class UsbAudioRoutingPreferenceController extends DeveloperOptionsPrefere public void updateState(Preference preference) { final int usbAudioRoutingMode = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, SETTING_VALUE_OFF); - ((SwitchPreference) mPreference).setChecked(usbAudioRoutingMode != SETTING_VALUE_OFF); + mPreference.setChecked(usbAudioRoutingMode != SETTING_VALUE_OFF); + mPreference.setDisabledByAdmin( + checkIfUsbDataSignalingIsDisabled(mContext, UserHandle.myUserId())); } @Override diff --git a/tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java index 7c6a305c18a..5c66db7266c 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java @@ -22,11 +22,17 @@ import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SINK; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.admin.DevicePolicyManager; import android.content.Context; import android.hardware.usb.UsbManager; +import android.os.UserHandle; import com.android.settings.R; import com.android.settings.connecteddevice.DevicePreferenceCallback; @@ -55,21 +61,30 @@ public class ConnectedUsbDeviceUpdaterTest { private DevicePreferenceCallback mDevicePreferenceCallback; @Mock private UsbBackend mUsbBackend; + @Mock + private DevicePolicyManager mDevicePolicyManager; + @Before - public void setUp() { + public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; + mContext = spy(RuntimeEnvironment.application); when(mFragment.getContext()).thenReturn(mContext); mDeviceUpdater = new ConnectedUsbDeviceUpdater(mContext, mFragment, mDevicePreferenceCallback, mUsbBackend); mDeviceUpdater.mUsbReceiver = mUsbReceiver; + when(mContext.getSystemService(DevicePolicyManager.class)).thenReturn(mDevicePolicyManager); + doReturn(mContext).when(mContext).createPackageContextAsUser( + any(String.class), anyInt(), any(UserHandle.class)); } @Test public void initUsbPreference_preferenceInit() { + when(mDevicePolicyManager.isUsbDataSignalingEnabledForUser( + UserHandle.myUserId())).thenReturn(true); + mDeviceUpdater.initUsbPreference(mContext); assertThat(mDeviceUpdater.mUsbPreference.getTitle()).isEqualTo("USB"); diff --git a/tests/robotests/src/com/android/settings/development/AdbPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/AdbPreferenceControllerTest.java index 2e63f5a4e63..ba9a7aa7a13 100644 --- a/tests/robotests/src/com/android/settings/development/AdbPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/AdbPreferenceControllerTest.java @@ -18,16 +18,21 @@ package com.android.settings.development; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.admin.DevicePolicyManager; import android.content.Context; +import android.os.UserHandle; import android.provider.Settings; import androidx.preference.PreferenceScreen; -import androidx.preference.SwitchPreference; + +import com.android.settingslib.RestrictedSwitchPreference; import org.junit.Before; import org.junit.Test; @@ -41,24 +46,29 @@ import org.robolectric.RuntimeEnvironment; public class AdbPreferenceControllerTest { @Mock - private SwitchPreference mPreference; + private RestrictedSwitchPreference mPreference; @Mock private PreferenceScreen mPreferenceScreen; @Mock private DevelopmentSettingsDashboardFragment mFragment; + @Mock + private DevicePolicyManager mDevicePolicyManager; private Context mContext; private AdbPreferenceController mController; @Before - public void setup() { + public void setup() throws Exception { MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; + mContext = spy(RuntimeEnvironment.application); mController = spy(new AdbPreferenceController(mContext, mFragment)); doReturn(true).when(mController).isAvailable(); when(mPreferenceScreen.findPreference(mController.getPreferenceKey())) .thenReturn(mPreference); mController.displayPreference(mPreferenceScreen); + when(mContext.getSystemService(DevicePolicyManager.class)).thenReturn(mDevicePolicyManager); + doReturn(mContext).when(mContext).createPackageContextAsUser( + any(String.class), anyInt(), any(UserHandle.class)); } @Test diff --git a/tests/robotests/src/com/android/settings/development/DefaultUsbConfigurationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/DefaultUsbConfigurationPreferenceControllerTest.java new file mode 100644 index 00000000000..15f4eb9e7c2 --- /dev/null +++ b/tests/robotests/src/com/android/settings/development/DefaultUsbConfigurationPreferenceControllerTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2021 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.development; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; +import android.content.Context; +import android.os.UserHandle; + +import androidx.preference.PreferenceScreen; + +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedSwitchPreference; + +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 DefaultUsbConfigurationPreferenceControllerTest { + + private static final ComponentName TEST_COMPONENT_NAME = new ComponentName("test", "test"); + + @Mock + private RestrictedSwitchPreference mPreference; + @Mock + private PreferenceScreen mPreferenceScreen; + @Mock + private DevicePolicyManager mDevicePolicyManager; + + private DefaultUsbConfigurationPreferenceController mController; + + @Before + public void setup() throws Exception { + MockitoAnnotations.initMocks(this); + Context context = spy(RuntimeEnvironment.application); + mController = new DefaultUsbConfigurationPreferenceController(context); + when(mPreferenceScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mPreference); + mController.displayPreference(mPreferenceScreen); + when(context.getSystemService(DevicePolicyManager.class)).thenReturn(mDevicePolicyManager); + doReturn(context).when(context).createPackageContextAsUser( + any(String.class), anyInt(), any(UserHandle.class)); + } + + @Test + public void updateState_usbDataSignalingEnabled_shouldNotDisablePreference() { + when(mDevicePolicyManager.isUsbDataSignalingEnabledForUser( + UserHandle.myUserId())).thenReturn(true); + when(mDevicePolicyManager.getProfileOwner()).thenReturn(TEST_COMPONENT_NAME); + + mController.updateState(mPreference); + + verify(mPreference).setDisabledByAdmin(null); + } + + @Test + public void updateState_usbDataSignalingDisabled_shouldDisablePreference() { + when(mDevicePolicyManager.isUsbDataSignalingEnabledForUser( + UserHandle.myUserId())).thenReturn(false); + when(mDevicePolicyManager.getProfileOwner()).thenReturn(TEST_COMPONENT_NAME); + + mController.updateState(mPreference); + + verify(mPreference).setDisabledByAdmin(eq(new RestrictedLockUtils.EnforcedAdmin( + TEST_COMPONENT_NAME, null, UserHandle.SYSTEM))); + } +} diff --git a/tests/robotests/src/com/android/settings/development/UsbAudioRoutingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/UsbAudioRoutingPreferenceControllerTest.java index affae700d46..1d45c1b4dc7 100644 --- a/tests/robotests/src/com/android/settings/development/UsbAudioRoutingPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/UsbAudioRoutingPreferenceControllerTest.java @@ -18,14 +18,24 @@ package com.android.settings.development; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; import android.content.Context; +import android.os.UserHandle; import android.provider.Settings; import androidx.preference.PreferenceScreen; -import androidx.preference.SwitchPreference; + +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedSwitchPreference; import org.junit.Before; import org.junit.Test; @@ -38,26 +48,36 @@ import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) public class UsbAudioRoutingPreferenceControllerTest { + private static final ComponentName TEST_COMPONENT_NAME = new ComponentName("test", "test"); + @Mock private PreferenceScreen mScreen; @Mock - private SwitchPreference mPreference; + private RestrictedSwitchPreference mPreference; + @Mock + private DevicePolicyManager mDevicePolicyManager; private Context mContext; private UsbAudioRoutingPreferenceController mController; @Before - public void setUp() { + public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; + mContext = spy(RuntimeEnvironment.application); mController = new UsbAudioRoutingPreferenceController(mContext); when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); mController.displayPreference(mScreen); + when(mContext.getSystemService(DevicePolicyManager.class)).thenReturn(mDevicePolicyManager); + doReturn(mContext).when(mContext).createPackageContextAsUser( + any(String.class), anyInt(), any(UserHandle.class)); } @Test public void updateState_usbAudioRoutingEnabled_shouldCheckedPreference() { + when(mDevicePolicyManager.isUsbDataSignalingEnabledForUser( + UserHandle.myUserId())).thenReturn(true); + when(mDevicePolicyManager.getProfileOwner()).thenReturn(TEST_COMPONENT_NAME); Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, UsbAudioRoutingPreferenceController.SETTING_VALUE_ON); @@ -69,6 +89,9 @@ public class UsbAudioRoutingPreferenceControllerTest { @Test public void updateState_usbAudioRoutingDisabled_shouldUncheckedPreference() { + when(mDevicePolicyManager.isUsbDataSignalingEnabledForUser( + UserHandle.myUserId())).thenReturn(true); + when(mDevicePolicyManager.getProfileOwner()).thenReturn(TEST_COMPONENT_NAME); Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, UsbAudioRoutingPreferenceController.SETTING_VALUE_OFF); @@ -78,6 +101,18 @@ public class UsbAudioRoutingPreferenceControllerTest { verify(mPreference).setChecked(false); } + @Test + public void updateState_usbDataSignalingDisabled_shouldDisablePreference() { + when(mDevicePolicyManager.isUsbDataSignalingEnabledForUser( + UserHandle.myUserId())).thenReturn(false); + when(mDevicePolicyManager.getProfileOwner()).thenReturn(TEST_COMPONENT_NAME); + + mController.updateState(mPreference); + + verify(mPreference).setDisabledByAdmin(eq(new RestrictedLockUtils.EnforcedAdmin( + TEST_COMPONENT_NAME, null, UserHandle.SYSTEM))); + } + @Test public void onPreferenceChange_preferenceChecked_shouldEnableUsbAudioRouting() { mController.onPreferenceChange(mPreference, true /* new value */);