Snap for 12190349 from b1f8213735 to 24Q4-release
Change-Id: I5eb31f535e81bdbacdb1a3a6915bafbb7a48d0bb
This commit is contained in:
@@ -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 {
|
flag {
|
||||||
name: "remove_qs_tooltip_in_suw"
|
name: "remove_qs_tooltip_in_suw"
|
||||||
namespace: "accessibility"
|
namespace: "accessibility"
|
||||||
|
|||||||
@@ -40,4 +40,6 @@
|
|||||||
<!-- PointerIcon Settings -->
|
<!-- PointerIcon Settings -->
|
||||||
<integer name="pointer_scale_seek_bar_start">0</integer>
|
<integer name="pointer_scale_seek_bar_start">0</integer>
|
||||||
<integer name="pointer_scale_seek_bar_end">3</integer>
|
<integer name="pointer_scale_seek_bar_end">3</integer>
|
||||||
|
|
||||||
|
<integer name="max_integer">2147483647</integer>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
android:summary="@string/daltonizer_mode_deuteranomaly_summary"
|
android:summary="@string/daltonizer_mode_deuteranomaly_summary"
|
||||||
android:title="@string/daltonizer_mode_deuteranomaly_title"
|
android:title="@string/daltonizer_mode_deuteranomaly_title"
|
||||||
|
settings:titleMaxLines="@integer/max_integer"
|
||||||
settings:controller="com.android.settings.accessibility.DaltonizerRadioButtonPreferenceController" />
|
settings:controller="com.android.settings.accessibility.DaltonizerRadioButtonPreferenceController" />
|
||||||
|
|
||||||
<com.android.settingslib.widget.SelectorWithWidgetPreference
|
<com.android.settingslib.widget.SelectorWithWidgetPreference
|
||||||
@@ -40,6 +41,7 @@
|
|||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
android:summary="@string/daltonizer_mode_protanomaly_summary"
|
android:summary="@string/daltonizer_mode_protanomaly_summary"
|
||||||
android:title="@string/daltonizer_mode_protanomaly_title"
|
android:title="@string/daltonizer_mode_protanomaly_title"
|
||||||
|
settings:titleMaxLines="@integer/max_integer"
|
||||||
settings:controller="com.android.settings.accessibility.DaltonizerRadioButtonPreferenceController" />
|
settings:controller="com.android.settings.accessibility.DaltonizerRadioButtonPreferenceController" />
|
||||||
|
|
||||||
<com.android.settingslib.widget.SelectorWithWidgetPreference
|
<com.android.settingslib.widget.SelectorWithWidgetPreference
|
||||||
@@ -47,12 +49,14 @@
|
|||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
android:summary="@string/daltonizer_mode_tritanomaly_summary"
|
android:summary="@string/daltonizer_mode_tritanomaly_summary"
|
||||||
android:title="@string/daltonizer_mode_tritanomaly_title"
|
android:title="@string/daltonizer_mode_tritanomaly_title"
|
||||||
|
settings:titleMaxLines="@integer/max_integer"
|
||||||
settings:controller="com.android.settings.accessibility.DaltonizerRadioButtonPreferenceController" />
|
settings:controller="com.android.settings.accessibility.DaltonizerRadioButtonPreferenceController" />
|
||||||
|
|
||||||
<com.android.settingslib.widget.SelectorWithWidgetPreference
|
<com.android.settingslib.widget.SelectorWithWidgetPreference
|
||||||
android:key="daltonizer_mode_grayscale"
|
android:key="daltonizer_mode_grayscale"
|
||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
android:title="@string/daltonizer_mode_grayscale_title"
|
android:title="@string/daltonizer_mode_grayscale_title"
|
||||||
|
settings:titleMaxLines="@integer/max_integer"
|
||||||
settings:controller="com.android.settings.accessibility.DaltonizerRadioButtonPreferenceController" />
|
settings:controller="com.android.settings.accessibility.DaltonizerRadioButtonPreferenceController" />
|
||||||
|
|
||||||
<com.android.settings.widget.SeekBarPreference
|
<com.android.settings.widget.SeekBarPreference
|
||||||
|
|||||||
@@ -202,10 +202,12 @@
|
|||||||
android:title="@string/call_category"
|
android:title="@string/call_category"
|
||||||
settings:controller="com.android.settings.network.telephony.CallingPreferenceCategoryController">
|
settings:controller="com.android.settings.network.telephony.CallingPreferenceCategoryController">
|
||||||
|
|
||||||
|
<!-- Settings search is handled by WifiCallingSearchItem. -->
|
||||||
<Preference
|
<Preference
|
||||||
android:key="wifi_calling"
|
android:key="wifi_calling"
|
||||||
android:title="@string/wifi_calling_settings_title"
|
android:title="@string/wifi_calling_settings_title"
|
||||||
android:summary="@string/wifi_calling_summary"
|
android:summary="@string/wifi_calling_summary"
|
||||||
|
settings:searchable="false"
|
||||||
settings:controller="com.android.settings.network.telephony.WifiCallingPreferenceController">
|
settings:controller="com.android.settings.network.telephony.WifiCallingPreferenceController">
|
||||||
<intent android:action="android.intent.action.MAIN"
|
<intent android:action="android.intent.action.MAIN"
|
||||||
android:targetPackage="com.android.settings"
|
android:targetPackage="com.android.settings"
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import android.net.Uri;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.VibrationAttributes;
|
import android.os.VibrationAttributes;
|
||||||
import android.os.Vibrator;
|
import android.os.Vibrator;
|
||||||
import android.os.vibrator.Flags;
|
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -110,8 +109,7 @@ public class KeyboardVibrationTogglePreferenceController extends TogglePreferenc
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAvailabilityStatus() {
|
public int getAvailabilityStatus() {
|
||||||
if (Flags.keyboardCategoryEnabled()
|
if (mContext.getResources().getBoolean(
|
||||||
&& mContext.getResources().getBoolean(
|
|
||||||
com.android.internal.R.bool.config_keyboardVibrationSettingsSupported)) {
|
com.android.internal.R.bool.config_keyboardVibrationSettingsSupported)) {
|
||||||
return AVAILABLE;
|
return AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,13 @@ public class RestrictedPreferenceHelper {
|
|||||||
AccessibilityActivityPreference preference = new AccessibilityActivityPreference(
|
AccessibilityActivityPreference preference = new AccessibilityActivityPreference(
|
||||||
mContext, componentName.getPackageName(), activityInfo.applicationInfo.uid,
|
mContext, componentName.getPackageName(), activityInfo.applicationInfo.uid,
|
||||||
info);
|
info);
|
||||||
|
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);
|
setRestrictedPreferenceEnabled(preference, permittedServices, serviceEnabled);
|
||||||
|
}
|
||||||
preferenceList.add(preference);
|
preferenceList.add(preference);
|
||||||
}
|
}
|
||||||
return preferenceList;
|
return preferenceList;
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
|
|||||||
* Helper to get the list of connectable and special profiles.
|
* Helper to get the list of connectable and special profiles.
|
||||||
*/
|
*/
|
||||||
private List<LocalBluetoothProfile> getProfiles() {
|
private List<LocalBluetoothProfile> getProfiles() {
|
||||||
List<LocalBluetoothProfile> result = new ArrayList<LocalBluetoothProfile>();
|
List<LocalBluetoothProfile> result = new ArrayList<>();
|
||||||
mProfileDeviceMap.clear();
|
mProfileDeviceMap.clear();
|
||||||
if (mAllOfCachedDevices == null || mAllOfCachedDevices.isEmpty()) {
|
if (mAllOfCachedDevices == null || mAllOfCachedDevices.isEmpty()) {
|
||||||
return result;
|
return result;
|
||||||
@@ -319,8 +319,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
|
|||||||
if (mProfileDeviceMap.containsKey(profile.toString())) {
|
if (mProfileDeviceMap.containsKey(profile.toString())) {
|
||||||
mProfileDeviceMap.get(profile.toString()).add(cachedItem);
|
mProfileDeviceMap.get(profile.toString()).add(cachedItem);
|
||||||
} else {
|
} else {
|
||||||
List<CachedBluetoothDevice> tmpCachedDeviceList =
|
List<CachedBluetoothDevice> tmpCachedDeviceList = new ArrayList<>();
|
||||||
new ArrayList<CachedBluetoothDevice>();
|
|
||||||
tmpCachedDeviceList.add(cachedItem);
|
tmpCachedDeviceList.add(cachedItem);
|
||||||
mProfileDeviceMap.put(profile.toString(), tmpCachedDeviceList);
|
mProfileDeviceMap.put(profile.toString(), tmpCachedDeviceList);
|
||||||
result.add(profile);
|
result.add(profile);
|
||||||
@@ -356,6 +355,10 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
|
|||||||
}
|
}
|
||||||
boolean hearingAidSupported = result.contains(
|
boolean hearingAidSupported = result.contains(
|
||||||
mManager.getProfileManager().getHearingAidProfile());
|
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) {
|
if (leAudioSupported && !classicAudioSupported && !hearingAidSupported) {
|
||||||
mIsLeAudioOnlyDevice = true;
|
mIsLeAudioOnlyDevice = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -263,6 +263,16 @@ public abstract class BasePreferenceController extends AbstractPreferenceControl
|
|||||||
|| availabilityStatus == DISABLED_DEPENDENT_SETTING);
|
|| 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
|
* @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
|
* 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
|
* Called by SearchIndexProvider#getNonIndexableKeys
|
||||||
*/
|
*/
|
||||||
public void updateNonIndexableKeys(List<String> keys) {
|
public void updateNonIndexableKeys(List<String> keys) {
|
||||||
final boolean shouldSuppressFromSearch = !isAvailable()
|
|
||||||
|| getAvailabilityStatus() == AVAILABLE_UNSEARCHABLE;
|
|
||||||
if (shouldSuppressFromSearch) {
|
|
||||||
final String key = getPreferenceKey();
|
final String key = getPreferenceKey();
|
||||||
if (TextUtils.isEmpty(key)) {
|
if (TextUtils.isEmpty(key)) {
|
||||||
Log.w(TAG, "Skipping updateNonIndexableKeys due to empty key " + toString());
|
Log.w(TAG, "Skipping updateNonIndexableKeys due to empty key " + this);
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (keys.contains(key)) {
|
|
||||||
Log.w(TAG, "Skipping updateNonIndexableKeys, key already in list. " + toString());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!keys.contains(key) && !isAvailableForSearch()) {
|
||||||
keys.add(key);
|
keys.add(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import android.database.ContentObserver;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.os.UserManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.telephony.SubscriptionInfo;
|
import android.telephony.SubscriptionInfo;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
@@ -79,19 +80,24 @@ public class MobileDataSlice implements CustomSliceable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Slice getSlice() {
|
public Slice getSlice() {
|
||||||
|
ListBuilder listBuilder = createListBuilder();
|
||||||
|
if (!isConfigMobileNetworksAllowed()) {
|
||||||
|
return listBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
final IconCompat icon = IconCompat.createWithResource(mContext,
|
final IconCompat icon = IconCompat.createWithResource(mContext,
|
||||||
R.drawable.ic_network_cell);
|
R.drawable.ic_network_cell);
|
||||||
final String title = mContext.getText(R.string.mobile_data_settings_title).toString();
|
final String title = mContext.getText(R.string.mobile_data_settings_title).toString();
|
||||||
@ColorInt final int color = Utils.getColorAccentDefaultColor(mContext);
|
@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()) {
|
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()) {
|
if (!isMobileDataAvailable()) {
|
||||||
return null;
|
return listBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
final CharSequence summary = getSummary();
|
final CharSequence summary = getSummary();
|
||||||
@@ -109,11 +115,15 @@ public class MobileDataSlice implements CustomSliceable {
|
|||||||
rowBuilder.setSubtitle(summary);
|
rowBuilder.setSubtitle(summary);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ListBuilder listBuilder = new ListBuilder(mContext, getUri(),
|
return listBuilder
|
||||||
ListBuilder.INFINITY)
|
|
||||||
.setAccentColor(color)
|
.setAccentColor(color)
|
||||||
.addRow(rowBuilder);
|
.addRow(rowBuilder)
|
||||||
return listBuilder.build();
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
ListBuilder createListBuilder() {
|
||||||
|
return new ListBuilder(mContext, getUri(), ListBuilder.INFINITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -211,6 +221,19 @@ public class MobileDataSlice implements CustomSliceable {
|
|||||||
return mTelephonyManager.isDataEnabled();
|
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.
|
* Listener for mobile data state changes.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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.MmsMessagePreferenceController.Companion.MmsMessageSearchItem
|
||||||
import com.android.settings.network.telephony.NrAdvancedCallingPreferenceController.Companion.NrAdvancedCallingSearchItem
|
import com.android.settings.network.telephony.NrAdvancedCallingPreferenceController.Companion.NrAdvancedCallingSearchItem
|
||||||
import com.android.settings.network.telephony.RoamingPreferenceController.Companion.RoamingSearchItem
|
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.BundleValue
|
||||||
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingFragment
|
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingFragment
|
||||||
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
|
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
|
||||||
@@ -112,9 +113,10 @@ class MobileNetworkSettingsSearchIndex(
|
|||||||
|
|
||||||
fun createSearchItems(context: Context): List<MobileNetworkSettingsSearchItem> =
|
fun createSearchItems(context: Context): List<MobileNetworkSettingsSearchItem> =
|
||||||
listOf(
|
listOf(
|
||||||
RoamingSearchItem(context),
|
|
||||||
MmsMessageSearchItem(context),
|
MmsMessageSearchItem(context),
|
||||||
NrAdvancedCallingSearchItem(context),
|
NrAdvancedCallingSearchItem(context),
|
||||||
|
RoamingSearchItem(context),
|
||||||
|
WifiCallingSearchItem(context),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,14 +22,17 @@ import android.telecom.TelecomManager
|
|||||||
import android.telephony.SubscriptionManager
|
import android.telephony.SubscriptionManager
|
||||||
import android.telephony.TelephonyManager
|
import android.telephony.TelephonyManager
|
||||||
import android.telephony.ims.ImsMmTelManager
|
import android.telephony.ims.ImsMmTelManager
|
||||||
import android.util.Log
|
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import com.android.settings.R
|
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.settings.network.telephony.wificalling.WifiCallingRepository
|
||||||
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
|
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,20 +47,21 @@ open class WifiCallingPreferenceController @JvmOverloads constructor(
|
|||||||
private val wifiCallingRepositoryFactory: (subId: Int) -> WifiCallingRepository = { subId ->
|
private val wifiCallingRepositoryFactory: (subId: Int) -> WifiCallingRepository = { subId ->
|
||||||
WifiCallingRepository(context, 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 preference: Preference
|
||||||
private lateinit var callingPreferenceCategoryController: CallingPreferenceCategoryController
|
private lateinit var callingPreferenceCategoryController: CallingPreferenceCategoryController
|
||||||
|
|
||||||
private val resourcesForSub by lazy {
|
private val resourcesForSub by lazy {
|
||||||
SubscriptionManager.getResourcesForSubId(mContext, mSubId)
|
SubscriptionManager.getResourcesForSubId(mContext, subId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun init(
|
fun init(
|
||||||
subId: Int,
|
subId: Int,
|
||||||
callingPreferenceCategoryController: CallingPreferenceCategoryController,
|
callingPreferenceCategoryController: CallingPreferenceCategoryController,
|
||||||
): WifiCallingPreferenceController {
|
): WifiCallingPreferenceController {
|
||||||
mSubId = subId
|
this.subId = subId
|
||||||
this.callingPreferenceCategoryController = callingPreferenceCategoryController
|
this.callingPreferenceCategoryController = callingPreferenceCategoryController
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@@ -65,39 +69,32 @@ open class WifiCallingPreferenceController @JvmOverloads constructor(
|
|||||||
/**
|
/**
|
||||||
* Note: Visibility also controlled by [onViewCreated].
|
* Note: Visibility also controlled by [onViewCreated].
|
||||||
*/
|
*/
|
||||||
override fun getAvailabilityStatus(subId: Int) =
|
override fun getAvailabilityStatus() =
|
||||||
if (SubscriptionManager.isValidSubscriptionId(subId)) AVAILABLE
|
if (SubscriptionManager.isValidSubscriptionId(subId)) AVAILABLE
|
||||||
else CONDITIONALLY_UNAVAILABLE
|
else CONDITIONALLY_UNAVAILABLE
|
||||||
|
|
||||||
override fun displayPreference(screen: PreferenceScreen) {
|
override fun displayPreference(screen: PreferenceScreen) {
|
||||||
// Not call super here, to avoid preference.isVisible changed unexpectedly
|
// Not call super here, to avoid preference.isVisible changed unexpectedly
|
||||||
preference = screen.findPreference(preferenceKey)!!
|
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) {
|
override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
|
||||||
if(mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID){
|
wifiCallingRepositoryFactory(subId).wifiCallingReadyFlow()
|
||||||
Log.e(
|
|
||||||
this.javaClass.simpleName,
|
|
||||||
"mSubId is INVALID_SUBSCRIPTION_ID"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
wifiCallingRepositoryFactory(mSubId).wifiCallingReadyFlow()
|
|
||||||
.collectLatestWithLifecycle(viewLifecycleOwner) { isReady ->
|
.collectLatestWithLifecycle(viewLifecycleOwner) { isReady ->
|
||||||
preference.isVisible = isReady
|
preference.isVisible = isReady
|
||||||
callingPreferenceCategoryController.updateChildVisible(preferenceKey, isReady)
|
callingPreferenceCategoryController.updateChildVisible(preferenceKey, isReady)
|
||||||
if (isReady) update()
|
if (isReady) update()
|
||||||
}
|
}
|
||||||
|
|
||||||
callStateRepository.callStateFlow(mSubId).collectLatestWithLifecycle(viewLifecycleOwner) {
|
callStateRepository.callStateFlow(subId).collectLatestWithLifecycle(viewLifecycleOwner) {
|
||||||
preference.isEnabled = (it == TelephonyManager.CALL_STATE_IDLE)
|
preference.isEnabled = (it == TelephonyManager.CALL_STATE_IDLE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun update() {
|
private suspend fun update() {
|
||||||
val simCallManager = mContext.getSystemService(TelecomManager::class.java)
|
val simCallManager = mContext.getSystemService(TelecomManager::class.java)
|
||||||
?.getSimCallManagerForSubscription(mSubId)
|
?.getSimCallManagerForSubscription(subId)
|
||||||
if (simCallManager != null) {
|
if (simCallManager != null) {
|
||||||
val intent = withContext(Dispatchers.Default) {
|
val intent = withContext(Dispatchers.Default) {
|
||||||
MobileNetworkUtils.buildPhoneAccountConfigureIntent(mContext, simCallManager)
|
MobileNetworkUtils.buildPhoneAccountConfigureIntent(mContext, simCallManager)
|
||||||
@@ -116,7 +113,7 @@ open class WifiCallingPreferenceController @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getSummaryForWfcMode(): String {
|
private fun getSummaryForWfcMode(): String {
|
||||||
val resId = when (wifiCallingRepositoryFactory(mSubId).getWiFiCallingMode()) {
|
val resId = when (wifiCallingRepositoryFactory(subId).getWiFiCallingMode()) {
|
||||||
ImsMmTelManager.WIFI_MODE_WIFI_ONLY ->
|
ImsMmTelManager.WIFI_MODE_WIFI_ONLY ->
|
||||||
com.android.internal.R.string.wfc_mode_wifi_only_summary
|
com.android.internal.R.string.wfc_mode_wifi_only_summary
|
||||||
|
|
||||||
@@ -130,4 +127,17 @@ open class WifiCallingPreferenceController @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
return resourcesForSub.getString(resId)
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -370,11 +370,18 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
mSwitchUserPref.setOnPreferenceClickListener(this);
|
mSwitchUserPref.setOnPreferenceClickListener(this);
|
||||||
}
|
}
|
||||||
|
if (android.multiuser.Flags.unicornModeRefactoringForHsumReadOnly()) {
|
||||||
|
if (isChangingAdminStatusRestricted()) {
|
||||||
|
removePreference(KEY_GRANT_ADMIN);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (mUserInfo.isMain() || mUserInfo.isGuest() || !UserManager.isMultipleAdminEnabled()
|
if (mUserInfo.isMain() || mUserInfo.isGuest() || !UserManager.isMultipleAdminEnabled()
|
||||||
|| mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_GRANT_ADMIN,
|
|| mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_GRANT_ADMIN,
|
||||||
mUserInfo.getUserHandle()) || !mUserManager.isAdminUser()) {
|
mUserInfo.getUserHandle()) || !mUserManager.isAdminUser()) {
|
||||||
removePreference(KEY_GRANT_ADMIN);
|
removePreference(KEY_GRANT_ADMIN);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!mUserManager.isAdminUser()) { // non admin users can't remove users and allow calls
|
if (!mUserManager.isAdminUser()) { // non admin users can't remove users and allow calls
|
||||||
removePreference(KEY_ENABLE_TELEPHONY);
|
removePreference(KEY_ENABLE_TELEPHONY);
|
||||||
removePreference(KEY_REMOVE_USER);
|
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 true so there will be no setup prompt dialog shown to the user anymore.
|
||||||
return isSecondaryUser(mUserInfo) && !mUserInfo.isInitialized();
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import android.app.settings.SettingsEnums;
|
|||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.os.vibrator.Flags;
|
|
||||||
import android.platform.test.flag.junit.SetFlagsRule;
|
import android.platform.test.flag.junit.SetFlagsRule;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
@@ -41,7 +40,6 @@ import androidx.preference.PreferenceScreen;
|
|||||||
import androidx.preference.SwitchPreference;
|
import androidx.preference.SwitchPreference;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -87,7 +85,6 @@ public class KeyboardVibrationTogglePreferenceControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getAvailabilityStatus_featureSupported_available() {
|
public void getAvailabilityStatus_featureSupported_available() {
|
||||||
mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED);
|
|
||||||
when(mResources.getBoolean(
|
when(mResources.getBoolean(
|
||||||
com.android.internal.R.bool.config_keyboardVibrationSettingsSupported))
|
com.android.internal.R.bool.config_keyboardVibrationSettingsSupported))
|
||||||
.thenReturn(true);
|
.thenReturn(true);
|
||||||
@@ -97,7 +94,6 @@ public class KeyboardVibrationTogglePreferenceControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getAvailabilityStatus_featureNotSupported_unavailable() {
|
public void getAvailabilityStatus_featureNotSupported_unavailable() {
|
||||||
mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED);
|
|
||||||
when(mResources.getBoolean(
|
when(mResources.getBoolean(
|
||||||
com.android.internal.R.bool.config_keyboardVibrationSettingsSupported))
|
com.android.internal.R.bool.config_keyboardVibrationSettingsSupported))
|
||||||
.thenReturn(false);
|
.thenReturn(false);
|
||||||
@@ -105,15 +101,6 @@ public class KeyboardVibrationTogglePreferenceControllerTest {
|
|||||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
|
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
|
@Test
|
||||||
public void updateState_mainVibrateDisabled_shouldReturnFalseForCheckedAndEnabled() {
|
public void updateState_mainVibrateDisabled_shouldReturnFalseForCheckedAndEnabled() {
|
||||||
|
|||||||
@@ -31,9 +31,8 @@ import android.content.pm.ActivityInfo;
|
|||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.platform.test.annotations.RequiresFlagsEnabled;
|
import android.platform.test.annotations.DisableFlags;
|
||||||
import android.platform.test.flag.junit.CheckFlagsRule;
|
import android.platform.test.annotations.EnableFlags;
|
||||||
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
|
|
||||||
import android.platform.test.flag.junit.SetFlagsRule;
|
import android.platform.test.flag.junit.SetFlagsRule;
|
||||||
|
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
@@ -83,8 +82,6 @@ public class RestrictedPreferenceHelperTest {
|
|||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||||
@Rule
|
|
||||||
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createAccessibilityServicePreferenceList_hasOneInfo_containsSameKey() {
|
public void createAccessibilityServicePreferenceList_hasOneInfo_containsSameKey() {
|
||||||
@@ -100,7 +97,7 @@ public class RestrictedPreferenceHelperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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})
|
android.permission.flags.Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED})
|
||||||
public void createAccessibilityServicePreferenceList_ecmRestricted_prefIsEcmRestricted() {
|
public void createAccessibilityServicePreferenceList_ecmRestricted_prefIsEcmRestricted() {
|
||||||
ShadowRestrictedLockUtilsInternal.setEcmRestrictedPkgs(
|
ShadowRestrictedLockUtilsInternal.setEcmRestrictedPkgs(
|
||||||
@@ -116,7 +113,7 @@ public class RestrictedPreferenceHelperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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})
|
android.permission.flags.Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED})
|
||||||
public void createAccessibilityServicePreferenceList_ecmNotRestricted_prefIsNotEcmRestricted() {
|
public void createAccessibilityServicePreferenceList_ecmNotRestricted_prefIsNotEcmRestricted() {
|
||||||
ShadowRestrictedLockUtilsInternal.setEcmRestrictedPkgs();
|
ShadowRestrictedLockUtilsInternal.setEcmRestrictedPkgs();
|
||||||
@@ -144,6 +141,40 @@ public class RestrictedPreferenceHelperTest {
|
|||||||
assertThat(preference.getKey()).isEqualTo(key);
|
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,
|
private AccessibilityServiceInfo getMockAccessibilityServiceInfo(String packageName,
|
||||||
String className) {
|
String className) {
|
||||||
final ApplicationInfo applicationInfo = new ApplicationInfo();
|
final ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import com.android.settings.testutils.shadow.ShadowBluetoothDevice;
|
|||||||
import com.android.settingslib.R;
|
import com.android.settingslib.R;
|
||||||
import com.android.settingslib.bluetooth.A2dpProfile;
|
import com.android.settingslib.bluetooth.A2dpProfile;
|
||||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||||
|
import com.android.settingslib.bluetooth.HearingAidProfile;
|
||||||
import com.android.settingslib.bluetooth.LeAudioProfile;
|
import com.android.settingslib.bluetooth.LeAudioProfile;
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
|
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
|
||||||
@@ -90,8 +91,12 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont
|
|||||||
@Mock
|
@Mock
|
||||||
private CachedBluetoothDeviceManager mCachedBluetoothDeviceManager;
|
private CachedBluetoothDeviceManager mCachedBluetoothDeviceManager;
|
||||||
|
|
||||||
private @Mock A2dpProfile mA2dpProfile;
|
@Mock
|
||||||
private @Mock LeAudioProfile mLeAudioProfile;
|
private A2dpProfile mA2dpProfile;
|
||||||
|
@Mock
|
||||||
|
private LeAudioProfile mLeAudioProfile;
|
||||||
|
@Mock
|
||||||
|
private HearingAidProfile mHearingAidProfile;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@@ -399,18 +404,23 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont
|
|||||||
when(mProfileManager.getProfileByName(eq(mA2dpProfile.toString())))
|
when(mProfileManager.getProfileByName(eq(mA2dpProfile.toString())))
|
||||||
.thenReturn(mA2dpProfile);
|
.thenReturn(mA2dpProfile);
|
||||||
when(mA2dpProfile.getNameResource(any()))
|
when(mA2dpProfile.getNameResource(any()))
|
||||||
.thenReturn(com.android.settingslib.R.string.bluetooth_profile_a2dp);
|
.thenReturn(R.string.bluetooth_profile_a2dp);
|
||||||
when(mA2dpProfile.getHighQualityAudioOptionLabel(any())).thenReturn(
|
when(mA2dpProfile.getHighQualityAudioOptionLabel(any())).thenReturn(
|
||||||
mContext.getString(com.android.settingslib.R
|
mContext.getString(R.string.bluetooth_profile_a2dp_high_quality_unknown_codec));
|
||||||
.string.bluetooth_profile_a2dp_high_quality_unknown_codec));
|
|
||||||
when(mA2dpProfile.isProfileReady()).thenReturn(true);
|
when(mA2dpProfile.isProfileReady()).thenReturn(true);
|
||||||
when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
|
when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
|
||||||
|
|
||||||
when(mLeAudioProfile.toString()).thenReturn("LE_AUDIO");
|
when(mLeAudioProfile.toString()).thenReturn("LE_AUDIO");
|
||||||
when(mLeAudioProfile.getNameResource(any()))
|
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(mLeAudioProfile.isProfileReady()).thenReturn(true);
|
||||||
when(mProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile);
|
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,
|
private void addA2dpProfileToDevice(boolean preferred, boolean supportsHighQualityAudio,
|
||||||
@@ -426,6 +436,11 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont
|
|||||||
mConnectableProfiles.add(mLeAudioProfile);
|
mConnectableProfiles.add(mLeAudioProfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addHearingAidProfileToDevice(boolean enabled) {
|
||||||
|
when(mHearingAidProfile.isEnabled(any())).thenReturn(enabled);
|
||||||
|
mConnectableProfiles.add(mHearingAidProfile);
|
||||||
|
}
|
||||||
|
|
||||||
private SwitchPreferenceCompat getHighQualityAudioPref() {
|
private SwitchPreferenceCompat getHighQualityAudioPref() {
|
||||||
return (SwitchPreferenceCompat) mScreen.findPreference(
|
return (SwitchPreferenceCompat) mScreen.findPreference(
|
||||||
BluetoothDetailsProfilesController.HIGH_QUALITY_AUDIO_PREF_TAG);
|
BluetoothDetailsProfilesController.HIGH_QUALITY_AUDIO_PREF_TAG);
|
||||||
@@ -591,4 +606,27 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont
|
|||||||
List<SwitchPreferenceCompat> switches = getProfileSwitches(false);
|
List<SwitchPreferenceCompat> switches = getProfileSwitches(false);
|
||||||
assertThat(switches.get(0).isVisible()).isFalse();
|
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)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,10 @@ package com.android.settings.network.telephony;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@@ -37,6 +39,7 @@ import androidx.core.graphics.drawable.IconCompat;
|
|||||||
import androidx.slice.Slice;
|
import androidx.slice.Slice;
|
||||||
import androidx.slice.SliceMetadata;
|
import androidx.slice.SliceMetadata;
|
||||||
import androidx.slice.SliceProvider;
|
import androidx.slice.SliceProvider;
|
||||||
|
import androidx.slice.builders.ListBuilder;
|
||||||
import androidx.slice.core.SliceAction;
|
import androidx.slice.core.SliceAction;
|
||||||
import androidx.slice.widget.SliceLiveData;
|
import androidx.slice.widget.SliceLiveData;
|
||||||
|
|
||||||
@@ -68,6 +71,7 @@ public class MobileDataSliceTest {
|
|||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private MobileDataSlice mMobileDataSlice;
|
private MobileDataSlice mMobileDataSlice;
|
||||||
|
private ListBuilder mListBuilder;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@@ -86,6 +90,8 @@ public class MobileDataSliceTest {
|
|||||||
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
|
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
|
||||||
|
|
||||||
mMobileDataSlice = spy(new MobileDataSlice(mContext));
|
mMobileDataSlice = spy(new MobileDataSlice(mContext));
|
||||||
|
mListBuilder = spy(mMobileDataSlice.createListBuilder());
|
||||||
|
doReturn(mListBuilder).when(mMobileDataSlice).createListBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -175,25 +181,41 @@ public class MobileDataSliceTest {
|
|||||||
@Test
|
@Test
|
||||||
public void isMobileDataAvailable_noSubscriptions_slicePrimaryActionIsEmpty() {
|
public void isMobileDataAvailable_noSubscriptions_slicePrimaryActionIsEmpty() {
|
||||||
when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(new ArrayList<>());
|
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
|
@Test
|
||||||
public void isMobileDataAvailable_nullSubscriptions_slicePrimaryActionIsEmpty() {
|
public void isMobileDataAvailable_nullSubscriptions_slicePrimaryActionIsEmpty() {
|
||||||
when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(null);
|
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
|
@Test
|
||||||
public void airplaneModeEnabled_slicePrimaryActionIsEmpty() {
|
public void airplaneModeEnabled_slicePrimaryActionIsEmpty() {
|
||||||
doReturn(true).when(mMobileDataSlice).isAirplaneModeEnabled();
|
doReturn(true).when(mMobileDataSlice).isAirplaneModeEnabled();
|
||||||
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -729,12 +729,25 @@ public class UserDetailsSettingsTest {
|
|||||||
public void initialize_restrictUserSelected_shouldNotShowGrantAdminPref_MultipleAdminEnabled() {
|
public void initialize_restrictUserSelected_shouldNotShowGrantAdminPref_MultipleAdminEnabled() {
|
||||||
setupSelectedUser();
|
setupSelectedUser();
|
||||||
ShadowUserManager.setIsMultipleAdminEnabled(true);
|
ShadowUserManager.setIsMultipleAdminEnabled(true);
|
||||||
|
// target user has DISALLOW_GRANT_ADMIN restriction
|
||||||
mUserManager.setUserRestriction(mUserInfo.getUserHandle(),
|
mUserManager.setUserRestriction(mUserInfo.getUserHandle(),
|
||||||
UserManager.DISALLOW_GRANT_ADMIN, true);
|
UserManager.DISALLOW_GRANT_ADMIN, true);
|
||||||
mFragment.initialize(mActivity, mArguments);
|
mFragment.initialize(mActivity, mArguments);
|
||||||
verify(mFragment).removePreference(KEY_GRANT_ADMIN);
|
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
|
@Test
|
||||||
public void initialize_mainUserSelected_shouldShowGrantAdminPref_MultipleAdminEnabled() {
|
public void initialize_mainUserSelected_shouldShowGrantAdminPref_MultipleAdminEnabled() {
|
||||||
setupSelectedMainUser();
|
setupSelectedMainUser();
|
||||||
|
|||||||
Reference in New Issue
Block a user