diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java index 7dbf3338ddb..fa76a948c06 100644 --- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java +++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java @@ -313,21 +313,7 @@ public class DeviceAdminAdd extends CollapsingToolbarBaseActivity { // otherwise, only the defined default supervision profile owner or holder of // supersvision role can be set after user setup. - final String supervisor = getString( - com.android.internal.R.string.config_defaultSupervisionProfileOwnerComponent); - final String supervisionRolePackage = getString( - com.android.internal.R.string.config_systemSupervision); - if (TextUtils.isEmpty(supervisor) && TextUtils.isEmpty(supervisionRolePackage)) { - Log.w(TAG, "Unable to set profile owner post-setup, no default supervisor" - + "profile owner defined"); - finish(); - return; - } - - final ComponentName supervisorComponent = ComponentName.unflattenFromString( - supervisor); - if (!who.equals(supervisorComponent) - && !who.getPackageName().equals(supervisionRolePackage)) { + if (!mDPM.isSupervisionComponent(who)) { Log.w(TAG, "Unable to set non-default profile owner post-setup " + who); finish(); return; diff --git a/src/com/android/settings/display/ScreenResolutionFragment.java b/src/com/android/settings/display/ScreenResolutionFragment.java index 3b08ae7f00b..a827e923bb0 100644 --- a/src/com/android/settings/display/ScreenResolutionFragment.java +++ b/src/com/android/settings/display/ScreenResolutionFragment.java @@ -19,6 +19,7 @@ package com.android.settings.display; import static com.android.settings.display.ScreenResolutionController.FHD_WIDTH; import static com.android.settings.display.ScreenResolutionController.QHD_WIDTH; +import android.annotation.Nullable; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.res.Resources; @@ -34,6 +35,7 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.widget.RadioButtonPickerFragment; +import com.android.settingslib.display.DisplayDensityUtils; import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.widget.CandidateInfo; import com.android.settingslib.widget.FooterPreference; @@ -48,7 +50,6 @@ import java.util.Set; /** Preference fragment used for switch screen resolution */ @SearchIndexable public class ScreenResolutionFragment extends RadioButtonPickerFragment { - private static final String TAG = "ScreenResolution"; private Resources mResources; @@ -60,6 +61,7 @@ public class ScreenResolutionFragment extends RadioButtonPickerFragment { private String[] mScreenResolutionSummaries; private IllustrationPreference mImagePreference; + private DensityRestorer mDensityRestorer; @Override public void onAttach(Context context) { @@ -74,6 +76,7 @@ public class ScreenResolutionFragment extends RadioButtonPickerFragment { mResources.getStringArray(R.array.config_screen_resolution_summaries_strings); mResolutions = getAllSupportedResolution(); mImagePreference = new IllustrationPreference(context); + mDensityRestorer = new DensityRestorer(context); } @Override @@ -151,16 +154,21 @@ public class ScreenResolutionFragment extends RadioButtonPickerFragment { /** Using display manager to set the display mode. */ @VisibleForTesting - public void setDisplayMode(int width) { + public void setDisplayMode(final int width) { + if (width == getDisplayMode().getPhysicalWidth()) { + return; + } + + mDensityRestorer.startObserve(); mDefaultDisplay.setUserPreferredDisplayMode(getPreferMode(width)); } /** Get the key corresponding to the resolution. */ @VisibleForTesting String getKeyForResolution(int width) { - return width == FHD_WIDTH ? mScreenResolutionOptions[FHD_INDEX] - : width == QHD_WIDTH ? mScreenResolutionOptions[QHD_INDEX] - : null; + return width == FHD_WIDTH + ? mScreenResolutionOptions[FHD_INDEX] + : width == QHD_WIDTH ? mScreenResolutionOptions[QHD_INDEX] : null; } @Override @@ -171,7 +179,7 @@ public class ScreenResolutionFragment extends RadioButtonPickerFragment { } @Override - protected boolean setDefaultKey(String key) { + protected boolean setDefaultKey(final String key) { if (mScreenResolutionOptions[FHD_INDEX].equals(key)) { setDisplayMode(FHD_WIDTH); @@ -236,10 +244,6 @@ public class ScreenResolutionFragment extends RadioButtonPickerFragment { public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = new BaseSearchIndexProvider(R.xml.screen_resolution_settings) { - - boolean mIsFHDSupport = false; - boolean mIsQHDSupport = false; - @Override protected boolean isPageSearchEnabled(Context context) { ScreenResolutionController mController = @@ -247,4 +251,76 @@ public class ScreenResolutionFragment extends RadioButtonPickerFragment { return mController.checkSupportedResolutions(); } }; + + private static final class DensityRestorer implements DisplayManager.DisplayListener { + private final @Nullable Context mContext; + private int mDefaultDensity; + private int mCurrentIndex; + + DensityRestorer(Context context) { + mContext = context; + } + + public void startObserve() { + if (mContext == null) { + return; + } + + final DisplayDensityUtils density = new DisplayDensityUtils(mContext); + final int currentIndex = density.getCurrentIndex(); + final int defaultDensity = density.getDefaultDensity(); + + if (density.getValues()[mCurrentIndex] == density.getDefaultDensity()) { + return; + } + + mDefaultDensity = defaultDensity; + mCurrentIndex = currentIndex; + final DisplayManager dm = mContext.getSystemService(DisplayManager.class); + dm.registerDisplayListener(this, null); + } + + public void stopObserve() { + if (mContext == null) { + return; + } + + final DisplayManager dm = mContext.getSystemService(DisplayManager.class); + dm.unregisterDisplayListener(this); + } + + @Override + public void onDisplayAdded(int displayId) {} + + @Override + public void onDisplayRemoved(int displayId) {} + + @Override + public void onDisplayChanged(int displayId) { + if (displayId != Display.DEFAULT_DISPLAY) { + return; + } + + restoreDensity(); + } + + private void restoreDensity() { + if (mContext == null) { + return; + } + + final DisplayDensityUtils density = new DisplayDensityUtils(mContext); + if (density.getDefaultDensity() == mDefaultDensity) { + return; + } + + if (density.getValues()[mCurrentIndex] != density.getDefaultDensity()) { + DisplayDensityUtils.setForcedDisplayDensity( + Display.DEFAULT_DISPLAY, density.getValues()[mCurrentIndex]); + } + + mDefaultDensity = density.getDefaultDensity(); + stopObserve(); + } + } } diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java index ecaf9ee8fc4..e6f0b31f384 100644 --- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java +++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java @@ -17,13 +17,16 @@ package com.android.settings.wifi.dpp; import android.app.settings.SettingsEnums; +import android.content.Context; import android.content.Intent; import android.net.Uri; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Bundle; +import android.os.UserManager; import android.provider.Settings; +import android.util.EventLog; import android.util.Log; import androidx.annotation.VisibleForTesting; @@ -116,6 +119,13 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements @Override protected void handleIntent(Intent intent) { + if (isGuestUser(getApplicationContext())) { + Log.e(TAG, "Guest user is not allowed to configure Wi-Fi!"); + EventLog.writeEvent(0x534e4554, "224772890", -1 /* UID */, "User is a guest"); + finish(); + return; + } + String action = intent != null ? intent.getAction() : null; if (action == null) { finish(); @@ -185,7 +195,8 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements } } - private void showQrCodeScannerFragment() { + @VisibleForTesting + void showQrCodeScannerFragment() { WifiDppQrCodeScannerFragment fragment = (WifiDppQrCodeScannerFragment) mFragmentManager.findFragmentByTag( WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER); @@ -384,4 +395,11 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements return null; } + + 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/slice/WifiSlice.java b/src/com/android/settings/wifi/slice/WifiSlice.java index 76dfab8491b..2e5524e5b45 100644 --- a/src/com/android/settings/wifi/slice/WifiSlice.java +++ b/src/com/android/settings/wifi/slice/WifiSlice.java @@ -34,7 +34,9 @@ import android.net.Uri; import android.net.wifi.WifiManager; import android.os.Binder; import android.os.Bundle; +import android.os.UserManager; import android.text.TextUtils; +import android.util.EventLog; import android.util.Log; import androidx.annotation.Nullable; @@ -96,10 +98,18 @@ public class WifiSlice implements CustomSliceable { @Override public Slice getSlice() { + final boolean isWifiEnabled = isWifiEnabled(); + // If user is a guest just return a slice without a toggle. + if (isGuestUser(mContext)) { + Log.e(TAG, "Guest user is not allowed to configure Wi-Fi!"); + EventLog.writeEvent(0x534e4554, "232798363", -1 /* UID */, "User is a guest"); + return getListBuilder(isWifiEnabled, null /* wifiSliceItem */, + false /* isWiFiPermissionGranted */).build(); + } + // If external calling package doesn't have Wi-Fi permission. final boolean isPermissionGranted = Utils.isSettingsIntelligence(mContext) || isPermissionGranted(mContext); - final boolean isWifiEnabled = isWifiEnabled(); ListBuilder listBuilder = getListBuilder(isWifiEnabled, null /* wifiSliceItem */, isPermissionGranted); // If the caller doesn't have the permission granted, just return a slice without a toggle. @@ -139,6 +149,13 @@ public class WifiSlice implements CustomSliceable { return listBuilder.build(); } + protected 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(); + } + private static boolean isPermissionGranted(Context settingsContext) { final int callingUid = Binder.getCallingUid(); final String callingPackage = settingsContext.getPackageManager() diff --git a/tests/robotests/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/robotests/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java index 0c9bf37cabb..d8605ded829 100644 --- a/tests/robotests/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java +++ b/tests/robotests/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java @@ -16,16 +16,78 @@ package com.android.settings.wifi.dpp; +import static org.mockito.Mockito.doNothing; +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.content.Context; +import android.content.Intent; +import android.os.UserManager; + +import androidx.test.core.app.ApplicationProvider; + +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.Robolectric; import org.robolectric.RobolectricTestRunner; @RunWith(RobolectricTestRunner.class) public class WifiDppConfiguratorActivityTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Spy + Context mContext = ApplicationProvider.getApplicationContext(); + @Mock + UserManager mUserManager; + + WifiDppConfiguratorActivity mActivity; + Intent mIntent; + + @Before + public void setUp() { + when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); + when(mUserManager.isGuestUser()).thenReturn(false); + + mIntent = new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_SCANNER); + mIntent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest"); + mIntent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WPA"); + mIntent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "\\012345678,"); + + mActivity = spy(Robolectric.setupActivity(WifiDppConfiguratorActivity.class)); + when(mActivity.getApplicationContext()).thenReturn(mContext); + } + @Test public void launchActivity_noIntentAction_shouldNotFatalException() { WifiDppConfiguratorActivity wifiDppConfiguratorActivity = Robolectric.setupActivity(WifiDppConfiguratorActivity.class); } + + @Test + public void handleIntent_isGuestUser_shouldFinish() { + when(mUserManager.isGuestUser()).thenReturn(true); + + mActivity.handleIntent(mIntent); + + verify(mActivity).finish(); + } + + @Test + public void handleIntent_notGuestUser_shouldNotFinish() { + when(mUserManager.isGuestUser()).thenReturn(false); + doNothing().when(mActivity).showQrCodeScannerFragment(); + + mActivity.handleIntent(mIntent); + + verify(mActivity, never()).finish(); + } } diff --git a/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java b/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java index 8e42fcd225a..33302ce8dc7 100644 --- a/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java +++ b/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java @@ -33,6 +33,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.net.wifi.WifiManager; +import android.os.UserManager; import androidx.slice.Slice; import androidx.slice.SliceItem; @@ -84,6 +85,8 @@ public class WifiSliceTest { @Spy Context mContext = ApplicationProvider.getApplicationContext(); @Mock + private UserManager mUserManager; + @Mock private WifiManager mWifiManager; @Mock private PackageManager mPackageManager; @@ -98,6 +101,8 @@ public class WifiSliceTest { @Before public void setUp() { doReturn(mResolver).when(mContext).getContentResolver(); + doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); + doReturn(false).when(mUserManager).isGuestUser(); doReturn(mWifiManager).when(mContext).getSystemService(WifiManager.class); doReturn(WifiManager.WIFI_STATE_ENABLED).when(mWifiManager).getWifiState(); when(mContext.getPackageManager()).thenReturn(mPackageManager); @@ -113,6 +118,33 @@ public class WifiSliceTest { mWifiSlice = new WifiSlice(mContext, mWifiRestriction); } + @Test + public void getWifiSlice_isGuestUser_shouldReturnNoToggle() { + doReturn(true).when(mUserManager).isGuestUser(); + + final Slice wifiSlice = mWifiSlice.getSlice(); + final SliceMetadata metadata = SliceMetadata.from(mContext, wifiSlice); + final List toggles = metadata.getToggles(); + assertThat(toggles).hasSize(0); + + final int rows = SliceQuery.findAll(wifiSlice, FORMAT_SLICE, HINT_LIST_ITEM, + null /* nonHints */).size(); + // Title row + assertThat(rows).isEqualTo(1); + } + + @Test + public void getWifiSlice_isNotGuestUser_shouldHaveTitleAndToggle() { + doReturn(false).when(mUserManager).isGuestUser(); + + final Slice wifiSlice = mWifiSlice.getSlice(); + assertThat(wifiSlice).isNotNull(); + + final SliceMetadata metadata = SliceMetadata.from(mContext, wifiSlice); + final List toggles = metadata.getToggles(); + assertThat(toggles).hasSize(1); + } + @Test public void getWifiSlice_fromSIPackage_shouldHaveTitleAndToggle() { when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{mSIPackageName});