diff --git a/res/values/strings.xml b/res/values/strings.xml index 1ac6437720d..e065fbdfd69 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -342,8 +342,8 @@ Disable Bluetooth A2DP hardware offload - - Disable Bluetooth LE AUDIO hardware offload + + Disable Bluetooth LE audio hardware offload Restart Device? @@ -353,6 +353,11 @@ Cancel + + Enable Bluetooth LE audio + + Enables Bluetooth LE audio feature if the device supports LE audio hardware capabilities. + Media devices diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index 6319763f579..19c12091400 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -320,13 +320,18 @@ android:summary="@string/bluetooth_disable_absolute_volume_summary" /> + android:key="bluetooth_enable_leaudio" + android:title="@string/bluetooth_enable_leaudio" + android:summary="@string/bluetooth_enable_leaudio_summary" /> + + - - + android:key="location_services" + android:title="@string/location_services_preference_title" + settings:controller="com.android.settings.location.LocationInjectedServicesPreferenceController"> diff --git a/res/xml/location_services_workprofile.xml b/res/xml/location_services_workprofile.xml index 6db208367d9..a130838afec 100644 --- a/res/xml/location_services_workprofile.xml +++ b/res/xml/location_services_workprofile.xml @@ -16,12 +16,7 @@ - - - + android:title="@string/location_services_screen_title" + android:key="location_services_managed_profile" + settings:controller="com.android.settings.location.LocationInjectedServicesForWorkPreferenceController"> diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java index 30b971c0c58..9be2177524f 100644 --- a/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java +++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java @@ -99,6 +99,8 @@ public abstract class ProfileSelectFragment extends DashboardFragment { private ViewGroup mContentView; + private ViewPager2 mViewPager; + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -111,12 +113,21 @@ public abstract class ProfileSelectFragment extends DashboardFragment { final int selectedTab = getTabId(activity, getArguments()); final View tabContainer = mContentView.findViewById(R.id.tab_container); - final ViewPager2 viewPager = tabContainer.findViewById(R.id.view_pager); - viewPager.setAdapter(new ProfileSelectFragment.ViewPagerAdapter(this)); + mViewPager = tabContainer.findViewById(R.id.view_pager); + mViewPager.setAdapter(new ProfileSelectFragment.ViewPagerAdapter(this)); final TabLayout tabs = tabContainer.findViewById(R.id.tabs); - new TabLayoutMediator(tabs, viewPager, + new TabLayoutMediator(tabs, mViewPager, (tab, position) -> tab.setText(getPageTitle(position)) ).attach(); + mViewPager.registerOnPageChangeCallback( + new ViewPager2.OnPageChangeCallback() { + @Override + public void onPageSelected(int position) { + super.onPageSelected(position); + updateHeight(position); + } + } + ); tabContainer.setVisibility(View.VISIBLE); final TabLayout.Tab tab = tabs.getTabAt(selectedTab); tab.select(); @@ -133,6 +144,36 @@ public abstract class ProfileSelectFragment extends DashboardFragment { return mContentView; } + protected boolean forceUpdateHeight() { + return false; + } + + private void updateHeight(int position) { + if (!forceUpdateHeight()) { + return; + } + ViewPagerAdapter adapter = (ViewPagerAdapter) mViewPager.getAdapter(); + if (adapter == null || adapter.getItemCount() <= position) { + return; + } + + Fragment fragment = adapter.createFragment(position); + View newPage = fragment.getView(); + if (newPage != null) { + int viewWidth = View.MeasureSpec.makeMeasureSpec(newPage.getWidth(), + View.MeasureSpec.EXACTLY); + int viewHeight = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + newPage.measure(viewWidth, viewHeight); + int currentHeight = mViewPager.getLayoutParams().height; + int newHeight = newPage.getMeasuredHeight(); + if (newHeight != 0 && currentHeight != newHeight) { + ViewGroup.LayoutParams layoutParams = mViewPager.getLayoutParams(); + layoutParams.height = newHeight; + mViewPager.setLayoutParams(layoutParams); + } + } + } + @Override public int getMetricsCategory() { return METRICS_CATEGORY_UNKNOWN; diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectLocationServicesFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectLocationServicesFragment.java index 5f25f599988..111e4ce7b86 100644 --- a/src/com/android/settings/dashboard/profileselector/ProfileSelectLocationServicesFragment.java +++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectLocationServicesFragment.java @@ -50,4 +50,9 @@ public class ProfileSelectLocationServicesFragment extends ProfileSelectFragment protected int getPreferenceScreenResId() { return R.xml.location_services_header; } + + @Override + protected boolean forceUpdateHeight() { + return true; + } } diff --git a/src/com/android/settings/development/BluetoothA2dpHwOffloadPreferenceController.java b/src/com/android/settings/development/BluetoothA2dpHwOffloadPreferenceController.java index 2ffa11b6c99..793b7fbc561 100644 --- a/src/com/android/settings/development/BluetoothA2dpHwOffloadPreferenceController.java +++ b/src/com/android/settings/development/BluetoothA2dpHwOffloadPreferenceController.java @@ -53,7 +53,7 @@ public class BluetoothA2dpHwOffloadPreferenceController extends DeveloperOptions @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - BluetoothHwOffloadRebootDialog.show(mFragment); + BluetoothRebootDialog.show(mFragment); mChanged = true; return false; } @@ -93,9 +93,9 @@ public class BluetoothA2dpHwOffloadPreferenceController extends DeveloperOptions } /** - * Called when the HwOffloadDialog confirm is clicked. + * Called when the RebootDialog confirm is clicked. */ - public void onHwOffloadDialogConfirmed() { + public void onRebootDialogConfirmed() { if (!mChanged) { return; } @@ -109,9 +109,9 @@ public class BluetoothA2dpHwOffloadPreferenceController extends DeveloperOptions } /** - * Called when the HwOffloadDialog cancel is clicked. + * Called when the RebootDialog cancel is clicked. */ - public void onHwOffloadDialogCanceled() { + public void onRebootDialogCanceled() { mChanged = false; } } diff --git a/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceController.java b/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceController.java index 911b62d6cc4..751ddce79d2 100644 --- a/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceController.java +++ b/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceController.java @@ -18,6 +18,9 @@ package com.android.settings.development; import static com.android.settings.development.BluetoothA2dpHwOffloadPreferenceController.A2DP_OFFLOAD_SUPPORTED_PROPERTY; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothStatusCodes; import android.content.Context; import android.os.SystemProperties; @@ -43,6 +46,9 @@ public class BluetoothLeAudioHwOffloadPreferenceController static final String LE_AUDIO_OFFLOAD_SUPPORTED_PROPERTY = "ro.bluetooth.leaudio_offload.supported"; + @VisibleForTesting + BluetoothAdapter mBluetoothAdapter; + @VisibleForTesting boolean mChanged = false; @@ -50,6 +56,7 @@ public class BluetoothLeAudioHwOffloadPreferenceController DevelopmentSettingsDashboardFragment fragment) { super(context); mFragment = fragment; + mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter(); } @Override @@ -59,17 +66,24 @@ public class BluetoothLeAudioHwOffloadPreferenceController @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - BluetoothHwOffloadRebootDialog.show(mFragment); + BluetoothRebootDialog.show(mFragment); mChanged = true; return false; } @Override public void updateState(Preference preference) { + if (mBluetoothAdapter == null) { + return; + } + + final boolean leAudioEnabled = + (mBluetoothAdapter.isLeAudioSupported() == BluetoothStatusCodes.FEATURE_SUPPORTED); + final boolean offloadSupported = SystemProperties.getBoolean(A2DP_OFFLOAD_SUPPORTED_PROPERTY, false) && SystemProperties.getBoolean(LE_AUDIO_OFFLOAD_SUPPORTED_PROPERTY, false); - if (offloadSupported) { + if (leAudioEnabled && offloadSupported) { final boolean offloadDisabled = SystemProperties.getBoolean(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, true); ((SwitchPreference) mPreference).setChecked(offloadDisabled); @@ -82,12 +96,20 @@ public class BluetoothLeAudioHwOffloadPreferenceController @Override protected void onDeveloperOptionsSwitchDisabled() { super.onDeveloperOptionsSwitchDisabled(); + if (mBluetoothAdapter == null) { + return; + } + + final boolean leAudioEnabled = + (mBluetoothAdapter.isLeAudioSupported() == BluetoothStatusCodes.FEATURE_SUPPORTED); final boolean offloadSupported = SystemProperties.getBoolean(A2DP_OFFLOAD_SUPPORTED_PROPERTY, false) && SystemProperties.getBoolean(LE_AUDIO_OFFLOAD_SUPPORTED_PROPERTY, false); - if (offloadSupported) { + if (leAudioEnabled && offloadSupported) { ((SwitchPreference) mPreference).setChecked(true); SystemProperties.set(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, "true"); + } else { + mPreference.setEnabled(false); } } @@ -104,9 +126,9 @@ public class BluetoothLeAudioHwOffloadPreferenceController } /** - * Called when the HwOffloadDialog confirm is clicked. + * Called when the RebootDialog confirm is clicked. */ - public void onHwOffloadDialogConfirmed() { + public void onRebootDialogConfirmed() { if (!mChanged) { return; } @@ -119,9 +141,9 @@ public class BluetoothLeAudioHwOffloadPreferenceController } /** - * Called when the HwOffloadDialog cancel is clicked. + * Called when the RebootDialog cancel is clicked. */ - public void onHwOffloadDialogCanceled() { + public void onRebootDialogCanceled() { mChanged = false; } } diff --git a/src/com/android/settings/development/BluetoothLeAudioPreferenceController.java b/src/com/android/settings/development/BluetoothLeAudioPreferenceController.java new file mode 100644 index 00000000000..00d0dd27af6 --- /dev/null +++ b/src/com/android/settings/development/BluetoothLeAudioPreferenceController.java @@ -0,0 +1,114 @@ +/* + * Copyright 2022 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 android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothStatusCodes; +import android.content.Context; +import android.os.SystemProperties; + +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; +import androidx.preference.SwitchPreference; + +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.development.DeveloperOptionsPreferenceController; + +/** + * Preference controller to control Bluetooth LE audio feature + */ +public class BluetoothLeAudioPreferenceController + extends DeveloperOptionsPreferenceController + implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin { + + private static final String PREFERENCE_KEY = "bluetooth_enable_leaudio"; + + private static final String LE_AUDIO_DYNAMIC_SWITCH_PROPERTY = + "ro.bluetooth.leaudio_switcher.supported"; + @VisibleForTesting + static final String LE_AUDIO_DYNAMIC_ENABLED_PROPERTY = + "persist.bluetooth.leaudio_switcher.enabled"; + + private final DevelopmentSettingsDashboardFragment mFragment; + + @VisibleForTesting + BluetoothAdapter mBluetoothAdapter; + + @VisibleForTesting + boolean mChanged = false; + + public BluetoothLeAudioPreferenceController(Context context, + DevelopmentSettingsDashboardFragment fragment) { + super(context); + mFragment = fragment; + mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter(); + } + + @Override + public String getPreferenceKey() { + return PREFERENCE_KEY; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + BluetoothRebootDialog.show(mFragment); + mChanged = true; + return false; + } + + @Override + public void updateState(Preference preference) { + if (mBluetoothAdapter == null) { + return; + } + + final boolean leAudioEnabled = + (mBluetoothAdapter.isLeAudioSupported() == BluetoothStatusCodes.FEATURE_SUPPORTED); + ((SwitchPreference) mPreference).setChecked(leAudioEnabled); + + final boolean leAudioSwitchSupported = + SystemProperties.getBoolean(LE_AUDIO_DYNAMIC_SWITCH_PROPERTY, false); + if (!leAudioSwitchSupported) { + mPreference.setEnabled(false); + } else { + SystemProperties.set(LE_AUDIO_DYNAMIC_ENABLED_PROPERTY, + Boolean.toString(leAudioEnabled)); + } + } + + /** + * Called when the RebootDialog confirm is clicked. + */ + public void onRebootDialogConfirmed() { + if (!mChanged || mBluetoothAdapter == null) { + return; + } + + final boolean leAudioEnabled = + (mBluetoothAdapter.isLeAudioSupported() == BluetoothStatusCodes.FEATURE_SUPPORTED); + SystemProperties.set(LE_AUDIO_DYNAMIC_ENABLED_PROPERTY, + Boolean.toString(!leAudioEnabled)); + } + + /** + * Called when the RebootDialog cancel is clicked. + */ + public void onRebootDialogCanceled() { + mChanged = false; + } +} diff --git a/src/com/android/settings/development/BluetoothHwOffloadRebootDialog.java b/src/com/android/settings/development/BluetoothRebootDialog.java similarity index 74% rename from src/com/android/settings/development/BluetoothHwOffloadRebootDialog.java rename to src/com/android/settings/development/BluetoothRebootDialog.java index 389103e816d..90f4c0c59b4 100644 --- a/src/com/android/settings/development/BluetoothHwOffloadRebootDialog.java +++ b/src/com/android/settings/development/BluetoothRebootDialog.java @@ -29,22 +29,23 @@ import com.android.settings.R; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; /** - * The a2dp and LE audio offload switch should reboot the device to take effect, the dialog is - * to ask the user to reboot the device after a2dp or LE audio offload user preference changed + * The a2dp/LE audio offload and LE audio feature switch should reboot the device to take effect, + * the dialog is to ask the user to reboot the device after a2dp/LE audio offload and LE audio + * feature user preference changed */ -public class BluetoothHwOffloadRebootDialog extends InstrumentedDialogFragment +public class BluetoothRebootDialog extends InstrumentedDialogFragment implements DialogInterface.OnClickListener { - public static final String TAG = "BluetoothHwOffloadReboot"; + public static final String TAG = "BluetoothReboot"; /** - * The function to show the HwOffloadReboot Dialog. + * The function to show the Reboot Dialog. */ public static void show(DevelopmentSettingsDashboardFragment host) { final FragmentManager manager = host.getActivity().getSupportFragmentManager(); if (manager.findFragmentByTag(TAG) == null) { - final BluetoothHwOffloadRebootDialog dialog = - new BluetoothHwOffloadRebootDialog(); + final BluetoothRebootDialog dialog = + new BluetoothRebootDialog(); dialog.setTargetFragment(host, 0 /* requestCode */); dialog.show(manager, TAG); } @@ -69,33 +70,33 @@ public class BluetoothHwOffloadRebootDialog extends InstrumentedDialogFragment @Override public void onClick(DialogInterface dialog, int which) { - final OnHwOffloadDialogListener host = - (OnHwOffloadDialogListener) getTargetFragment(); + final OnRebootDialogListener host = + (OnRebootDialogListener) getTargetFragment(); if (host == null) { return; } if (which == DialogInterface.BUTTON_POSITIVE) { - host.onHwOffloadDialogConfirmed(); + host.onRebootDialogConfirmed(); PowerManager pm = getContext().getSystemService(PowerManager.class); pm.reboot(null); } else { - host.onHwOffloadDialogCanceled(); + host.onRebootDialogCanceled(); } } /** - * The interface for the HsOffloadDialogListener to provide the action as the + * The interface for the RebootDialogListener to provide the action as the * confirmed or canceled clicked. */ - public interface OnHwOffloadDialogListener { + public interface OnRebootDialogListener { /** * Called when the user presses reboot on the warning dialog. */ - void onHwOffloadDialogConfirmed(); + void onRebootDialogConfirmed(); /** * Called when the user presses cancel on the warning dialog. */ - void onHwOffloadDialogCanceled(); + void onRebootDialogCanceled(); } } diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index 3fbea5249a0..d92fb7fd99b 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -80,7 +80,7 @@ import java.util.List; public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFragment implements OnMainSwitchChangeListener, OemUnlockDialogHost, AdbDialogHost, AdbClearKeysDialogHost, LogPersistDialogHost, - BluetoothHwOffloadRebootDialog.OnHwOffloadDialogListener, + BluetoothRebootDialog.OnRebootDialogListener, AbstractBluetoothPreferenceController.Callback { private static final String TAG = "DevSettingsDashboard"; @@ -362,27 +362,37 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra } @Override - public void onHwOffloadDialogConfirmed() { + public void onRebootDialogConfirmed() { final BluetoothA2dpHwOffloadPreferenceController a2dpController = getDevelopmentOptionsController(BluetoothA2dpHwOffloadPreferenceController.class); - a2dpController.onHwOffloadDialogConfirmed(); + a2dpController.onRebootDialogConfirmed(); final BluetoothLeAudioHwOffloadPreferenceController leAudioController = getDevelopmentOptionsController( BluetoothLeAudioHwOffloadPreferenceController.class); - leAudioController.onHwOffloadDialogConfirmed(); + leAudioController.onRebootDialogConfirmed(); + + final BluetoothLeAudioPreferenceController leAudioFeatureController = + getDevelopmentOptionsController( + BluetoothLeAudioPreferenceController.class); + leAudioFeatureController.onRebootDialogConfirmed(); } @Override - public void onHwOffloadDialogCanceled() { + public void onRebootDialogCanceled() { final BluetoothA2dpHwOffloadPreferenceController a2dpController = getDevelopmentOptionsController(BluetoothA2dpHwOffloadPreferenceController.class); - a2dpController.onHwOffloadDialogCanceled(); + a2dpController.onRebootDialogCanceled(); final BluetoothLeAudioHwOffloadPreferenceController leAudioController = getDevelopmentOptionsController( BluetoothLeAudioHwOffloadPreferenceController.class); - leAudioController.onHwOffloadDialogCanceled(); + leAudioController.onRebootDialogCanceled(); + + final BluetoothLeAudioPreferenceController leAudioFeatureController = + getDevelopmentOptionsController( + BluetoothLeAudioPreferenceController.class); + leAudioFeatureController.onRebootDialogCanceled(); } @Override @@ -540,6 +550,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra controllers.add(new BluetoothAbsoluteVolumePreferenceController(context)); controllers.add(new BluetoothAvrcpVersionPreferenceController(context)); controllers.add(new BluetoothMapVersionPreferenceController(context)); + controllers.add(new BluetoothLeAudioPreferenceController(context, fragment)); controllers.add(new BluetoothA2dpHwOffloadPreferenceController(context, fragment)); controllers.add(new BluetoothLeAudioHwOffloadPreferenceController(context, fragment)); controllers.add(new BluetoothMaxConnectedAudioDevicesPreferenceController(context)); diff --git a/src/com/android/settings/location/LocationInjectedServicesForWorkPreferenceController.java b/src/com/android/settings/location/LocationInjectedServicesForWorkPreferenceController.java index b7e6cf2a412..a8a13b3ca76 100644 --- a/src/com/android/settings/location/LocationInjectedServicesForWorkPreferenceController.java +++ b/src/com/android/settings/location/LocationInjectedServicesForWorkPreferenceController.java @@ -20,7 +20,6 @@ import android.content.Context; import android.os.UserHandle; import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; import com.android.settings.widget.RestrictedAppPreference; @@ -41,8 +40,6 @@ public class LocationInjectedServicesForWorkPreferenceController extends @Override protected void injectLocationServices(PreferenceScreen screen) { - final PreferenceCategory categoryLocationServices = - screen.findPreference(getPreferenceKey()); final Map> prefs = getLocationServices(); for (Map.Entry> entry : prefs.entrySet()) { for (Preference pref : entry.getValue()) { @@ -51,7 +48,7 @@ public class LocationInjectedServicesForWorkPreferenceController extends } } if (entry.getKey() != UserHandle.myUserId()) { - LocationSettings.addPreferencesSorted(entry.getValue(), categoryLocationServices); + LocationSettings.addPreferencesSorted(entry.getValue(), screen); } } } diff --git a/src/com/android/settings/location/LocationInjectedServicesPreferenceController.java b/src/com/android/settings/location/LocationInjectedServicesPreferenceController.java index d623baef56c..356716d3a68 100644 --- a/src/com/android/settings/location/LocationInjectedServicesPreferenceController.java +++ b/src/com/android/settings/location/LocationInjectedServicesPreferenceController.java @@ -19,7 +19,6 @@ import android.content.Context; import android.os.UserHandle; import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; import com.android.settings.widget.RestrictedAppPreference; @@ -41,8 +40,6 @@ public class LocationInjectedServicesPreferenceController @Override protected void injectLocationServices(PreferenceScreen screen) { - final PreferenceCategory categoryLocationServices = - screen.findPreference(getPreferenceKey()); final Map> prefs = getLocationServices(); for (Map.Entry> entry : prefs.entrySet()) { for (Preference pref : entry.getValue()) { @@ -51,10 +48,7 @@ public class LocationInjectedServicesPreferenceController } } if (entry.getKey() == UserHandle.myUserId()) { - if (categoryLocationServices != null) { - LocationSettings.addPreferencesSorted(entry.getValue(), - categoryLocationServices); - } + LocationSettings.addPreferencesSorted(entry.getValue(), screen); } } } diff --git a/src/com/android/settings/location/LocationServices.java b/src/com/android/settings/location/LocationServices.java index aceb9d56583..52e958cb093 100644 --- a/src/com/android/settings/location/LocationServices.java +++ b/src/com/android/settings/location/LocationServices.java @@ -22,12 +22,8 @@ import android.content.Context; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.search.SearchIndexable; -import java.util.ArrayList; -import java.util.List; - /** * A page that configures the Location Services settings including Wi-Fi scanning, Bluetooth * scanning, and injected location services. @@ -51,11 +47,6 @@ public class LocationServices extends DashboardFragment { return TAG; } - @Override - protected List createPreferenceControllers(Context context) { - return buildPreferenceControllers(context); - } - @Override public void onAttach(Context context) { super.onAttach(context); @@ -63,23 +54,9 @@ public class LocationServices extends DashboardFragment { use(LocationInjectedServicesPreferenceController.class).init(this); } - private static List buildPreferenceControllers(Context context) { - final List controllers = new ArrayList<>(); - controllers.add(new WifiScanningPreferenceController(context)); - controllers.add(new BluetoothScanningPreferenceController(context)); - return controllers; - } - /** * For Search. */ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.location_services) { - - @Override - public List createPreferenceControllers(Context - context) { - return buildPreferenceControllers(context); - } - }; + new BaseSearchIndexProvider(R.xml.location_services); } diff --git a/src/com/android/settings/location/LocationServicesForWork.java b/src/com/android/settings/location/LocationServicesForWork.java index 4b3124eb129..390be101ddf 100644 --- a/src/com/android/settings/location/LocationServicesForWork.java +++ b/src/com/android/settings/location/LocationServicesForWork.java @@ -22,12 +22,8 @@ import android.content.Context; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.search.SearchIndexable; -import java.util.ArrayList; -import java.util.List; - /** * A page that configures the Location Services settings for work profile. */ @@ -50,32 +46,15 @@ public class LocationServicesForWork extends DashboardFragment { return TAG; } - @Override - protected List createPreferenceControllers(Context context) { - return buildPreferenceControllers(context); - } - @Override public void onAttach(Context context) { super.onAttach(context); use(LocationInjectedServicesForWorkPreferenceController.class).init(this); } - private static List buildPreferenceControllers(Context context) { - final List controllers = new ArrayList<>(); - return controllers; - } - /** * For Search. */ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.location_services_workprofile) { - - @Override - public List createPreferenceControllers(Context - context) { - return buildPreferenceControllers(context); - } - }; + new BaseSearchIndexProvider(R.xml.location_services_workprofile); } diff --git a/src/com/android/settings/wifi/ConfigureWifiSettings.java b/src/com/android/settings/wifi/ConfigureWifiSettings.java index 6bb4389bddb..33f2827d7f8 100644 --- a/src/com/android/settings/wifi/ConfigureWifiSettings.java +++ b/src/com/android/settings/wifi/ConfigureWifiSettings.java @@ -15,19 +15,21 @@ */ package com.android.settings.wifi; -import static android.content.Context.WIFI_SERVICE; - +import android.annotation.Nullable; import android.app.settings.SettingsEnums; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.net.wifi.WifiManager; import android.os.Bundle; -import android.util.FeatureFlagUtils; +import android.os.UserManager; +import android.util.EventLog; import android.util.Log; +import android.view.View; +import android.widget.TextView; +import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; @@ -43,7 +45,8 @@ import java.util.List; public class ConfigureWifiSettings extends DashboardFragment { private static final String TAG = "ConfigureWifiSettings"; - private static final String KEY_INSTALL_CREDENTIALS = "install_credentials"; + @VisibleForTesting + static final String KEY_INSTALL_CREDENTIALS = "install_credentials"; private static final String ACTION_INSTALL_CERTS = "android.credentials.INSTALL"; private static final String PACKAGE_INSTALL_CERTS = "com.android.certinstaller"; private static final String CLASS_INSTALL_CERTS = "com.android.certinstaller.CertInstallerMain"; @@ -53,16 +56,26 @@ public class ConfigureWifiSettings extends DashboardFragment { public static final int WIFI_WAKEUP_REQUEST_CODE = 600; private WifiWakeupPreferenceController mWifiWakeupPreferenceController; - private Preference mCertinstallerPreference; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + if (isGuestUser(context)) return; + + mWifiWakeupPreferenceController = use(WifiWakeupPreferenceController.class); + mWifiWakeupPreferenceController.setFragment(this); + } @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); getActivity().setTitle(R.string.network_and_internet_preferences_title); - mCertinstallerPreference = findPreference(KEY_INSTALL_CREDENTIALS); - if (mCertinstallerPreference != null) { - mCertinstallerPreference.setOnPreferenceClickListener(preference -> { + if (isGuestUser(getContext())) return; + + final Preference installCredentialsPref = findPreference(KEY_INSTALL_CREDENTIALS); + if (installCredentialsPref != null) { + installCredentialsPref.setOnPreferenceClickListener(preference -> { Intent intent = new Intent(ACTION_INSTALL_CERTS); intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK); @@ -77,6 +90,23 @@ public class ConfigureWifiSettings extends DashboardFragment { } } + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (!isGuestUser(getContext())) return; + + Log.w(TAG, "Displays the restricted UI because the user is a guest."); + EventLog.writeEvent(0x534e4554, "231987122", -1 /* UID */, "User is a guest"); + + // Restricted UI + final TextView emptyView = getActivity().findViewById(android.R.id.empty); + if (emptyView != null) { + emptyView.setVisibility(View.VISIBLE); + emptyView.setText(R.string.wifi_empty_list_user_restricted); + } + getPreferenceScreen().removeAll(); + } + @Override public int getMetricsCategory() { return SettingsEnums.CONFIGURE_WIFI; @@ -94,25 +124,18 @@ public class ConfigureWifiSettings extends DashboardFragment { @Override protected List createPreferenceControllers(Context context) { - final WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); + if (isGuestUser(context)) return null; + + final WifiManager wifiManager = getSystemService(WifiManager.class); final List controllers = new ArrayList<>(); controllers.add(new WifiP2pPreferenceController(context, getSettingsLifecycle(), wifiManager)); return controllers; } - @Override - public void onAttach(Context context) { - super.onAttach(context); - - - mWifiWakeupPreferenceController = use(WifiWakeupPreferenceController.class); - mWifiWakeupPreferenceController.setFragment(this); - } - @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == WIFI_WAKEUP_REQUEST_CODE) { + if (mWifiWakeupPreferenceController != null && requestCode == WIFI_WAKEUP_REQUEST_CODE) { mWifiWakeupPreferenceController.onActivityResult(requestCode, resultCode); return; } @@ -122,8 +145,16 @@ public class ConfigureWifiSettings extends DashboardFragment { public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = new BaseSearchIndexProvider(R.xml.wifi_configure_settings) { protected boolean isPageSearchEnabled(Context context) { + if (isGuestUser(context)) return false; return context.getResources() .getBoolean(R.bool.config_show_wifi_settings); } }; + + private static boolean isGuestUser(Context context) { + if (context == null) return false; + final UserManager userManager = context.getSystemService(UserManager.class); + if (userManager == null) return false; + return userManager.isGuestUser(); + } } diff --git a/src/com/android/settings/wifi/WifiDialogActivity.java b/src/com/android/settings/wifi/WifiDialogActivity.java index 67f291da49d..8a46c9d18c5 100644 --- a/src/com/android/settings/wifi/WifiDialogActivity.java +++ b/src/com/android/settings/wifi/WifiDialogActivity.java @@ -17,6 +17,7 @@ package com.android.settings.wifi; import static android.Manifest.permission.ACCESS_FINE_LOCATION; +import static android.os.UserManager.DISALLOW_CONFIG_WIFI; import android.content.DialogInterface; import android.content.Intent; @@ -31,6 +32,7 @@ import android.os.Looper; import android.os.Process; import android.os.SimpleClock; import android.os.SystemClock; +import android.os.UserManager; import android.text.TextUtils; import android.util.EventLog; import android.util.Log; @@ -115,6 +117,10 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog } super.onCreate(savedInstanceState); + if (!isConfigWifiAllowed()) { + finish(); + return; + } mIsWifiTrackerLib = !TextUtils.isEmpty(mIntent.getStringExtra(KEY_CHOSEN_WIFIENTRY_KEY)); @@ -361,6 +367,19 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog } } + @VisibleForTesting + boolean isConfigWifiAllowed() { + UserManager userManager = getSystemService(UserManager.class); + if (userManager == null) return true; + final boolean isConfigWifiAllowed = !userManager.hasUserRestriction(DISALLOW_CONFIG_WIFI); + if (!isConfigWifiAllowed) { + Log.e(TAG, "The user is not allowed to configure Wi-Fi."); + EventLog.writeEvent(0x534e4554, "226133034", getApplicationContext().getUserId(), + "The user is not allowed to configure Wi-Fi."); + } + return isConfigWifiAllowed; + } + private boolean hasWifiManager() { if (mWifiManager != null) return true; mWifiManager = getSystemService(WifiManager.class); diff --git a/tests/robotests/src/com/android/settings/development/BluetoothA2dpHwOffloadPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothA2dpHwOffloadPreferenceControllerTest.java index fcb3ea929a4..660c8f1bac8 100644 --- a/tests/robotests/src/com/android/settings/development/BluetoothA2dpHwOffloadPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/BluetoothA2dpHwOffloadPreferenceControllerTest.java @@ -68,7 +68,7 @@ public class BluetoothA2dpHwOffloadPreferenceControllerTest { SystemProperties.set(A2DP_OFFLOAD_DISABLED_PROPERTY, Boolean.toString(false)); mController.mChanged = true; - mController.onHwOffloadDialogConfirmed(); + mController.onRebootDialogConfirmed(); final boolean mode = SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false); assertThat(mode).isTrue(); } @@ -80,7 +80,7 @@ public class BluetoothA2dpHwOffloadPreferenceControllerTest { mController.mChanged = true; - mController.onHwOffloadDialogConfirmed(); + mController.onRebootDialogConfirmed(); final boolean a2dpMode = SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, true); final boolean leAudioMode = SystemProperties .getBoolean(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, true); @@ -93,7 +93,7 @@ public class BluetoothA2dpHwOffloadPreferenceControllerTest { SystemProperties.set(A2DP_OFFLOAD_DISABLED_PROPERTY, Boolean.toString(false)); mController.mChanged = true; - mController.onHwOffloadDialogCanceled(); + mController.onRebootDialogCanceled(); final boolean mode = SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false); assertThat(mode).isFalse(); } diff --git a/tests/robotests/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceControllerTest.java index c82df40e038..ec64fe348d9 100644 --- a/tests/robotests/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceControllerTest.java @@ -66,7 +66,7 @@ public class BluetoothLeAudioHwOffloadPreferenceControllerTest { SystemProperties.set(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, Boolean.toString(false)); mController.mChanged = true; - mController.onHwOffloadDialogConfirmed(); + mController.onRebootDialogConfirmed(); final boolean mode = SystemProperties.getBoolean(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, false); assertThat(mode).isTrue(); } @@ -76,7 +76,7 @@ public class BluetoothLeAudioHwOffloadPreferenceControllerTest { SystemProperties.set(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, Boolean.toString(true)); mController.mChanged = true; - mController.onHwOffloadDialogConfirmed(); + mController.onRebootDialogConfirmed(); final boolean mode2 = SystemProperties.getBoolean( LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, true); assertThat(mode2).isFalse(); @@ -87,7 +87,7 @@ public class BluetoothLeAudioHwOffloadPreferenceControllerTest { SystemProperties.set(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, Boolean.toString(false)); mController.mChanged = true; - mController.onHwOffloadDialogCanceled(); + mController.onRebootDialogCanceled(); final boolean mode = SystemProperties.getBoolean(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, false); assertThat(mode).isFalse(); } diff --git a/tests/robotests/src/com/android/settings/development/BluetoothLeAudioPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothLeAudioPreferenceControllerTest.java new file mode 100644 index 00000000000..527fabbc526 --- /dev/null +++ b/tests/robotests/src/com/android/settings/development/BluetoothLeAudioPreferenceControllerTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2022 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.settings.development.BluetoothLeAudioPreferenceController + .LE_AUDIO_DYNAMIC_ENABLED_PROPERTY; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothStatusCodes; +import android.content.Context; +import android.os.SystemProperties; + +import androidx.preference.PreferenceScreen; +import androidx.preference.SwitchPreference; + +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 BluetoothLeAudioPreferenceControllerTest { + + @Mock + private PreferenceScreen mPreferenceScreen; + @Mock + private DevelopmentSettingsDashboardFragment mFragment; + + @Mock + private BluetoothAdapter mBluetoothAdapter; + + private Context mContext; + private SwitchPreference mPreference; + private BluetoothLeAudioPreferenceController mController; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mPreference = new SwitchPreference(mContext); + mController = spy(new BluetoothLeAudioPreferenceController(mContext, mFragment)); + when(mPreferenceScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mPreference); + mController.mBluetoothAdapter = mBluetoothAdapter; + mController.displayPreference(mPreferenceScreen); + } + + @Test + public void onRebootDialogConfirmedAsLeAudioDisabled_shouldSwitchStatus() { + when(mBluetoothAdapter.isLeAudioSupported()) + .thenReturn(BluetoothStatusCodes.FEATURE_NOT_SUPPORTED); + mController.mChanged = true; + + mController.onRebootDialogConfirmed(); + final boolean status = SystemProperties + .getBoolean(LE_AUDIO_DYNAMIC_ENABLED_PROPERTY, false); + assertThat(status).isTrue(); + } + + @Test + public void onRebootDialogConfirmedAsLeAudioEnabled_shouldSwitchStatus() { + when(mBluetoothAdapter.isLeAudioSupported()) + .thenReturn(BluetoothStatusCodes.FEATURE_SUPPORTED); + mController.mChanged = true; + + mController.onRebootDialogConfirmed(); + final boolean status = SystemProperties + .getBoolean(LE_AUDIO_DYNAMIC_ENABLED_PROPERTY, false); + assertThat(status).isFalse(); + } + + @Test + public void onRebootDialogCanceled_shouldNotSwitchStatus() { + when(mBluetoothAdapter.isLeAudioSupported()) + .thenReturn(BluetoothStatusCodes.FEATURE_NOT_SUPPORTED); + mController.mChanged = true; + + mController.onRebootDialogCanceled(); + final boolean status = SystemProperties + .getBoolean(LE_AUDIO_DYNAMIC_ENABLED_PROPERTY, false); + assertThat(status).isFalse(); + } +} diff --git a/tests/robotests/src/com/android/settings/wifi/ConfigureWifiSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/ConfigureWifiSettingsTest.java index 89df035c8d5..5e3d7150bb5 100644 --- a/tests/robotests/src/com/android/settings/wifi/ConfigureWifiSettingsTest.java +++ b/tests/robotests/src/com/android/settings/wifi/ConfigureWifiSettingsTest.java @@ -1,41 +1,180 @@ package com.android.settings.wifi; +import static com.android.settings.wifi.ConfigureWifiSettings.KEY_INSTALL_CREDENTIALS; + import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import android.annotation.Nullable; import android.content.Context; +import android.net.wifi.WifiManager; +import android.os.Bundle; +import android.os.UserManager; +import android.view.View; +import android.widget.TextView; +import androidx.fragment.app.FragmentActivity; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; +import androidx.test.core.app.ApplicationProvider; + +import com.android.settings.dashboard.DashboardFragment; import com.android.settings.testutils.XmlTestUtils; +import com.android.settingslib.core.AbstractPreferenceController; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; import java.util.List; @RunWith(RobolectricTestRunner.class) public class ConfigureWifiSettingsTest { - private Context mContext; + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Spy + Context mContext = ApplicationProvider.getApplicationContext(); + @Mock + UserManager mUserManager; + @Mock + WifiManager mWifiManager; + @Mock + FragmentActivity mActivity; + @Mock + WifiWakeupPreferenceController mWifiWakeupPreferenceController; + @Mock + Preference mInstallCredentialsPref; + @Mock + PreferenceScreen mPreferenceScreen; + @Mock + TextView mEmptyView; + + TestConfigureWifiSettings mSettings; @Before public void setUp() { - mContext = spy(RuntimeEnvironment.application); + when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); + when(mUserManager.isGuestUser()).thenReturn(false); + when(mActivity.getSystemService(WifiManager.class)).thenReturn(mWifiManager); + + mSettings = spy(new TestConfigureWifiSettings()); + when(mSettings.getContext()).thenReturn(mContext); + when(mSettings.getActivity()).thenReturn(mActivity); + when(mSettings.use(WifiWakeupPreferenceController.class)) + .thenReturn(mWifiWakeupPreferenceController); + when(mSettings.findPreference(KEY_INSTALL_CREDENTIALS)).thenReturn(mInstallCredentialsPref); + } + + @Test + public void onAttach_isNotGuestUser_setupController() { + when(mUserManager.isGuestUser()).thenReturn(false); + + mSettings.onAttach(mContext); + + verify(mWifiWakeupPreferenceController).setFragment(any()); + } + + @Test + public void onAttach_isGuestUser_doNotSetupController() { + when(mUserManager.isGuestUser()).thenReturn(true); + + mSettings.onAttach(mContext); + + verify(mWifiWakeupPreferenceController, never()).setFragment(any()); + } + + @Test + @Config(shadows = ShadowDashboardFragment.class) + public void onCreate_isNotGuestUser_setupPreference() { + when(mUserManager.isGuestUser()).thenReturn(false); + + mSettings.onCreate(null); + + verify(mInstallCredentialsPref).setOnPreferenceClickListener(any()); + } + + @Test + @Config(shadows = ShadowDashboardFragment.class) + public void onCreate_isGuestUser_doNotSetupPreference() { + when(mUserManager.isGuestUser()).thenReturn(true); + + mSettings.onCreate(null); + + verify(mInstallCredentialsPref, never()).setOnPreferenceClickListener(any()); + } + + @Test + @Config(shadows = ShadowDashboardFragment.class) + public void onViewCreated_isNotGuestUser_doNotRestrictUi() { + when(mUserManager.isGuestUser()).thenReturn(false); + when(mActivity.findViewById(android.R.id.empty)).thenReturn(mEmptyView); + doReturn(mPreferenceScreen).when(mSettings).getPreferenceScreen(); + + mSettings.onViewCreated(mock(View.class), null); + + verify(mEmptyView, never()).setVisibility(View.VISIBLE); + verify(mPreferenceScreen, never()).removeAll(); + } + + @Test + @Config(shadows = ShadowDashboardFragment.class) + public void onViewCreated_isGuestUser_restrictUi() { + when(mUserManager.isGuestUser()).thenReturn(true); + when(mActivity.findViewById(android.R.id.empty)).thenReturn(mEmptyView); + doReturn(mPreferenceScreen).when(mSettings).getPreferenceScreen(); + + mSettings.onViewCreated(mock(View.class), null); + + verify(mEmptyView).setVisibility(View.VISIBLE); + verify(mPreferenceScreen).removeAll(); } @Test @Config(qualifiers = "mcc999") - public void testNonIndexableKeys_ifPageDisabled_shouldNotIndexResource() { + public void getNonIndexableKeys_ifPageDisabled_shouldNotIndexResource() { final List niks = ConfigureWifiSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext); - final int xmlId = new ConfigureWifiSettings().getPreferenceScreenResId(); + final int xmlId = mSettings.getPreferenceScreenResId(); final List keys = XmlTestUtils.getKeysFromPreferenceXml(mContext, xmlId); assertThat(keys).isNotNull(); assertThat(niks).containsAtLeastElementsIn(keys); } + + public static class TestConfigureWifiSettings extends ConfigureWifiSettings { + @Override + public T use(Class clazz) { + return super.use(clazz); + } + } + + @Implements(DashboardFragment.class) + public static class ShadowDashboardFragment { + @Implementation + public void onCreate(Bundle icicle) { + // do nothing + } + + @Implementation + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + // do nothing + } + } } diff --git a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java index 4ceb1e3b002..28b7ecbf09b 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java @@ -18,6 +18,7 @@ package com.android.settings.wifi; import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION; +import static android.os.UserManager.DISALLOW_CONFIG_WIFI; import static com.android.settings.wifi.WifiDialogActivity.REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER; import static com.android.settings.wifi.WifiDialogActivity.RESULT_CONNECTED; @@ -36,6 +37,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; +import android.os.UserManager; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settingslib.wifi.AccessPoint; @@ -44,6 +46,7 @@ import com.android.wifitrackerlib.WifiEntry; import com.google.android.setupcompat.util.WizardManagerHelper; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -57,6 +60,8 @@ public class WifiDialogActivityTest { static final String CALLING_PACKAGE = "calling_package"; static final int REQUEST_CODE = REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER; + @Mock + UserManager mUserManager; @Mock PackageManager mPackageManager; @Mock @@ -92,6 +97,7 @@ public class WifiDialogActivityTest { FakeFeatureFactory.setupForTest(); mActivity = spy(Robolectric.setupActivity(WifiDialogActivity.class)); + when(mActivity.getSystemService(UserManager.class)).thenReturn(mUserManager); when(mActivity.getSystemService(WifiManager.class)).thenReturn(mWifiManager); } @@ -211,6 +217,20 @@ public class WifiDialogActivityTest { verify(mActivity).setResult(RESULT_CONNECTED, mResultData); } + @Test + public void isConfigWifiAllowed_hasNoUserRestriction_returnTrue() { + when(mUserManager.hasUserRestriction(DISALLOW_CONFIG_WIFI)).thenReturn(false); + + assertThat(mActivity.isConfigWifiAllowed()).isTrue(); + } + + @Test + public void isConfigWifiAllowed_hasUserRestriction_returnFalse() { + when(mUserManager.hasUserRestriction(DISALLOW_CONFIG_WIFI)).thenReturn(true); + + assertThat(mActivity.isConfigWifiAllowed()).isFalse(); + } + @Test public void hasPermissionForResult_noCallingPackage_returnFalse() { when(mActivity.getCallingPackage()).thenReturn(null);