diff --git a/src/com/android/settings/slices/RestrictedSliceUtils.java b/src/com/android/settings/slices/RestrictedSliceUtils.java new file mode 100644 index 00000000000..a5b5a146458 --- /dev/null +++ b/src/com/android/settings/slices/RestrictedSliceUtils.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2023 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.slices; + +import android.content.ContentResolver; +import android.net.Uri; +import android.provider.SettingsSlicesContract; + +/** + * A utility class to check slice Uris for restriction. + */ +public class RestrictedSliceUtils { + + /** + * Uri for the notifying open networks Slice. + */ + private static final Uri NOTIFY_OPEN_NETWORKS_SLICE_URI = new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(SettingsSliceProvider.SLICE_AUTHORITY) + .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) + .appendPath("notify_open_networks") + .build(); + + /** + * Uri for the auto turning on Wi-Fi Slice. + */ + private static final Uri AUTO_TURN_ON_WIFI_SLICE_URI = new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(SettingsSliceProvider.SLICE_AUTHORITY) + .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) + .appendPath("enable_wifi_wakeup") + .build(); + + /** + * Uri for the usb tethering Slice. + */ + private static final Uri USB_TETHERING_SLICE_URI = new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(SettingsSliceProvider.SLICE_AUTHORITY) + .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) + .appendPath("enable_usb_tethering") + .build(); + + /** + * Uri for the bluetooth tethering Slice. + */ + private static final Uri BLUETOOTH_TETHERING_SLICE_URI = new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(SettingsSliceProvider.SLICE_AUTHORITY) + .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) + .appendPath("enable_bluetooth_tethering_2") + .build(); + + /** + * Returns true if the slice Uri restricts access to guest user. + */ + public static boolean isGuestRestricted(Uri sliceUri) { + if (AUTO_TURN_ON_WIFI_SLICE_URI.equals(sliceUri) + || NOTIFY_OPEN_NETWORKS_SLICE_URI.equals(sliceUri) + || BLUETOOTH_TETHERING_SLICE_URI.equals(sliceUri) + || USB_TETHERING_SLICE_URI.equals(sliceUri) + || CustomSliceRegistry.MOBILE_DATA_SLICE_URI.equals(sliceUri)) { + return true; + } + return false; + } +} diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java index 12272a7523a..5d2bde31da0 100644 --- a/src/com/android/settings/slices/SettingsSliceProvider.java +++ b/src/com/android/settings/slices/SettingsSliceProvider.java @@ -30,6 +30,7 @@ import android.content.pm.PackageManager; import android.net.Uri; import android.os.Binder; import android.os.StrictMode; +import android.os.UserManager; import android.provider.Settings; import android.provider.SettingsSlicesContract; import android.text.TextUtils; @@ -233,6 +234,14 @@ public class SettingsSliceProvider extends SliceProvider { getContext().getTheme().rebase(); } + // Checking if some semi-sensitive slices are requested by a guest user. If so, will + // return an empty slice. + final UserManager userManager = getContext().getSystemService(UserManager.class); + if (userManager.isGuestUser() && RestrictedSliceUtils.isGuestRestricted(sliceUri)) { + Log.i(TAG, "Guest user access denied."); + return null; + } + // Before adding a slice to {@link CustomSliceManager}, please get approval // from the Settings team. if (CustomSliceRegistry.isValidUri(sliceUri)) { diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java index b7d249d36fe..4903a28ad53 100644 --- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java @@ -119,6 +119,7 @@ public class SettingsSliceProviderTest { private Context mContext; private SettingsSliceProvider mProvider; private ShadowPackageManager mPackageManager; + private ShadowUserManager mShadowUserManager; @Mock private SliceManager mManager; @@ -157,6 +158,7 @@ public class SettingsSliceProviderTest { when(mManager.getPinnedSlices()).thenReturn(Collections.emptyList()); mPackageManager = Shadows.shadowOf(mContext.getPackageManager()); + mShadowUserManager = ShadowUserManager.getShadow(); SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); } @@ -292,6 +294,37 @@ public class SettingsSliceProviderTest { assertThat(ShadowTheme.isThemeRebased()).isFalse(); } + @Test + public void onBindSlice_guestRestricted_returnsNull() { + final String key = "enable_usb_tethering"; + mShadowUserManager.setGuestUser(true); + final Uri testUri = new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(SettingsSliceProvider.SLICE_AUTHORITY) + .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) + .appendPath(key) + .build(); + + final Slice slice = mProvider.onBindSlice(testUri); + + assertThat(slice).isNull(); + } + + @Test + public void onBindSlice_notGuestRestricted_returnsNotNull() { + final String key = "enable_usb_tethering"; + final Uri testUri = new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(SettingsSliceProvider.SLICE_AUTHORITY) + .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) + .appendPath(key) + .build(); + + final Slice slice = mProvider.onBindSlice(testUri); + + assertThat(slice).isNotNull(); + } + @Test public void getDescendantUris_fullActionUri_returnsSelf() { final Collection descendants = mProvider.onGetSliceDescendants(ACTION_SLICE_URI); diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java index df38420f961..324a82964ae 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java @@ -55,6 +55,7 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager private int[] profileIdsForUser = new int[0]; private boolean mUserSwitchEnabled; private Bundle mDefaultGuestUserRestriction = new Bundle(); + private boolean mIsGuestUser = false; private @UserManager.UserSwitchabilityResult int mSwitchabilityStatus = UserManager.SWITCHABILITY_STATUS_OK; @@ -270,4 +271,13 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager mUserProfileInfos.get(i).flags |= UserInfo.FLAG_ADMIN; } } + + @Implementation + protected boolean isGuestUser() { + return mIsGuestUser; + } + + public void setGuestUser(boolean isGuestUser) { + mIsGuestUser = isGuestUser; + } }