Snap for 12190349 from b1f8213735 to 24Q4-release

Change-Id: I5eb31f535e81bdbacdb1a3a6915bafbb7a48d0bb
This commit is contained in:
Android Build Coastguard Worker
2024-08-06 23:21:49 +00:00
17 changed files with 272 additions and 81 deletions

View File

@@ -71,6 +71,16 @@ flag {
}
}
flag {
name: "never_restrict_accessibility_activity"
namespace: "accessibility"
description: "Stops possibly restricting AccessibilityActivityPreferences"
bug: "331990900"
metadata {
purpose: PURPOSE_BUGFIX
}
}
flag {
name: "remove_qs_tooltip_in_suw"
namespace: "accessibility"

View File

@@ -40,4 +40,6 @@
<!-- PointerIcon Settings -->
<integer name="pointer_scale_seek_bar_start">0</integer>
<integer name="pointer_scale_seek_bar_end">3</integer>
<integer name="max_integer">2147483647</integer>
</resources>

View File

@@ -33,6 +33,7 @@
android:persistent="false"
android:summary="@string/daltonizer_mode_deuteranomaly_summary"
android:title="@string/daltonizer_mode_deuteranomaly_title"
settings:titleMaxLines="@integer/max_integer"
settings:controller="com.android.settings.accessibility.DaltonizerRadioButtonPreferenceController" />
<com.android.settingslib.widget.SelectorWithWidgetPreference
@@ -40,6 +41,7 @@
android:persistent="false"
android:summary="@string/daltonizer_mode_protanomaly_summary"
android:title="@string/daltonizer_mode_protanomaly_title"
settings:titleMaxLines="@integer/max_integer"
settings:controller="com.android.settings.accessibility.DaltonizerRadioButtonPreferenceController" />
<com.android.settingslib.widget.SelectorWithWidgetPreference
@@ -47,12 +49,14 @@
android:persistent="false"
android:summary="@string/daltonizer_mode_tritanomaly_summary"
android:title="@string/daltonizer_mode_tritanomaly_title"
settings:titleMaxLines="@integer/max_integer"
settings:controller="com.android.settings.accessibility.DaltonizerRadioButtonPreferenceController" />
<com.android.settingslib.widget.SelectorWithWidgetPreference
android:key="daltonizer_mode_grayscale"
android:persistent="false"
android:title="@string/daltonizer_mode_grayscale_title"
settings:titleMaxLines="@integer/max_integer"
settings:controller="com.android.settings.accessibility.DaltonizerRadioButtonPreferenceController" />
<com.android.settings.widget.SeekBarPreference

View File

@@ -202,10 +202,12 @@
android:title="@string/call_category"
settings:controller="com.android.settings.network.telephony.CallingPreferenceCategoryController">
<!-- Settings search is handled by WifiCallingSearchItem. -->
<Preference
android:key="wifi_calling"
android:title="@string/wifi_calling_settings_title"
android:summary="@string/wifi_calling_summary"
settings:searchable="false"
settings:controller="com.android.settings.network.telephony.WifiCallingPreferenceController">
<intent android:action="android.intent.action.MAIN"
android:targetPackage="com.android.settings"

View File

@@ -29,7 +29,6 @@ import android.net.Uri;
import android.os.Handler;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.os.vibrator.Flags;
import android.provider.Settings;
import android.util.Log;
@@ -110,8 +109,7 @@ public class KeyboardVibrationTogglePreferenceController extends TogglePreferenc
@Override
public int getAvailabilityStatus() {
if (Flags.keyboardCategoryEnabled()
&& mContext.getResources().getBoolean(
if (mContext.getResources().getBoolean(
com.android.internal.R.bool.config_keyboardVibrationSettingsSupported)) {
return AVAILABLE;
}

View File

@@ -128,7 +128,13 @@ public class RestrictedPreferenceHelper {
AccessibilityActivityPreference preference = new AccessibilityActivityPreference(
mContext, componentName.getPackageName(), activityInfo.applicationInfo.uid,
info);
setRestrictedPreferenceEnabled(preference, permittedServices, serviceEnabled);
if (Flags.neverRestrictAccessibilityActivity()) {
// Accessibility Activities do not have elevated privileges so restricting
// them based on ECM or device admin does not give any value.
preference.setEnabled(true);
} else {
setRestrictedPreferenceEnabled(preference, permittedServices, serviceEnabled);
}
preferenceList.add(preference);
}
return preferenceList;

View File

@@ -308,7 +308,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
* Helper to get the list of connectable and special profiles.
*/
private List<LocalBluetoothProfile> getProfiles() {
List<LocalBluetoothProfile> result = new ArrayList<LocalBluetoothProfile>();
List<LocalBluetoothProfile> result = new ArrayList<>();
mProfileDeviceMap.clear();
if (mAllOfCachedDevices == null || mAllOfCachedDevices.isEmpty()) {
return result;
@@ -319,8 +319,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
if (mProfileDeviceMap.containsKey(profile.toString())) {
mProfileDeviceMap.get(profile.toString()).add(cachedItem);
} else {
List<CachedBluetoothDevice> tmpCachedDeviceList =
new ArrayList<CachedBluetoothDevice>();
List<CachedBluetoothDevice> tmpCachedDeviceList = new ArrayList<>();
tmpCachedDeviceList.add(cachedItem);
mProfileDeviceMap.put(profile.toString(), tmpCachedDeviceList);
result.add(profile);
@@ -356,6 +355,10 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
}
boolean hearingAidSupported = result.contains(
mManager.getProfileManager().getHearingAidProfile());
// Remove hearing aids toggle anyway since showing the toggle will confuse users
if (hearingAidSupported) {
result.remove(mManager.getProfileManager().getHearingAidProfile());
}
if (leAudioSupported && !classicAudioSupported && !hearingAidSupported) {
mIsLeAudioOnlyDevice = true;
}

View File

@@ -263,6 +263,16 @@ public abstract class BasePreferenceController extends AbstractPreferenceControl
|| availabilityStatus == DISABLED_DEPENDENT_SETTING);
}
private boolean isAvailableForSearch() {
if (mIsForWork && mWorkProfileUser == null) {
return false;
}
final int availabilityStatus = getAvailabilityStatus();
return (availabilityStatus == AVAILABLE
|| availabilityStatus == DISABLED_DEPENDENT_SETTING);
}
/**
* @return {@code false} if the setting is not applicable to the device. This covers both
* settings which were only introduced in future versions of android, or settings that have
@@ -303,18 +313,12 @@ public abstract class BasePreferenceController extends AbstractPreferenceControl
* Called by SearchIndexProvider#getNonIndexableKeys
*/
public void updateNonIndexableKeys(List<String> keys) {
final boolean shouldSuppressFromSearch = !isAvailable()
|| getAvailabilityStatus() == AVAILABLE_UNSEARCHABLE;
if (shouldSuppressFromSearch) {
final String key = getPreferenceKey();
if (TextUtils.isEmpty(key)) {
Log.w(TAG, "Skipping updateNonIndexableKeys due to empty key " + toString());
return;
}
if (keys.contains(key)) {
Log.w(TAG, "Skipping updateNonIndexableKeys, key already in list. " + toString());
return;
}
final String key = getPreferenceKey();
if (TextUtils.isEmpty(key)) {
Log.w(TAG, "Skipping updateNonIndexableKeys due to empty key " + this);
return;
}
if (!keys.contains(key) && !isAvailableForSearch()) {
keys.add(key);
}
}

View File

@@ -29,6 +29,7 @@ import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.UserManager;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -79,19 +80,24 @@ public class MobileDataSlice implements CustomSliceable {
@Override
public Slice getSlice() {
ListBuilder listBuilder = createListBuilder();
if (!isConfigMobileNetworksAllowed()) {
return listBuilder.build();
}
final IconCompat icon = IconCompat.createWithResource(mContext,
R.drawable.ic_network_cell);
final String title = mContext.getText(R.string.mobile_data_settings_title).toString();
@ColorInt final int color = Utils.getColorAccentDefaultColor(mContext);
// Return null until we can show a disabled-action Slice, blaming Airplane mode.
// Return empty slice until we can show a disabled-action Slice, blaming Airplane mode.
if (isAirplaneModeEnabled()) {
return null;
return listBuilder.build();
}
// Return null until we can show a disabled-action Slice.
// Return empty slice until we can show a disabled-action Slice.
if (!isMobileDataAvailable()) {
return null;
return listBuilder.build();
}
final CharSequence summary = getSummary();
@@ -109,11 +115,15 @@ public class MobileDataSlice implements CustomSliceable {
rowBuilder.setSubtitle(summary);
}
final ListBuilder listBuilder = new ListBuilder(mContext, getUri(),
ListBuilder.INFINITY)
return listBuilder
.setAccentColor(color)
.addRow(rowBuilder);
return listBuilder.build();
.addRow(rowBuilder)
.build();
}
@VisibleForTesting
ListBuilder createListBuilder() {
return new ListBuilder(mContext, getUri(), ListBuilder.INFINITY);
}
@Override
@@ -211,6 +221,19 @@ public class MobileDataSlice implements CustomSliceable {
return mTelephonyManager.isDataEnabled();
}
@VisibleForTesting
boolean isConfigMobileNetworksAllowed() {
if (mContext == null) return true;
UserManager userManager = mContext.getSystemService(UserManager.class);
if (userManager == null) return true;
boolean isAllowed = userManager.isAdminUser() && !userManager.hasUserRestriction(
UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
if (!isAllowed) {
Log.w(TAG, "The user is not allowed to configure Mobile Networks.");
}
return isAllowed;
}
/**
* Listener for mobile data state changes.
*

View File

@@ -24,6 +24,7 @@ import com.android.settings.network.SubscriptionUtil
import com.android.settings.network.telephony.MmsMessagePreferenceController.Companion.MmsMessageSearchItem
import com.android.settings.network.telephony.NrAdvancedCallingPreferenceController.Companion.NrAdvancedCallingSearchItem
import com.android.settings.network.telephony.RoamingPreferenceController.Companion.RoamingSearchItem
import com.android.settings.network.telephony.WifiCallingPreferenceController.Companion.WifiCallingSearchItem
import com.android.settings.spa.SpaSearchLanding.BundleValue
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingFragment
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
@@ -112,9 +113,10 @@ class MobileNetworkSettingsSearchIndex(
fun createSearchItems(context: Context): List<MobileNetworkSettingsSearchItem> =
listOf(
RoamingSearchItem(context),
MmsMessageSearchItem(context),
NrAdvancedCallingSearchItem(context),
RoamingSearchItem(context),
WifiCallingSearchItem(context),
)
}
}

View File

@@ -22,14 +22,17 @@ import android.telecom.TelecomManager
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
import android.telephony.ims.ImsMmTelManager
import android.util.Log
import androidx.lifecycle.LifecycleOwner
import androidx.preference.Preference
import androidx.preference.PreferenceScreen
import com.android.settings.R
import com.android.settings.core.BasePreferenceController
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
import com.android.settings.network.telephony.wificalling.WifiCallingRepository
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
/**
@@ -44,20 +47,21 @@ open class WifiCallingPreferenceController @JvmOverloads constructor(
private val wifiCallingRepositoryFactory: (subId: Int) -> WifiCallingRepository = { subId ->
WifiCallingRepository(context, subId)
},
) : TelephonyBasePreferenceController(context, key) {
) : BasePreferenceController(context, key) {
private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID
private lateinit var preference: Preference
private lateinit var callingPreferenceCategoryController: CallingPreferenceCategoryController
private val resourcesForSub by lazy {
SubscriptionManager.getResourcesForSubId(mContext, mSubId)
SubscriptionManager.getResourcesForSubId(mContext, subId)
}
fun init(
subId: Int,
callingPreferenceCategoryController: CallingPreferenceCategoryController,
): WifiCallingPreferenceController {
mSubId = subId
this.subId = subId
this.callingPreferenceCategoryController = callingPreferenceCategoryController
return this
}
@@ -65,39 +69,32 @@ open class WifiCallingPreferenceController @JvmOverloads constructor(
/**
* Note: Visibility also controlled by [onViewCreated].
*/
override fun getAvailabilityStatus(subId: Int) =
override fun getAvailabilityStatus() =
if (SubscriptionManager.isValidSubscriptionId(subId)) AVAILABLE
else CONDITIONALLY_UNAVAILABLE
override fun displayPreference(screen: PreferenceScreen) {
// Not call super here, to avoid preference.isVisible changed unexpectedly
preference = screen.findPreference(preferenceKey)!!
preference.intent?.putExtra(Settings.EXTRA_SUB_ID, mSubId)
preference.intent?.putExtra(Settings.EXTRA_SUB_ID, subId)
}
override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
if(mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID){
Log.e(
this.javaClass.simpleName,
"mSubId is INVALID_SUBSCRIPTION_ID"
)
return
}
wifiCallingRepositoryFactory(mSubId).wifiCallingReadyFlow()
wifiCallingRepositoryFactory(subId).wifiCallingReadyFlow()
.collectLatestWithLifecycle(viewLifecycleOwner) { isReady ->
preference.isVisible = isReady
callingPreferenceCategoryController.updateChildVisible(preferenceKey, isReady)
if (isReady) update()
}
callStateRepository.callStateFlow(mSubId).collectLatestWithLifecycle(viewLifecycleOwner) {
callStateRepository.callStateFlow(subId).collectLatestWithLifecycle(viewLifecycleOwner) {
preference.isEnabled = (it == TelephonyManager.CALL_STATE_IDLE)
}
}
private suspend fun update() {
val simCallManager = mContext.getSystemService(TelecomManager::class.java)
?.getSimCallManagerForSubscription(mSubId)
?.getSimCallManagerForSubscription(subId)
if (simCallManager != null) {
val intent = withContext(Dispatchers.Default) {
MobileNetworkUtils.buildPhoneAccountConfigureIntent(mContext, simCallManager)
@@ -116,7 +113,7 @@ open class WifiCallingPreferenceController @JvmOverloads constructor(
}
private fun getSummaryForWfcMode(): String {
val resId = when (wifiCallingRepositoryFactory(mSubId).getWiFiCallingMode()) {
val resId = when (wifiCallingRepositoryFactory(subId).getWiFiCallingMode()) {
ImsMmTelManager.WIFI_MODE_WIFI_ONLY ->
com.android.internal.R.string.wfc_mode_wifi_only_summary
@@ -130,4 +127,17 @@ open class WifiCallingPreferenceController @JvmOverloads constructor(
}
return resourcesForSub.getString(resId)
}
companion object {
class WifiCallingSearchItem(
private val context: Context,
) : MobileNetworkSettingsSearchItem {
override val key: String = "wifi_calling"
override val title: String = context.getString(R.string.wifi_calling_settings_title)
override fun isAvailable(subId: Int): Boolean = runBlocking {
WifiCallingRepository(context, subId).wifiCallingReadyFlow().first()
}
}
}
}

View File

@@ -370,11 +370,18 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
}
mSwitchUserPref.setOnPreferenceClickListener(this);
}
if (mUserInfo.isMain() || mUserInfo.isGuest() || !UserManager.isMultipleAdminEnabled()
|| mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_GRANT_ADMIN,
mUserInfo.getUserHandle()) || !mUserManager.isAdminUser()) {
removePreference(KEY_GRANT_ADMIN);
if (android.multiuser.Flags.unicornModeRefactoringForHsumReadOnly()) {
if (isChangingAdminStatusRestricted()) {
removePreference(KEY_GRANT_ADMIN);
}
} else {
if (mUserInfo.isMain() || mUserInfo.isGuest() || !UserManager.isMultipleAdminEnabled()
|| mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_GRANT_ADMIN,
mUserInfo.getUserHandle()) || !mUserManager.isAdminUser()) {
removePreference(KEY_GRANT_ADMIN);
}
}
if (!mUserManager.isAdminUser()) { // non admin users can't remove users and allow calls
removePreference(KEY_ENABLE_TELEPHONY);
removePreference(KEY_REMOVE_USER);
@@ -552,4 +559,33 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
// return true so there will be no setup prompt dialog shown to the user anymore.
return isSecondaryUser(mUserInfo) && !mUserInfo.isInitialized();
}
/**
* Determines if changing admin status is restricted.
*
* <p>Admin status change is restricted under the following conditions of current & target user.
*
* <ul>
* <li>The <b>current</b> user is NOT an admin user.</li>
* <li>OR multiple admin support is NOT enabled.</li>
* <li>OR the <b>current</b> user has DISALLOW_GRANT_ADMIN restriction applied</li>
*
* <li>OR the <b>target</b> user ('mUserInfo') is a main user OR a guest user.</li>
* <li>OR the <b>target</b> user ('mUserInfo') has DISALLOW_GRANT_ADMIN restriction.</li>
* </ul>
*
* @return true if changing admin status is restricted, false otherwise
*/
private boolean isChangingAdminStatusRestricted() {
boolean currentUserRestricted = !mUserManager.isAdminUser()
|| !UserManager.isMultipleAdminEnabled()
|| mUserManager.hasUserRestriction(UserManager.DISALLOW_GRANT_ADMIN);
boolean targetUserRestricted = mUserInfo.isMain()
|| mUserInfo.isGuest()
|| mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_GRANT_ADMIN,
mUserInfo.getUserHandle());
return currentUserRestricted || targetUserRestricted;
}
}

View File

@@ -33,7 +33,6 @@ import android.app.settings.SettingsEnums;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.os.vibrator.Flags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
@@ -41,7 +40,6 @@ import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
@@ -87,7 +85,6 @@ public class KeyboardVibrationTogglePreferenceControllerTest {
@Test
public void getAvailabilityStatus_featureSupported_available() {
mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED);
when(mResources.getBoolean(
com.android.internal.R.bool.config_keyboardVibrationSettingsSupported))
.thenReturn(true);
@@ -97,7 +94,6 @@ public class KeyboardVibrationTogglePreferenceControllerTest {
@Test
public void getAvailabilityStatus_featureNotSupported_unavailable() {
mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED);
when(mResources.getBoolean(
com.android.internal.R.bool.config_keyboardVibrationSettingsSupported))
.thenReturn(false);
@@ -105,15 +101,6 @@ public class KeyboardVibrationTogglePreferenceControllerTest {
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void getAvailabilityStatus_keyboardCategoryDisabled_unavailable() {
mSetFlagsRule.disableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED);
when(mResources.getBoolean(
com.android.internal.R.bool.config_keyboardVibrationSettingsSupported))
.thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void updateState_mainVibrateDisabled_shouldReturnFalseForCheckedAndEnabled() {

View File

@@ -31,9 +31,8 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.core.app.ApplicationProvider;
@@ -83,8 +82,6 @@ public class RestrictedPreferenceHelperTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@Test
public void createAccessibilityServicePreferenceList_hasOneInfo_containsSameKey() {
@@ -100,7 +97,7 @@ public class RestrictedPreferenceHelperTest {
}
@Test
@RequiresFlagsEnabled(value = {android.security.Flags.FLAG_EXTEND_ECM_TO_ALL_SETTINGS,
@EnableFlags(value = {android.security.Flags.FLAG_EXTEND_ECM_TO_ALL_SETTINGS,
android.permission.flags.Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED})
public void createAccessibilityServicePreferenceList_ecmRestricted_prefIsEcmRestricted() {
ShadowRestrictedLockUtilsInternal.setEcmRestrictedPkgs(
@@ -116,7 +113,7 @@ public class RestrictedPreferenceHelperTest {
}
@Test
@RequiresFlagsEnabled(value = {android.security.Flags.FLAG_EXTEND_ECM_TO_ALL_SETTINGS,
@EnableFlags(value = {android.security.Flags.FLAG_EXTEND_ECM_TO_ALL_SETTINGS,
android.permission.flags.Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED})
public void createAccessibilityServicePreferenceList_ecmNotRestricted_prefIsNotEcmRestricted() {
ShadowRestrictedLockUtilsInternal.setEcmRestrictedPkgs();
@@ -144,6 +141,40 @@ public class RestrictedPreferenceHelperTest {
assertThat(preference.getKey()).isEqualTo(key);
}
@Test
@EnableFlags(value = {android.security.Flags.FLAG_EXTEND_ECM_TO_ALL_SETTINGS,
android.permission.flags.Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED})
@DisableFlags(Flags.FLAG_NEVER_RESTRICT_ACCESSIBILITY_ACTIVITY)
public void createAccessibilityActivityPreference_ecmRestricted_prefIsEcmRestricted() {
setMockAccessibilityShortcutInfo(mShortcutInfo);
ShadowRestrictedLockUtilsInternal.setEcmRestrictedPkgs(PACKAGE_NAME);
final List<AccessibilityActivityPreference> preferenceList =
mHelper.createAccessibilityActivityPreferenceList(List.of(mShortcutInfo));
assertThat(preferenceList).hasSize(1);
final RestrictedPreference preference = preferenceList.get(0);
assertThat(preference.isDisabledByEcm()).isTrue();
}
@Test
@EnableFlags(value = {
android.security.Flags.FLAG_EXTEND_ECM_TO_ALL_SETTINGS,
android.permission.flags.Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED,
Flags.FLAG_NEVER_RESTRICT_ACCESSIBILITY_ACTIVITY,
})
public void createAccessibilityActivityPreference_ecmRestricted_prefIsNotEcmRestricted() {
setMockAccessibilityShortcutInfo(mShortcutInfo);
ShadowRestrictedLockUtilsInternal.setEcmRestrictedPkgs(PACKAGE_NAME);
final List<AccessibilityActivityPreference> preferenceList =
mHelper.createAccessibilityActivityPreferenceList(List.of(mShortcutInfo));
assertThat(preferenceList).hasSize(1);
final RestrictedPreference preference = preferenceList.get(0);
assertThat(preference.isDisabledByEcm()).isFalse();
}
private AccessibilityServiceInfo getMockAccessibilityServiceInfo(String packageName,
String className) {
final ApplicationInfo applicationInfo = new ApplicationInfo();

View File

@@ -44,6 +44,7 @@ import com.android.settings.testutils.shadow.ShadowBluetoothDevice;
import com.android.settingslib.R;
import com.android.settingslib.bluetooth.A2dpProfile;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.HearingAidProfile;
import com.android.settingslib.bluetooth.LeAudioProfile;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
@@ -90,8 +91,12 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont
@Mock
private CachedBluetoothDeviceManager mCachedBluetoothDeviceManager;
private @Mock A2dpProfile mA2dpProfile;
private @Mock LeAudioProfile mLeAudioProfile;
@Mock
private A2dpProfile mA2dpProfile;
@Mock
private LeAudioProfile mLeAudioProfile;
@Mock
private HearingAidProfile mHearingAidProfile;
@Override
public void setUp() {
@@ -399,18 +404,23 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont
when(mProfileManager.getProfileByName(eq(mA2dpProfile.toString())))
.thenReturn(mA2dpProfile);
when(mA2dpProfile.getNameResource(any()))
.thenReturn(com.android.settingslib.R.string.bluetooth_profile_a2dp);
.thenReturn(R.string.bluetooth_profile_a2dp);
when(mA2dpProfile.getHighQualityAudioOptionLabel(any())).thenReturn(
mContext.getString(com.android.settingslib.R
.string.bluetooth_profile_a2dp_high_quality_unknown_codec));
mContext.getString(R.string.bluetooth_profile_a2dp_high_quality_unknown_codec));
when(mA2dpProfile.isProfileReady()).thenReturn(true);
when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
when(mLeAudioProfile.toString()).thenReturn("LE_AUDIO");
when(mLeAudioProfile.getNameResource(any()))
.thenReturn(com.android.settingslib.R.string.bluetooth_profile_le_audio);
.thenReturn(R.string.bluetooth_profile_le_audio);
when(mLeAudioProfile.isProfileReady()).thenReturn(true);
when(mProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile);
when(mHearingAidProfile.toString()).thenReturn("HearingAid");
when(mHearingAidProfile.getNameResource(any()))
.thenReturn(R.string.bluetooth_profile_hearing_aid);
when(mHearingAidProfile.isProfileReady()).thenReturn(true);
when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
}
private void addA2dpProfileToDevice(boolean preferred, boolean supportsHighQualityAudio,
@@ -426,6 +436,11 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont
mConnectableProfiles.add(mLeAudioProfile);
}
private void addHearingAidProfileToDevice(boolean enabled) {
when(mHearingAidProfile.isEnabled(any())).thenReturn(enabled);
mConnectableProfiles.add(mHearingAidProfile);
}
private SwitchPreferenceCompat getHighQualityAudioPref() {
return (SwitchPreferenceCompat) mScreen.findPreference(
BluetoothDetailsProfilesController.HIGH_QUALITY_AUDIO_PREF_TAG);
@@ -591,4 +606,27 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont
List<SwitchPreferenceCompat> switches = getProfileSwitches(false);
assertThat(switches.get(0).isVisible()).isFalse();
}
@Test
public void ashaHearingAid_hideAshaToggle() {
setupDevice(makeDefaultDeviceConfig());
addHearingAidProfileToDevice(true);
showScreen(mController);
List<SwitchPreferenceCompat> switches = getProfileSwitches(false);
assertThat(switches.isEmpty()).isTrue();
}
@Test
public void ashaHearingAidWithLeAudio_showLeAudioToggle() {
setupDevice(makeDefaultDeviceConfig());
addHearingAidProfileToDevice(false);
addLeAudioProfileToDevice(true);
showScreen(mController);
List<SwitchPreferenceCompat> switches = getProfileSwitches(false);
assertThat(switches.getFirst().getTitle()).isEqualTo(
mContext.getString(mLeAudioProfile.getNameResource(mDevice)));
}
}

View File

@@ -19,8 +19,10 @@ package com.android.settings.network.telephony;
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.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -37,6 +39,7 @@ import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
import androidx.slice.SliceMetadata;
import androidx.slice.SliceProvider;
import androidx.slice.builders.ListBuilder;
import androidx.slice.core.SliceAction;
import androidx.slice.widget.SliceLiveData;
@@ -68,6 +71,7 @@ public class MobileDataSliceTest {
private Context mContext;
private MobileDataSlice mMobileDataSlice;
private ListBuilder mListBuilder;
@Before
public void setUp() {
@@ -86,6 +90,8 @@ public class MobileDataSliceTest {
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
mMobileDataSlice = spy(new MobileDataSlice(mContext));
mListBuilder = spy(mMobileDataSlice.createListBuilder());
doReturn(mListBuilder).when(mMobileDataSlice).createListBuilder();
}
@Test
@@ -175,25 +181,41 @@ public class MobileDataSliceTest {
@Test
public void isMobileDataAvailable_noSubscriptions_slicePrimaryActionIsEmpty() {
when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(new ArrayList<>());
final Slice mobileData = mMobileDataSlice.getSlice();
assertThat(mobileData).isNull();
Slice mobileData = mMobileDataSlice.getSlice();
assertThat(mobileData).isNotNull();
verify(mListBuilder, never()).addRow(any());
}
@Test
public void isMobileDataAvailable_nullSubscriptions_slicePrimaryActionIsEmpty() {
when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(null);
final Slice mobileData = mMobileDataSlice.getSlice();
assertThat(mobileData).isNull();
Slice mobileData = mMobileDataSlice.getSlice();
assertThat(mobileData).isNotNull();
verify(mListBuilder, never()).addRow(any());
}
@Test
public void airplaneModeEnabled_slicePrimaryActionIsEmpty() {
doReturn(true).when(mMobileDataSlice).isAirplaneModeEnabled();
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
final Slice mobileData = mMobileDataSlice.getSlice();
assertThat(mobileData).isNull();
Slice mobileData = mMobileDataSlice.getSlice();
assertThat(mobileData).isNotNull();
verify(mListBuilder, never()).addRow(any());
}
@Test
public void getSlice_disallowConfigMobileNetworks_slicePrimaryActionIsEmpty() {
doReturn(false).when(mMobileDataSlice).isConfigMobileNetworksAllowed();
Slice mobileData = mMobileDataSlice.getSlice();
assertThat(mobileData).isNotNull();
verify(mListBuilder, never()).addRow(any());
}
}

View File

@@ -729,12 +729,25 @@ public class UserDetailsSettingsTest {
public void initialize_restrictUserSelected_shouldNotShowGrantAdminPref_MultipleAdminEnabled() {
setupSelectedUser();
ShadowUserManager.setIsMultipleAdminEnabled(true);
// target user has DISALLOW_GRANT_ADMIN restriction
mUserManager.setUserRestriction(mUserInfo.getUserHandle(),
UserManager.DISALLOW_GRANT_ADMIN, true);
mFragment.initialize(mActivity, mArguments);
verify(mFragment).removePreference(KEY_GRANT_ADMIN);
}
@Test
@RequiresFlagsEnabled(Flags.FLAG_UNICORN_MODE_REFACTORING_FOR_HSUM_READ_ONLY)
public void initialize_currentUserRestrict_shouldNotShowGrantAdminPref_MultipleAdminEnabled() {
setupSelectedUser();
ShadowUserManager.setIsMultipleAdminEnabled(true);
// current user has DISALLOW_GRANT_ADMIN restriction
mUserManager.setUserRestriction(mContext.getUser(),
UserManager.DISALLOW_GRANT_ADMIN, true);
mFragment.initialize(mActivity, mArguments);
verify(mFragment).removePreference(KEY_GRANT_ADMIN);
}
@Test
public void initialize_mainUserSelected_shouldShowGrantAdminPref_MultipleAdminEnabled() {
setupSelectedMainUser();