Snap for 13235988 from 4bc471f61e
to 25Q2-release
Change-Id: Ifc3e397531aca70c7a40287ada0a08b0eb54bb60
This commit is contained in:
@@ -14360,6 +14360,16 @@ Data usage charges may apply.</string>
|
||||
<string name="supervision_web_content_filters_browser_block_explicit_sites_summary">No filter is perfect, but this should help hide sexually explicit sites</string>
|
||||
<!-- Title for web content filters browser category allow all sites option [CHAR LIMIT=60] -->
|
||||
<string name="supervision_web_content_filters_browser_allow_all_sites_title">Allow all sites</string>
|
||||
<!-- Title for web content filters search category [CHAR LIMIT=60] -->
|
||||
<string name="supervision_web_content_filters_search_title">Google Search</string>
|
||||
<!-- Title for web content filters search category filter on option [CHAR LIMIT=60] -->
|
||||
<string name="supervision_web_content_filters_search_filter_on_title">SafeSearch filtering ON</string>
|
||||
<!-- Summary for web content filters search category filter on option [CHAR LIMIT=None] -->
|
||||
<string name="supervision_web_content_filters_search_filter_on_summary">Helps filter out explicit images, text, and links from search results on this device</string>
|
||||
<!-- Title for web content filters search category filter off option [CHAR LIMIT=60] -->
|
||||
<string name="supervision_web_content_filters_search_filter_off_title">SafeSearch filtering OFF</string>
|
||||
<!-- Summary for web content filters search category filter off option [CHAR LIMIT=None] -->
|
||||
<string name="supervision_web_content_filters_search_filter_off_summary">Account settings may still filter or blur explicit results</string>
|
||||
<!-- Generic content description that is attached to the preview illustration at the top of an Accessibility feature toggle page. [CHAR LIMIT=NONE] -->
|
||||
<!-- Title for supervision PIN verification screen [CHAR LIMIT=60] -->
|
||||
<string name="supervision_full_screen_pin_verification_title">Enter supervision PIN</string>
|
||||
|
@@ -419,32 +419,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
|
||||
mContext,
|
||||
SettingsEnums.ACTION_BLUETOOTH_PROFILE_LE_AUDIO_OFF,
|
||||
isCurrentDeviceInOrByPassAllowList());
|
||||
|
||||
LocalBluetoothProfile asha = mProfileManager.getHearingAidProfile();
|
||||
LocalBluetoothProfile broadcastAssistant =
|
||||
mProfileManager.getLeAudioBroadcastAssistantProfile();
|
||||
|
||||
for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) {
|
||||
Log.d(TAG,
|
||||
"device:" + leAudioDevice.getDevice().getAnonymizedAddress()
|
||||
+ " disable LE profile");
|
||||
profile.setEnabled(leAudioDevice.getDevice(), false);
|
||||
if (asha != null) {
|
||||
asha.setEnabled(leAudioDevice.getDevice(), true);
|
||||
}
|
||||
if (broadcastAssistant != null) {
|
||||
Log.d(TAG,
|
||||
"device:" + leAudioDevice.getDevice().getAnonymizedAddress()
|
||||
+ " disable LE broadcast assistant profile");
|
||||
broadcastAssistant.setEnabled(leAudioDevice.getDevice(), false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!SystemProperties.getBoolean(ENABLE_DUAL_MODE_AUDIO, false)) {
|
||||
Log.i(TAG, "Enabling classic audio profiles because dual mode is disabled");
|
||||
enableProfileAfterUserDisablesLeAudio(mProfileManager.getA2dpProfile());
|
||||
enableProfileAfterUserDisablesLeAudio(mProfileManager.getHeadsetProfile());
|
||||
}
|
||||
Utils.setLeAudioEnabled(mManager, List.copyOf(mCachedDeviceGroup), false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -462,75 +437,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
|
||||
mContext,
|
||||
SettingsEnums.ACTION_BLUETOOTH_PROFILE_LE_AUDIO_ON,
|
||||
isCurrentDeviceInOrByPassAllowList());
|
||||
|
||||
if (!SystemProperties.getBoolean(ENABLE_DUAL_MODE_AUDIO, false)) {
|
||||
Log.i(TAG, "Disabling classic audio profiles because dual mode is disabled");
|
||||
disableProfileBeforeUserEnablesLeAudio(mProfileManager.getA2dpProfile());
|
||||
disableProfileBeforeUserEnablesLeAudio(mProfileManager.getHeadsetProfile());
|
||||
}
|
||||
LocalBluetoothProfile asha = mProfileManager.getHearingAidProfile();
|
||||
LocalBluetoothProfile broadcastAssistant =
|
||||
mProfileManager.getLeAudioBroadcastAssistantProfile();
|
||||
|
||||
for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) {
|
||||
Log.d(TAG,
|
||||
"device:" + leAudioDevice.getDevice().getAnonymizedAddress()
|
||||
+ " enable LE profile");
|
||||
profile.setEnabled(leAudioDevice.getDevice(), true);
|
||||
if (asha != null) {
|
||||
asha.setEnabled(leAudioDevice.getDevice(), false);
|
||||
}
|
||||
if (broadcastAssistant != null) {
|
||||
Log.d(TAG,
|
||||
"device:" + leAudioDevice.getDevice().getAnonymizedAddress()
|
||||
+ " enable LE broadcast assistant profile");
|
||||
broadcastAssistant.setEnabled(leAudioDevice.getDevice(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void disableProfileBeforeUserEnablesLeAudio(LocalBluetoothProfile profile) {
|
||||
if (profile != null && mProfileDeviceMap.get(profile.toString()) != null) {
|
||||
Log.d(TAG, "Disable " + profile.toString() + " before user enables LE");
|
||||
for (CachedBluetoothDevice profileDevice : mProfileDeviceMap.get(profile.toString())) {
|
||||
if (profile.isEnabled(profileDevice.getDevice())) {
|
||||
Log.d(TAG, "The " + profileDevice.getDevice().getAnonymizedAddress() + ":"
|
||||
+ profile.toString() + " set disable");
|
||||
profile.setEnabled(profileDevice.getDevice(), false);
|
||||
} else {
|
||||
Log.d(TAG, "The " + profileDevice.getDevice().getAnonymizedAddress() + ":"
|
||||
+ profile.toString() + " profile is disabled. Do nothing.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (profile == null) {
|
||||
Log.w(TAG, "profile is null");
|
||||
} else {
|
||||
Log.w(TAG, profile.toString() + " is not in " + mProfileDeviceMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void enableProfileAfterUserDisablesLeAudio(LocalBluetoothProfile profile) {
|
||||
if (profile != null && mProfileDeviceMap.get(profile.toString()) != null) {
|
||||
Log.d(TAG, "enable " + profile.toString() + "after user disables LE");
|
||||
for (CachedBluetoothDevice profileDevice : mProfileDeviceMap.get(profile.toString())) {
|
||||
if (!profile.isEnabled(profileDevice.getDevice())) {
|
||||
Log.d(TAG, "The " + profileDevice.getDevice().getAnonymizedAddress() + ":"
|
||||
+ profile.toString() + " set enable");
|
||||
profile.setEnabled(profileDevice.getDevice(), true);
|
||||
} else {
|
||||
Log.d(TAG, "The " + profileDevice.getDevice().getAnonymizedAddress() + ":"
|
||||
+ profile.toString() + " profile is enabled. Do nothing.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (profile == null) {
|
||||
Log.w(TAG, "profile is null");
|
||||
} else {
|
||||
Log.w(TAG, profile.toString() + " is not in " + mProfileDeviceMap);
|
||||
}
|
||||
}
|
||||
Utils.setLeAudioEnabled(mManager, List.copyOf(mCachedDeviceGroup), true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -55,9 +55,18 @@ public final class BluetoothKeyMissingReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
PowerManager powerManager = context.getSystemService(PowerManager.class);
|
||||
if (TextUtils.equals(action, BluetoothDevice.ACTION_KEY_MISSING)) {
|
||||
Log.d(TAG, "Receive ACTION_KEY_MISSING");
|
||||
if (device.getBondState() == BluetoothDevice.BOND_NONE) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"Device " + device.getAnonymizedAddress() + " is already unbonded, skip.");
|
||||
return;
|
||||
}
|
||||
Integer keyMissingCount = BluetoothUtils.getKeyMissingCount(device);
|
||||
if (keyMissingCount != null && keyMissingCount != 1) {
|
||||
Log.d(TAG, "Key missing count is " + keyMissingCount + ", skip.");
|
||||
|
@@ -28,6 +28,7 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
@@ -45,15 +46,20 @@ import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils.ErrorListener;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
import com.android.settingslib.bluetooth.HearingAidProfile;
|
||||
import com.android.settingslib.bluetooth.LeAudioProfile;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager.BluetoothManagerCallback;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -70,6 +76,7 @@ import java.util.stream.Collectors;
|
||||
public final class Utils {
|
||||
|
||||
private static final String TAG = "BluetoothUtils";
|
||||
private static final String ENABLE_DUAL_MODE_AUDIO = "persist.bluetooth.enable_dual_mode_audio";
|
||||
|
||||
static final boolean V = BluetoothUtils.V; // verbose logging
|
||||
static final boolean D = BluetoothUtils.D; // regular logging
|
||||
@@ -360,4 +367,119 @@ public final class Utils {
|
||||
dialog.show();
|
||||
return dialog;
|
||||
}
|
||||
|
||||
/** Enables/disables LE Audio profile for the device. */
|
||||
public static void setLeAudioEnabled(
|
||||
@NonNull LocalBluetoothManager manager,
|
||||
@NonNull CachedBluetoothDevice cachedDevice,
|
||||
boolean enable) {
|
||||
List<CachedBluetoothDevice> devices =
|
||||
List.copyOf(findAllCachedBluetoothDevicesByGroupId(manager, cachedDevice));
|
||||
setLeAudioEnabled(manager, devices, enable);
|
||||
}
|
||||
|
||||
/** Enables/disables LE Audio profile for the devices in the same csip group. */
|
||||
public static void setLeAudioEnabled(
|
||||
@NonNull LocalBluetoothManager manager,
|
||||
@NonNull List<CachedBluetoothDevice> devicesWithSameGroupId,
|
||||
boolean enable) {
|
||||
LocalBluetoothProfileManager profileManager = manager.getProfileManager();
|
||||
LeAudioProfile leAudioProfile = profileManager.getLeAudioProfile();
|
||||
List<CachedBluetoothDevice> leAudioDevices =
|
||||
getDevicesWithProfile(devicesWithSameGroupId, leAudioProfile);
|
||||
if (leAudioDevices.isEmpty()) {
|
||||
Log.i(TAG, "Fail to setLeAudioEnabled, no LE Audio profile found.");
|
||||
}
|
||||
boolean dualModeEnabled = SystemProperties.getBoolean(ENABLE_DUAL_MODE_AUDIO, false);
|
||||
|
||||
if (enable && !dualModeEnabled) {
|
||||
Log.i(TAG, "Disabling classic audio profiles because dual mode is disabled");
|
||||
setProfileEnabledWhenChangingLeAudio(
|
||||
devicesWithSameGroupId, profileManager.getA2dpProfile(), false);
|
||||
setProfileEnabledWhenChangingLeAudio(
|
||||
devicesWithSameGroupId, profileManager.getHeadsetProfile(), false);
|
||||
}
|
||||
|
||||
HearingAidProfile asha = profileManager.getHearingAidProfile();
|
||||
LocalBluetoothLeBroadcastAssistant broadcastAssistant =
|
||||
profileManager.getLeAudioBroadcastAssistantProfile();
|
||||
|
||||
for (CachedBluetoothDevice leAudioDevice : leAudioDevices) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"device:"
|
||||
+ leAudioDevice.getDevice().getAnonymizedAddress()
|
||||
+ " set LE profile enabled: "
|
||||
+ enable);
|
||||
leAudioProfile.setEnabled(leAudioDevice.getDevice(), enable);
|
||||
if (asha != null) {
|
||||
asha.setEnabled(leAudioDevice.getDevice(), !enable);
|
||||
}
|
||||
if (broadcastAssistant != null) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"device:"
|
||||
+ leAudioDevice.getDevice().getAnonymizedAddress()
|
||||
+ " enable LE broadcast assistant profile: "
|
||||
+ enable);
|
||||
broadcastAssistant.setEnabled(leAudioDevice.getDevice(), enable);
|
||||
}
|
||||
}
|
||||
|
||||
if (!enable && !dualModeEnabled) {
|
||||
Log.i(TAG, "Enabling classic audio profiles because dual mode is disabled");
|
||||
setProfileEnabledWhenChangingLeAudio(
|
||||
devicesWithSameGroupId, profileManager.getA2dpProfile(), true);
|
||||
setProfileEnabledWhenChangingLeAudio(
|
||||
devicesWithSameGroupId, profileManager.getHeadsetProfile(), true);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<CachedBluetoothDevice> getDevicesWithProfile(
|
||||
List<CachedBluetoothDevice> devices, LocalBluetoothProfile profile) {
|
||||
List<CachedBluetoothDevice> devicesWithProfile = new ArrayList<>();
|
||||
for (CachedBluetoothDevice device : devices) {
|
||||
for (LocalBluetoothProfile currentProfile : device.getProfiles()) {
|
||||
if (currentProfile.toString().equals(profile.toString())) {
|
||||
devicesWithProfile.add(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
return devicesWithProfile;
|
||||
}
|
||||
|
||||
private static void setProfileEnabledWhenChangingLeAudio(
|
||||
List<CachedBluetoothDevice> devices,
|
||||
@Nullable LocalBluetoothProfile profile,
|
||||
boolean enable) {
|
||||
if (profile == null) {
|
||||
Log.i(TAG, "profile is null");
|
||||
return;
|
||||
}
|
||||
List<CachedBluetoothDevice> deviceWithProfile = getDevicesWithProfile(devices, profile);
|
||||
Log.d(TAG, "Set " + profile + " enabled:" + enable + " when switching LE Audio");
|
||||
for (CachedBluetoothDevice profileDevice : deviceWithProfile) {
|
||||
if (profile.isEnabled(profileDevice.getDevice()) != enable) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"The "
|
||||
+ profileDevice.getDevice().getAnonymizedAddress()
|
||||
+ ":"
|
||||
+ profile
|
||||
+ " set to "
|
||||
+ enable);
|
||||
profile.setEnabled(profileDevice.getDevice(), enable);
|
||||
} else {
|
||||
Log.d(
|
||||
TAG,
|
||||
"The "
|
||||
+ profileDevice.getDevice().getAnonymizedAddress()
|
||||
+ ":"
|
||||
+ profile
|
||||
+ " profile is already "
|
||||
+ enable
|
||||
+ ". Do nothing.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -192,7 +192,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
Log.d(TAG, "Skip handleOnBroadcastReady, not in starting process");
|
||||
return;
|
||||
}
|
||||
handleOnBroadcastReady();
|
||||
handleOnBroadcastReady(metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -273,7 +273,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
+ mSinksInAdding);
|
||||
if (mSinksToWaitFor.contains(sink)) {
|
||||
mSinksToWaitFor.remove(sink);
|
||||
if (mSinksToWaitFor.isEmpty()) {
|
||||
if (mSinksToWaitFor.isEmpty() && mBroadcast != null) {
|
||||
// To avoid users advance to share then pair flow before the
|
||||
// primary/active sinks successfully join the audio sharing,
|
||||
// popup dialog till adding source complete for mSinksToWaitFor.
|
||||
@@ -284,7 +284,8 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
/* userTriggered= */ false,
|
||||
/* deviceCountInSharing= */ 1,
|
||||
/* candidateDeviceCount= */ 0);
|
||||
showAudioSharingDialog(eventData);
|
||||
showJoinAudioSharingDialog(eventData,
|
||||
mBroadcast.getLatestBluetoothLeBroadcastMetadata());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -501,9 +502,10 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
mBtManager == null ? null : mBtManager.getCachedDeviceManager();
|
||||
CachedBluetoothDevice cachedDevice =
|
||||
deviceManager == null ? null : deviceManager.findDevice(device);
|
||||
if (cachedDevice != null) {
|
||||
if (cachedDevice != null && mBroadcast != null) {
|
||||
Log.d(TAG, "handleAutoAddSourceAfterPair, device = " + device.getAnonymizedAddress());
|
||||
addSourceToTargetSinks(ImmutableList.of(device), cachedDevice.getName());
|
||||
addSourceToTargetSinks(ImmutableList.of(device), cachedDevice.getName(),
|
||||
mBroadcast.getLatestBluetoothLeBroadcastMetadata());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -642,7 +644,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
return mAssistant != null && mAssistant.getAllConnectedDevices().isEmpty();
|
||||
}
|
||||
|
||||
private void handleOnBroadcastReady() {
|
||||
private void handleOnBroadcastReady(@NonNull BluetoothLeBroadcastMetadata metadata) {
|
||||
List<BluetoothDevice> targetActiveSinks = mTargetActiveItem == null ? ImmutableList.of()
|
||||
: mGroupedConnectedDevices.getOrDefault(
|
||||
mTargetActiveItem.getGroupId(), ImmutableList.of());
|
||||
@@ -656,7 +658,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
// Auto add primary/active sinks w/o user interactions.
|
||||
if (!targetActiveSinks.isEmpty() && mTargetActiveItem != null) {
|
||||
Log.d(TAG, "handleOnBroadcastReady: automatically add source to active sinks.");
|
||||
addSourceToTargetSinks(targetActiveSinks, mTargetActiveItem.getName());
|
||||
addSourceToTargetSinks(targetActiveSinks, mTargetActiveItem.getName(), metadata);
|
||||
// To avoid users advance to share then pair flow before the primary/active sinks
|
||||
// successfully join the audio sharing, save the primary/active sinks in mSinksToWaitFor
|
||||
// and popup dialog till adding source complete for these sinks.
|
||||
@@ -677,7 +679,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
AudioSharingDeviceItem target = mDeviceItemsForSharing.get(0);
|
||||
List<BluetoothDevice> targetSinks = mGroupedConnectedDevices.getOrDefault(
|
||||
target.getGroupId(), ImmutableList.of());
|
||||
addSourceToTargetSinks(targetSinks, target.getName());
|
||||
addSourceToTargetSinks(targetSinks, target.getName(), metadata);
|
||||
cleanUpStatesForStartSharing();
|
||||
// TODO: Add metric for auto add by intent
|
||||
return;
|
||||
@@ -698,20 +700,21 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
// successfully join the audio sharing, popup dialog till adding source complete for
|
||||
// mSinksToWaitFor.
|
||||
if (mSinksToWaitFor.isEmpty() && !mStoppingSharing.get()) {
|
||||
showAudioSharingDialog(eventData);
|
||||
showJoinAudioSharingDialog(eventData, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
private void showAudioSharingDialog(Pair<Integer, Object>[] eventData) {
|
||||
private void showJoinAudioSharingDialog(Pair<Integer, Object>[] eventData,
|
||||
@Nullable BluetoothLeBroadcastMetadata metadata) {
|
||||
if (!BluetoothUtils.isBroadcasting(mBtManager)) {
|
||||
Log.d(TAG, "Skip showAudioSharingDialog, broadcast is stopped");
|
||||
Log.d(TAG, "Skip showJoinAudioSharingDialog, broadcast is stopped");
|
||||
return;
|
||||
}
|
||||
AudioSharingDialogFragment.DialogEventListener listener =
|
||||
new AudioSharingDialogFragment.DialogEventListener() {
|
||||
@Override
|
||||
public void onPositiveClick() {
|
||||
// Could go to other pages, dismiss the progress dialog.
|
||||
// Could go to other pages (pair new device), dismiss the progress dialog.
|
||||
dismissProgressDialogIfNeeded();
|
||||
cleanUpStatesForStartSharing();
|
||||
}
|
||||
@@ -720,19 +723,17 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
public void onItemClick(@NonNull AudioSharingDeviceItem item) {
|
||||
List<BluetoothDevice> targetSinks = mGroupedConnectedDevices.getOrDefault(
|
||||
item.getGroupId(), ImmutableList.of());
|
||||
addSourceToTargetSinks(targetSinks, item.getName());
|
||||
addSourceToTargetSinks(targetSinks, item.getName(), metadata);
|
||||
cleanUpStatesForStartSharing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelClick() {
|
||||
// Could go to other pages, dismiss the progress dialog.
|
||||
// Could go to other pages (show qr code), dismiss the progress dialog.
|
||||
dismissProgressDialogIfNeeded();
|
||||
cleanUpStatesForStartSharing();
|
||||
}
|
||||
};
|
||||
BluetoothLeBroadcastMetadata metadata = mBroadcast == null ? null
|
||||
: mBroadcast.getLatestBluetoothLeBroadcastMetadata();
|
||||
AudioSharingUtils.postOnMainThread(
|
||||
mContext,
|
||||
() -> AudioSharingDialogFragment.show(
|
||||
@@ -828,13 +829,27 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
});
|
||||
}
|
||||
|
||||
private void addSourceToTargetSinks(List<BluetoothDevice> targetActiveSinks,
|
||||
@NonNull String sinkName) {
|
||||
mSinksInAdding.addAll(targetActiveSinks);
|
||||
private void addSourceToTargetSinks(List<BluetoothDevice> targetGroupedSinks,
|
||||
@NonNull String targetSinkName, @Nullable BluetoothLeBroadcastMetadata metadata) {
|
||||
if (targetGroupedSinks.isEmpty()) {
|
||||
Log.d(TAG, "Skip addSourceToTargetSinks, no sinks.");
|
||||
return;
|
||||
}
|
||||
if (metadata == null) {
|
||||
Log.d(TAG, "Skip addSourceToTargetSinks, metadata is null");
|
||||
return;
|
||||
}
|
||||
if (mAssistant == null) {
|
||||
Log.d(TAG, "skip addSourceToTargetDevices, assistant profile is null.");
|
||||
return;
|
||||
}
|
||||
mSinksInAdding.addAll(targetGroupedSinks);
|
||||
String progressMessage = mContext.getString(
|
||||
R.string.audio_sharing_progress_dialog_add_source_content, sinkName);
|
||||
R.string.audio_sharing_progress_dialog_add_source_content, targetSinkName);
|
||||
showProgressDialog(progressMessage);
|
||||
AudioSharingUtils.addSourceToTargetSinks(targetActiveSinks, mBtManager);
|
||||
for (BluetoothDevice sink : targetGroupedSinks) {
|
||||
mAssistant.addSource(sink, metadata, /* isGroupOp= */ false);
|
||||
}
|
||||
}
|
||||
|
||||
private void showProgressDialog(@NonNull String progressMessage) {
|
||||
|
@@ -69,6 +69,12 @@ const val KEY_SCREEN_ATTENTION = "screen_attention"
|
||||
/** Contract key for the "Use adaptive connectivity" setting. */
|
||||
const val KEY_ADAPTIVE_CONNECTIVITY = "adaptive_connectivity"
|
||||
|
||||
/** Contract key for the "Auto-switch Wi-Fi to Cellular" setting. */
|
||||
const val KEY_ADAPTIVE_WIFI_SCORER = "adaptive_wifi_scorer"
|
||||
|
||||
/** Contract key for the " Auto-switch mobile network for battery life" setting. */
|
||||
const val KEY_ADAPTIVE_MOBILE_NETWORK = "adaptive_mobile_network"
|
||||
|
||||
/** Contract key for the "WiFi hotspot" setting. */
|
||||
const val KEY_WIFI_HOTSPOT = "enable_wifi_ap"
|
||||
|
||||
|
@@ -65,9 +65,10 @@ public class PhoneNumberPreferenceController extends BasePreferenceController {
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
if (!SubscriptionUtil.isSimHardwareVisible(mContext)) {
|
||||
if (!isAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Preference preference = screen.findPreference(getPreferenceKey());
|
||||
final PreferenceCategory category = screen.findPreference(KEY_PREFERENCE_CATEGORY);
|
||||
mPreferenceList.add(preference);
|
||||
|
@@ -35,7 +35,6 @@ import com.android.settings.core.TogglePreferenceController;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManager;
|
||||
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
|
||||
import com.android.settingslib.search.SearchIndexableRaw;
|
||||
|
||||
import java.util.List;
|
||||
@@ -46,7 +45,7 @@ public class DeviceStateAutoRotateSettingController extends TogglePreferenceCont
|
||||
|
||||
private TwoStatePreference mPreference;
|
||||
|
||||
private final DeviceStateRotationLockSettingsManager mAutoRotateSettingsManager;
|
||||
private final DeviceStateAutoRotateSettingManager mAutoRotateSettingsManager;
|
||||
private final int mOrder;
|
||||
private final DeviceStateAutoRotateSettingManager.DeviceStateAutoRotateSettingListener
|
||||
mDeviceStateAutoRotateSettingListener = () -> updateState(mPreference);
|
||||
@@ -62,7 +61,8 @@ public class DeviceStateAutoRotateSettingController extends TogglePreferenceCont
|
||||
mMetricsFeatureProvider = metricsFeatureProvider;
|
||||
mDeviceState = deviceState;
|
||||
mDeviceStateDescription = deviceStateDescription;
|
||||
mAutoRotateSettingsManager = DeviceStateRotationLockSettingsManager.getInstance(context);
|
||||
mAutoRotateSettingsManager =
|
||||
DeviceStateAutoRotateSettingManagerProvider.getSingletonInstance(context);
|
||||
mOrder = order;
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.display
|
||||
|
||||
import android.content.Context
|
||||
import android.hardware.devicestate.DeviceStateManager
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.android.internal.annotations.VisibleForTesting
|
||||
import com.android.settingslib.devicestate.AndroidSecureSettings
|
||||
import com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManager
|
||||
import com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManagerProvider.createInstance
|
||||
import com.android.settingslib.devicestate.PosturesHelper
|
||||
import com.android.settingslib.utils.ThreadUtils
|
||||
import com.android.window.flags.Flags
|
||||
|
||||
/**
|
||||
* Provides appropriate instance of [DeviceStateAutoRotateSettingManager], based on the value of
|
||||
* [Flags.FLAG_ENABLE_DEVICE_STATE_AUTO_ROTATE_SETTING_REFACTOR].
|
||||
*/
|
||||
object DeviceStateAutoRotateSettingManagerProvider {
|
||||
private var nullableSingletonSettingManager: DeviceStateAutoRotateSettingManager? = null
|
||||
|
||||
/**
|
||||
* Provides a singleton instance of [DeviceStateAutoRotateSettingManager], based on the
|
||||
* value of[Flags.FLAG_ENABLE_DEVICE_STATE_AUTO_ROTATE_SETTING_REFACTOR]. It is supposed to
|
||||
* be used by apps that don't support dagger to provide and manager instance.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getSingletonInstance(context: Context) =
|
||||
nullableSingletonSettingManager ?: createInstance(
|
||||
context,
|
||||
ThreadUtils.getBackgroundExecutor(),
|
||||
AndroidSecureSettings(context.contentResolver),
|
||||
Handler(Looper.getMainLooper()),
|
||||
PosturesHelper(context, context.getSystemService(DeviceStateManager::class.java))
|
||||
).also {
|
||||
nullableSingletonSettingManager = it
|
||||
}
|
||||
|
||||
/** Resets the singleton instance of [DeviceStateAutoRotateSettingManager]. */
|
||||
@JvmStatic
|
||||
@VisibleForTesting
|
||||
fun resetInstance() {
|
||||
nullableSingletonSettingManager = null
|
||||
}
|
||||
}
|
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.display;
|
||||
|
||||
import static com.android.settingslib.devicestate.DeviceStateAutoRotateSettingUtils.isDeviceStateRotationLockEnabled;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -25,7 +27,6 @@ import com.android.internal.view.RotationPolicy;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
|
||||
import com.android.settingslib.devicestate.SettableDeviceState;
|
||||
import com.android.settingslib.search.SearchIndexableRaw;
|
||||
|
||||
@@ -51,8 +52,8 @@ public class DeviceStateAutoRotationHelper {
|
||||
|
||||
static ImmutableList<AbstractPreferenceController> createPreferenceControllers(
|
||||
Context context) {
|
||||
List<SettableDeviceState> settableDeviceStates = DeviceStateRotationLockSettingsManager
|
||||
.getInstance(context).getSettableDeviceStates();
|
||||
List<SettableDeviceState> settableDeviceStates = DeviceStateAutoRotateSettingManagerProvider
|
||||
.getSingletonInstance(context).getSettableDeviceStates();
|
||||
int numDeviceStates = settableDeviceStates.size();
|
||||
if (numDeviceStates == 0) {
|
||||
return ImmutableList.of();
|
||||
@@ -99,7 +100,7 @@ public class DeviceStateAutoRotationHelper {
|
||||
/** Returns whether the device state based auto-rotation settings are enabled. */
|
||||
public static boolean isDeviceStateRotationEnabled(Context context) {
|
||||
return RotationPolicy.isRotationLockToggleVisible(context)
|
||||
&& DeviceStateRotationLockSettingsManager.isDeviceStateRotationLockEnabled(context);
|
||||
&& isDeviceStateRotationLockEnabled(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,6 +109,6 @@ public class DeviceStateAutoRotationHelper {
|
||||
*/
|
||||
public static boolean isDeviceStateRotationEnabledForA11y(Context context) {
|
||||
return RotationPolicy.isRotationSupported(context)
|
||||
&& DeviceStateRotationLockSettingsManager.isDeviceStateRotationLockEnabled(context);
|
||||
&& isDeviceStateRotationLockEnabled(context);
|
||||
}
|
||||
}
|
||||
|
@@ -47,7 +47,6 @@ import com.android.settings.core.TogglePreferenceController;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManager;
|
||||
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
|
||||
|
||||
/**
|
||||
* SmartAutoRotateController controls whether auto rotation is enabled
|
||||
@@ -75,7 +74,7 @@ public class SmartAutoRotateController extends TogglePreferenceController implem
|
||||
}
|
||||
};
|
||||
|
||||
private final DeviceStateRotationLockSettingsManager mDeviceStateAutoRotateSettingsManager;
|
||||
private final DeviceStateAutoRotateSettingManager mDeviceStateAutoRotateSettingsManager;
|
||||
private final DeviceStateAutoRotateSettingManager.DeviceStateAutoRotateSettingListener
|
||||
mDeviceStateAutoRotateSettingListener = () -> updateState(mPreference);
|
||||
private RotationPolicy.RotationPolicyListener mRotationPolicyListener;
|
||||
@@ -85,8 +84,9 @@ public class SmartAutoRotateController extends TogglePreferenceController implem
|
||||
mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
||||
mPrivacyManager = SensorPrivacyManager.getInstance(context);
|
||||
mPowerManager = context.getSystemService(PowerManager.class);
|
||||
mDeviceStateAutoRotateSettingsManager = DeviceStateRotationLockSettingsManager.getInstance(
|
||||
context);
|
||||
mDeviceStateAutoRotateSettingsManager =
|
||||
DeviceStateAutoRotateSettingManagerProvider.getSingletonInstance(
|
||||
context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -159,6 +159,7 @@ public class SatelliteSettingsPreferenceCategoryController
|
||||
@Override
|
||||
public void onResult(Boolean result) {
|
||||
mIsSatelliteSupported.set(result);
|
||||
Log.d(TAG, "Satellite requestIsSupported : " + result);
|
||||
SatelliteSettingsPreferenceCategoryController.this.displayPreference();
|
||||
}
|
||||
});
|
||||
|
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.supervision
|
||||
|
||||
import android.content.Context
|
||||
import androidx.preference.Preference
|
||||
import com.android.settings.R
|
||||
import com.android.settingslib.datastore.KeyValueStore
|
||||
import com.android.settingslib.datastore.Permissions
|
||||
import com.android.settingslib.datastore.SettingsSecureStore
|
||||
import com.android.settingslib.metadata.BooleanValuePreference
|
||||
import com.android.settingslib.metadata.PreferenceMetadata
|
||||
import com.android.settingslib.metadata.ReadWritePermit
|
||||
import com.android.settingslib.metadata.SensitivityLevel
|
||||
import com.android.settingslib.preference.PreferenceBinding
|
||||
import com.android.settingslib.preference.forEachRecursively
|
||||
import com.android.settingslib.widget.SelectorWithWidgetPreference
|
||||
|
||||
/** Base class of web content filters SafeSearch preferences. */
|
||||
sealed class SupervisionSafeSearchPreference :
|
||||
BooleanValuePreference, SelectorWithWidgetPreference.OnClickListener, PreferenceBinding {
|
||||
override fun storage(context: Context): KeyValueStore = SettingsSecureStore.get(context)
|
||||
|
||||
override fun getReadPermissions(context: Context) = Permissions.EMPTY
|
||||
|
||||
override fun getWritePermissions(context: Context) = Permissions.EMPTY
|
||||
|
||||
override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) =
|
||||
ReadWritePermit.ALLOW
|
||||
|
||||
override fun getWritePermit(
|
||||
context: Context,
|
||||
value: Boolean?,
|
||||
callingPid: Int,
|
||||
callingUid: Int,
|
||||
) = ReadWritePermit.DISALLOW
|
||||
|
||||
override val sensitivityLevel
|
||||
get() = SensitivityLevel.NO_SENSITIVITY
|
||||
|
||||
override fun createWidget(context: Context) = SelectorWithWidgetPreference(context)
|
||||
|
||||
override fun onRadioButtonClicked(emiter: SelectorWithWidgetPreference) {
|
||||
emiter.parent?.forEachRecursively {
|
||||
if (it is SelectorWithWidgetPreference) {
|
||||
it.isChecked = it == emiter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun bind(preference: Preference, metadata: PreferenceMetadata) {
|
||||
super.bind(preference, metadata)
|
||||
(preference as SelectorWithWidgetPreference).also {
|
||||
// TODO(b/401568995): Set the isChecked value using stored values.
|
||||
it.isChecked = (it.key == SupervisionSearchFilterOffPreference.KEY)
|
||||
it.setOnClickListener(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** The SafeSearch filter on preference. */
|
||||
class SupervisionSearchFilterOnPreference : SupervisionSafeSearchPreference() {
|
||||
|
||||
override val key
|
||||
get() = KEY
|
||||
|
||||
override val title
|
||||
get() = R.string.supervision_web_content_filters_search_filter_on_title
|
||||
|
||||
override val summary
|
||||
get() = R.string.supervision_web_content_filters_search_filter_on_summary
|
||||
|
||||
companion object {
|
||||
const val KEY = "web_content_filters_search_filter_on"
|
||||
}
|
||||
}
|
||||
|
||||
/** The SafeSearch filter off preference. */
|
||||
class SupervisionSearchFilterOffPreference : SupervisionSafeSearchPreference() {
|
||||
|
||||
override val key
|
||||
get() = KEY
|
||||
|
||||
override val title
|
||||
get() = R.string.supervision_web_content_filters_search_filter_off_title
|
||||
|
||||
override val summary
|
||||
get() = R.string.supervision_web_content_filters_search_filter_off_summary
|
||||
|
||||
companion object {
|
||||
const val KEY = "web_content_filters_search_filter_off"
|
||||
}
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.supervision
|
||||
|
||||
import android.content.Context
|
||||
import android.provider.Settings.Secure.BROWSER_CONTENT_FILTERS_ENABLED
|
||||
import com.android.settingslib.datastore.AbstractKeyedDataObservable
|
||||
import com.android.settingslib.datastore.HandlerExecutor
|
||||
import com.android.settingslib.datastore.KeyValueStore
|
||||
import com.android.settingslib.datastore.KeyedObserver
|
||||
import com.android.settingslib.datastore.SettingsSecureStore
|
||||
import com.android.settingslib.datastore.SettingsStore
|
||||
|
||||
/** Datastore of the safe sites preference. */
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class SupervisionSafeSitesDataStore(
|
||||
private val context: Context,
|
||||
private val settingsStore: SettingsStore = SettingsSecureStore.get(context),
|
||||
) : AbstractKeyedDataObservable<String>(), KeyedObserver<String>, KeyValueStore {
|
||||
|
||||
override fun contains(key: String) =
|
||||
key == SupervisionBlockExplicitSitesPreference.KEY ||
|
||||
key == SupervisionAllowAllSitesPreference.KEY
|
||||
|
||||
override fun <T : Any> getValue(key: String, valueType: Class<T>): T? {
|
||||
val settingValue = (settingsStore.getBoolean(BROWSER_CONTENT_FILTERS_ENABLED) == true)
|
||||
return when (key) {
|
||||
SupervisionAllowAllSitesPreference.KEY -> !settingValue
|
||||
|
||||
SupervisionBlockExplicitSitesPreference.KEY -> settingValue
|
||||
|
||||
else -> null
|
||||
}
|
||||
as T?
|
||||
}
|
||||
|
||||
override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) {
|
||||
if (value !is Boolean) return
|
||||
when (key) {
|
||||
SupervisionAllowAllSitesPreference.KEY ->
|
||||
settingsStore.setBoolean(BROWSER_CONTENT_FILTERS_ENABLED, !value)
|
||||
|
||||
SupervisionBlockExplicitSitesPreference.KEY ->
|
||||
settingsStore.setBoolean(BROWSER_CONTENT_FILTERS_ENABLED, value)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFirstObserverAdded() {
|
||||
// observe the underlying storage key
|
||||
settingsStore.addObserver(BROWSER_CONTENT_FILTERS_ENABLED, this, HandlerExecutor.main)
|
||||
}
|
||||
|
||||
override fun onKeyChanged(key: String, reason: Int) {
|
||||
// forward data change to preference hierarchy key
|
||||
notifyChange(SupervisionBlockExplicitSitesPreference.KEY, reason)
|
||||
notifyChange(SupervisionAllowAllSitesPreference.KEY, reason)
|
||||
}
|
||||
|
||||
override fun onLastObserverRemoved() {
|
||||
settingsStore.removeObserver(BROWSER_CONTENT_FILTERS_ENABLED, this)
|
||||
}
|
||||
}
|
@@ -18,9 +18,7 @@ package com.android.settings.supervision
|
||||
import android.content.Context
|
||||
import androidx.preference.Preference
|
||||
import com.android.settings.R
|
||||
import com.android.settingslib.datastore.KeyValueStore
|
||||
import com.android.settingslib.datastore.Permissions
|
||||
import com.android.settingslib.datastore.SettingsSecureStore
|
||||
import com.android.settingslib.metadata.BooleanValuePreference
|
||||
import com.android.settingslib.metadata.PreferenceMetadata
|
||||
import com.android.settingslib.metadata.ReadWritePermit
|
||||
@@ -30,9 +28,10 @@ import com.android.settingslib.preference.forEachRecursively
|
||||
import com.android.settingslib.widget.SelectorWithWidgetPreference
|
||||
|
||||
/** Base class of web content filters Safe sites preferences. */
|
||||
sealed class SupervisionSafeSitesPreference :
|
||||
BooleanValuePreference, SelectorWithWidgetPreference.OnClickListener, PreferenceBinding {
|
||||
override fun storage(context: Context): KeyValueStore = SettingsSecureStore.get(context)
|
||||
sealed class SupervisionSafeSitesPreference(
|
||||
protected val dataStore: SupervisionSafeSitesDataStore
|
||||
) : BooleanValuePreference, SelectorWithWidgetPreference.OnClickListener, PreferenceBinding {
|
||||
override fun storage(context: Context) = dataStore
|
||||
|
||||
override fun getReadPermissions(context: Context) = Permissions.EMPTY
|
||||
|
||||
@@ -64,15 +63,15 @@ sealed class SupervisionSafeSitesPreference :
|
||||
override fun bind(preference: Preference, metadata: PreferenceMetadata) {
|
||||
super.bind(preference, metadata)
|
||||
(preference as SelectorWithWidgetPreference).also {
|
||||
// TODO(b/401568468): Set the isChecked value using stored values.
|
||||
it.isChecked = (it.key == SupervisionAllowAllSitesPreference.KEY)
|
||||
it.isChecked = (dataStore.getBoolean(it.key) == true)
|
||||
it.setOnClickListener(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** The "Try to block explicit sites" preference. */
|
||||
class SupervisionBlockExplicitSitesPreference : SupervisionSafeSitesPreference() {
|
||||
class SupervisionBlockExplicitSitesPreference(dataStore: SupervisionSafeSitesDataStore) :
|
||||
SupervisionSafeSitesPreference(dataStore) {
|
||||
|
||||
override val key
|
||||
get() = KEY
|
||||
@@ -89,7 +88,8 @@ class SupervisionBlockExplicitSitesPreference : SupervisionSafeSitesPreference()
|
||||
}
|
||||
|
||||
/** The "Allow all sites" preference. */
|
||||
class SupervisionAllowAllSitesPreference : SupervisionSafeSitesPreference() {
|
||||
class SupervisionAllowAllSitesPreference(dataStore: SupervisionSafeSitesDataStore) :
|
||||
SupervisionSafeSitesPreference(dataStore) {
|
||||
|
||||
override val key
|
||||
get() = KEY
|
||||
|
@@ -47,14 +47,23 @@ class SupervisionWebContentFiltersScreen : PreferenceScreenCreator {
|
||||
R.string.supervision_web_content_filters_browser_title,
|
||||
) +=
|
||||
{
|
||||
+SupervisionBlockExplicitSitesPreference()
|
||||
+SupervisionAllowAllSitesPreference()
|
||||
val dataStore = SupervisionSafeSitesDataStore(context)
|
||||
+SupervisionBlockExplicitSitesPreference(dataStore)
|
||||
+SupervisionAllowAllSitesPreference(dataStore)
|
||||
}
|
||||
+PreferenceCategory(
|
||||
SEARCH_RADIO_BUTTON_GROUP,
|
||||
R.string.supervision_web_content_filters_search_title,
|
||||
) +=
|
||||
{
|
||||
+SupervisionSearchFilterOnPreference()
|
||||
+SupervisionSearchFilterOffPreference()
|
||||
}
|
||||
// TODO(b/401569571) implement the SafeSearch group.
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KEY = "supervision_web_content_filters"
|
||||
internal const val BROWSER_RADIO_BUTTON_GROUP = "browser_radio_button_group"
|
||||
internal const val SEARCH_RADIO_BUTTON_GROUP = "search_radio_button_group"
|
||||
}
|
||||
}
|
||||
|
@@ -16,9 +16,14 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.testutils.DeviceStateAutoRotateSettingTestUtils.setDeviceStateRotationLockEnabled;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
@@ -26,12 +31,14 @@ import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.internal.view.RotationPolicy;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
|
||||
import com.android.settings.testutils.shadow.ShadowRotationPolicy;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
@@ -41,48 +48,45 @@ import org.robolectric.annotation.Config;
|
||||
com.android.settings.testutils.shadow.ShadowSystemSettings.class,
|
||||
})
|
||||
public class LockScreenRotationPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private Resources mResources;
|
||||
private Context mContext;
|
||||
private SwitchPreference mPreference;
|
||||
private LockScreenRotationPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = Mockito.spy(RuntimeEnvironment.application);
|
||||
mPreference = new SwitchPreference(mContext);
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
|
||||
mController = new LockScreenRotationPreferenceController(mContext, "lock_screen");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
ShadowRotationPolicy.class,
|
||||
ShadowDeviceStateRotationLockSettingsManager.class
|
||||
})
|
||||
@Config(shadows = {ShadowRotationPolicy.class})
|
||||
public void getAvailabilityStatus_supportedRotation_shouldReturnAvailable() {
|
||||
ShadowRotationPolicy.setRotationSupported(true /* supported */);
|
||||
setDeviceStateRotationLockEnabled(false, mResources);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
ShadowRotationPolicy.class,
|
||||
ShadowDeviceStateRotationLockSettingsManager.class
|
||||
})
|
||||
@Config(shadows = {ShadowRotationPolicy.class})
|
||||
public void getAvailabilityStatus_deviceStateRotationEnabled_returnsUnsupported() {
|
||||
ShadowRotationPolicy.setRotationSupported(true /* supported */);
|
||||
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
|
||||
setDeviceStateRotationLockEnabled(true, mResources);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.UNSUPPORTED_ON_DEVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
ShadowRotationPolicy.class,
|
||||
ShadowDeviceStateRotationLockSettingsManager.class
|
||||
}) public void getAvailabilityStatus_unsupportedRotation_shouldReturnUnsupportedOnDevice() {
|
||||
@Config(shadows = {ShadowRotationPolicy.class})
|
||||
public void getAvailabilityStatus_unsupportedRotation_shouldReturnUnsupportedOnDevice() {
|
||||
ShadowRotationPolicy.setRotationSupported(false /* supported */);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
|
@@ -127,6 +127,7 @@ public class BluetoothKeyMissingReceiverTest {
|
||||
public void broadcastReceiver_background_showNotification() {
|
||||
Intent intent = spy(new Intent(BluetoothDevice.ACTION_KEY_MISSING));
|
||||
when(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)).thenReturn(mBluetoothDevice);
|
||||
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
|
||||
BluetoothKeyMissingReceiver bluetoothKeyMissingReceiver = getReceiver(intent);
|
||||
bluetoothKeyMissingReceiver.onReceive(mContext, intent);
|
||||
|
||||
@@ -141,6 +142,7 @@ public class BluetoothKeyMissingReceiverTest {
|
||||
when(mLocalBtManager.isForegroundActivity()).thenReturn(true);
|
||||
Intent intent = spy(new Intent(BluetoothDevice.ACTION_KEY_MISSING));
|
||||
when(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)).thenReturn(mBluetoothDevice);
|
||||
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
|
||||
BluetoothKeyMissingReceiver bluetoothKeyMissingReceiver = getReceiver(intent);
|
||||
bluetoothKeyMissingReceiver.onReceive(mContext, intent);
|
||||
|
||||
|
@@ -18,22 +18,29 @@ package com.android.settings.bluetooth;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothCsipSetCoordinator;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||
import android.content.Context;
|
||||
import android.os.SystemProperties;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.A2dpProfile;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
import com.android.settingslib.bluetooth.HeadsetProfile;
|
||||
import com.android.settingslib.bluetooth.HearingAidProfile;
|
||||
import com.android.settingslib.bluetooth.LeAudioProfile;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
@@ -41,8 +48,8 @@ import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -52,10 +59,8 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowBluetoothUtils.class})
|
||||
public class UtilsTest {
|
||||
private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25;
|
||||
private static final String TEMP_BOND_METADATA =
|
||||
@@ -73,6 +78,14 @@ public class UtilsTest {
|
||||
@Mock
|
||||
private LocalBluetoothLeBroadcastAssistant mAssistant;
|
||||
@Mock
|
||||
private A2dpProfile mA2dpProfile;
|
||||
@Mock
|
||||
private HeadsetProfile mHeadsetProfile;
|
||||
@Mock
|
||||
private LeAudioProfile mLeAudioProfile;
|
||||
@Mock
|
||||
private HearingAidProfile mHearingAidProfile;
|
||||
@Mock
|
||||
private CachedBluetoothDeviceManager mDeviceManager;
|
||||
|
||||
private MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
@@ -80,17 +93,14 @@ public class UtilsTest {
|
||||
@Before
|
||||
public void setUp() {
|
||||
mMetricsFeatureProvider = FakeFeatureFactory.setupForTest().getMetricsFeatureProvider();
|
||||
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager;
|
||||
mLocalBtManager = Utils.getLocalBtManager(mContext);
|
||||
when(mLocalBtManager.getProfileManager()).thenReturn(mProfileManager);
|
||||
when(mLocalBtManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
|
||||
when(mProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast);
|
||||
when(mProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(mAssistant);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ShadowBluetoothUtils.reset();
|
||||
when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
|
||||
when(mProfileManager.getHeadsetProfile()).thenReturn(mHeadsetProfile);
|
||||
when(mProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile);
|
||||
when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -170,4 +180,148 @@ public class UtilsTest {
|
||||
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(state));
|
||||
assertThat(Utils.shouldBlockPairingInAudioSharing(mLocalBtManager)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableLeAudioProfile_multipleDeviceInGroup() {
|
||||
CachedBluetoothDevice cachedDevice1 = mock(CachedBluetoothDevice.class);
|
||||
CachedBluetoothDevice cachedDevice2 = mock(CachedBluetoothDevice.class);
|
||||
CachedBluetoothDevice cachedDevice3 = mock(CachedBluetoothDevice.class);
|
||||
BluetoothDevice device1 = mock(BluetoothDevice.class);
|
||||
BluetoothDevice device2 = mock(BluetoothDevice.class);
|
||||
BluetoothDevice device3 = mock(BluetoothDevice.class);
|
||||
when(cachedDevice1.getDevice()).thenReturn(device1);
|
||||
when(cachedDevice2.getDevice()).thenReturn(device2);
|
||||
when(cachedDevice3.getDevice()).thenReturn(device3);
|
||||
when(cachedDevice1.getMemberDevice()).thenReturn(ImmutableSet.of(cachedDevice2));
|
||||
when(mDeviceManager.getCachedDevicesCopy())
|
||||
.thenReturn(ImmutableList.of(cachedDevice1, cachedDevice3));
|
||||
when(cachedDevice1.getGroupId()).thenReturn(1);
|
||||
when(cachedDevice2.getGroupId()).thenReturn(1);
|
||||
when(cachedDevice3.getGroupId()).thenReturn(2);
|
||||
when(cachedDevice1.getProfiles())
|
||||
.thenReturn(ImmutableList.of(mA2dpProfile, mHeadsetProfile, mLeAudioProfile));
|
||||
when(cachedDevice2.getProfiles()).thenReturn(ImmutableList.of(mLeAudioProfile));
|
||||
when(cachedDevice3.getProfiles())
|
||||
.thenReturn(ImmutableList.of(mA2dpProfile, mHeadsetProfile, mLeAudioProfile));
|
||||
|
||||
Utils.setLeAudioEnabled(mLocalBtManager, cachedDevice2, true);
|
||||
|
||||
verify(mLeAudioProfile).setEnabled(device1, true);
|
||||
verify(mLeAudioProfile).setEnabled(device2, true);
|
||||
verify(mHearingAidProfile).setEnabled(device1, false);
|
||||
verify(mAssistant).setEnabled(device1, true);
|
||||
verify(mLeAudioProfile, never()).setEnabled(eq(device3), anyBoolean());
|
||||
verify(mA2dpProfile, never()).setEnabled(eq(device3), anyBoolean());
|
||||
verify(mHeadsetProfile, never()).setEnabled(eq(device3), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableLeAudioProfile_dualModeEnabled_a2dpAndHfpNotChanged() {
|
||||
SystemProperties.set("persist.bluetooth.enable_dual_mode_audio", "true");
|
||||
CachedBluetoothDevice cachedDevice1 = mock(CachedBluetoothDevice.class);
|
||||
BluetoothDevice device1 = mock(BluetoothDevice.class);
|
||||
when(cachedDevice1.getDevice()).thenReturn(device1);
|
||||
when(cachedDevice1.getGroupId()).thenReturn(BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
|
||||
when(cachedDevice1.getProfiles())
|
||||
.thenReturn(ImmutableList.of(mA2dpProfile, mHeadsetProfile, mLeAudioProfile));
|
||||
when(mA2dpProfile.isEnabled(device1)).thenReturn(true);
|
||||
when(mHeadsetProfile.isEnabled(device1)).thenReturn(true);
|
||||
|
||||
Utils.setLeAudioEnabled(mLocalBtManager, cachedDevice1, true);
|
||||
|
||||
verify(mLeAudioProfile).setEnabled(device1, true);
|
||||
verify(mA2dpProfile, never()).setEnabled(device1, false);
|
||||
verify(mHeadsetProfile, never()).setEnabled(device1, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableLeAudioProfile_dualModeDisabled_disableA2dpAndHfp() {
|
||||
SystemProperties.set("persist.bluetooth.enable_dual_mode_audio", "false");
|
||||
CachedBluetoothDevice cachedDevice1 = mock(CachedBluetoothDevice.class);
|
||||
BluetoothDevice device1 = mock(BluetoothDevice.class);
|
||||
when(cachedDevice1.getDevice()).thenReturn(device1);
|
||||
when(cachedDevice1.getGroupId()).thenReturn(BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
|
||||
when(cachedDevice1.getProfiles())
|
||||
.thenReturn(ImmutableList.of(mA2dpProfile, mHeadsetProfile, mLeAudioProfile));
|
||||
when(mA2dpProfile.isEnabled(device1)).thenReturn(true);
|
||||
when(mHeadsetProfile.isEnabled(device1)).thenReturn(true);
|
||||
|
||||
Utils.setLeAudioEnabled(mLocalBtManager, cachedDevice1, true);
|
||||
|
||||
verify(mLeAudioProfile).setEnabled(device1, true);
|
||||
verify(mA2dpProfile).setEnabled(device1, false);
|
||||
verify(mHeadsetProfile).setEnabled(device1, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disableLeAudioProfile_multipleDeviceInGroup() {
|
||||
CachedBluetoothDevice cachedDevice1 = mock(CachedBluetoothDevice.class);
|
||||
CachedBluetoothDevice cachedDevice2 = mock(CachedBluetoothDevice.class);
|
||||
CachedBluetoothDevice cachedDevice3 = mock(CachedBluetoothDevice.class);
|
||||
BluetoothDevice device1 = mock(BluetoothDevice.class);
|
||||
BluetoothDevice device2 = mock(BluetoothDevice.class);
|
||||
BluetoothDevice device3 = mock(BluetoothDevice.class);
|
||||
when(cachedDevice1.getDevice()).thenReturn(device1);
|
||||
when(cachedDevice2.getDevice()).thenReturn(device2);
|
||||
when(cachedDevice3.getDevice()).thenReturn(device3);
|
||||
when(cachedDevice1.getMemberDevice()).thenReturn(ImmutableSet.of(cachedDevice2));
|
||||
when(mDeviceManager.getCachedDevicesCopy())
|
||||
.thenReturn(ImmutableList.of(cachedDevice1, cachedDevice3));
|
||||
when(cachedDevice1.getGroupId()).thenReturn(1);
|
||||
when(cachedDevice2.getGroupId()).thenReturn(1);
|
||||
when(cachedDevice3.getGroupId()).thenReturn(2);
|
||||
when(cachedDevice1.getProfiles())
|
||||
.thenReturn(ImmutableList.of(mA2dpProfile, mHeadsetProfile, mLeAudioProfile));
|
||||
when(cachedDevice2.getProfiles()).thenReturn(ImmutableList.of(mLeAudioProfile));
|
||||
when(cachedDevice3.getProfiles())
|
||||
.thenReturn(ImmutableList.of(mA2dpProfile, mHeadsetProfile, mLeAudioProfile));
|
||||
|
||||
Utils.setLeAudioEnabled(mLocalBtManager, cachedDevice2, false);
|
||||
|
||||
verify(mLeAudioProfile).setEnabled(device1, false);
|
||||
verify(mLeAudioProfile).setEnabled(device2, false);
|
||||
verify(mHearingAidProfile).setEnabled(device1, true);
|
||||
verify(mAssistant).setEnabled(device1, false);
|
||||
verify(mLeAudioProfile, never()).setEnabled(eq(device3), anyBoolean());
|
||||
verify(mA2dpProfile, never()).setEnabled(eq(device3), anyBoolean());
|
||||
verify(mHeadsetProfile, never()).setEnabled(eq(device3), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disableLeAudioProfile_dualModeEnabled_a2dpAndHfpNotChanged() {
|
||||
SystemProperties.set("persist.bluetooth.enable_dual_mode_audio", "true");
|
||||
CachedBluetoothDevice cachedDevice1 = mock(CachedBluetoothDevice.class);
|
||||
BluetoothDevice device1 = mock(BluetoothDevice.class);
|
||||
when(cachedDevice1.getDevice()).thenReturn(device1);
|
||||
when(cachedDevice1.getGroupId()).thenReturn(BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
|
||||
when(cachedDevice1.getProfiles())
|
||||
.thenReturn(ImmutableList.of(mA2dpProfile, mHeadsetProfile, mLeAudioProfile));
|
||||
when(mA2dpProfile.isEnabled(device1)).thenReturn(false);
|
||||
when(mHeadsetProfile.isEnabled(device1)).thenReturn(false);
|
||||
|
||||
Utils.setLeAudioEnabled(mLocalBtManager, cachedDevice1, false);
|
||||
|
||||
verify(mLeAudioProfile).setEnabled(device1, false);
|
||||
verify(mA2dpProfile, never()).setEnabled(device1, true);
|
||||
verify(mHeadsetProfile, never()).setEnabled(device1, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disableLeAudioProfile_dualModeDisabled_enableA2dpAndHfp() {
|
||||
SystemProperties.set("persist.bluetooth.enable_dual_mode_audio", "false");
|
||||
CachedBluetoothDevice cachedDevice1 = mock(CachedBluetoothDevice.class);
|
||||
BluetoothDevice device1 = mock(BluetoothDevice.class);
|
||||
when(cachedDevice1.getDevice()).thenReturn(device1);
|
||||
when(cachedDevice1.getGroupId()).thenReturn(BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
|
||||
when(cachedDevice1.getProfiles())
|
||||
.thenReturn(ImmutableList.of(mA2dpProfile, mHeadsetProfile, mLeAudioProfile));
|
||||
when(mA2dpProfile.isEnabled(device1)).thenReturn(false);
|
||||
when(mHeadsetProfile.isEnabled(device1)).thenReturn(false);
|
||||
|
||||
Utils.setLeAudioEnabled(mLocalBtManager, cachedDevice1, false);
|
||||
|
||||
verify(mLeAudioProfile).setEnabled(device1, false);
|
||||
verify(mA2dpProfile).setEnabled(device1, true);
|
||||
verify(mHeadsetProfile).setEnabled(device1, true);
|
||||
}
|
||||
}
|
||||
|
@@ -39,7 +39,6 @@ import android.hardware.devicestate.DeviceStateManager;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -144,16 +143,15 @@ public class DeviceStateAutoRotateDetailsFragmentTest {
|
||||
}
|
||||
|
||||
private void enableDeviceStateSettableRotationStates(String[] settableStates,
|
||||
String[] settableStatesDescriptions) {
|
||||
String[] settableStatesDescriptions) {
|
||||
when(mResources.getStringArray(
|
||||
com.android.internal.R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
|
||||
settableStates);
|
||||
when(mResources.getStringArray(
|
||||
R.array.config_settableAutoRotationDeviceStatesDescriptions)).thenReturn(
|
||||
settableStatesDescriptions);
|
||||
DeviceStateRotationLockSettingsManager.resetInstance();
|
||||
DeviceStateRotationLockSettingsManager.getInstance(mContext)
|
||||
.resetStateForTesting(mResources);
|
||||
DeviceStateAutoRotateSettingManagerProvider.resetInstance();
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
}
|
||||
|
||||
// Sets up posture mappings for PosturesHelper
|
||||
|
@@ -18,30 +18,48 @@ package com.android.settings.display;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
|
||||
import static com.android.settings.testutils.DeviceStateAutoRotateSettingTestUtils.setDeviceStateRotationLockEnabled;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowRotationPolicy;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowRotationPolicy.class, ShadowDeviceStateRotationLockSettingsManager.class})
|
||||
@Config(shadows = {ShadowRotationPolicy.class})
|
||||
public class DeviceStateAutoRotateOverviewControllerTest {
|
||||
@Mock
|
||||
private Resources mResources;
|
||||
private DeviceStateAutoRotateOverviewController mController;
|
||||
|
||||
private final DeviceStateAutoRotateOverviewController mController =
|
||||
new DeviceStateAutoRotateOverviewController(
|
||||
RuntimeEnvironment.application, "device_state_auto_rotate");
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
Context context = Mockito.spy(RuntimeEnvironment.application);
|
||||
when(context.getResources()).thenReturn(mResources);
|
||||
|
||||
mController = new DeviceStateAutoRotateOverviewController(
|
||||
context, "device_state_auto_rotate");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_rotationAndDeviceStateRotationEnabled_returnsAvailable() {
|
||||
ShadowRotationPolicy.setRotationSupported(true);
|
||||
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
|
||||
setDeviceStateRotationLockEnabled(true, mResources);
|
||||
|
||||
int availability = mController.getAvailabilityStatus();
|
||||
|
||||
@@ -51,7 +69,7 @@ public class DeviceStateAutoRotateOverviewControllerTest {
|
||||
@Test
|
||||
public void getAvailabilityStatus_rotationNotSupported_returnsUnsupportedOnDevice() {
|
||||
ShadowRotationPolicy.setRotationSupported(false);
|
||||
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
|
||||
setDeviceStateRotationLockEnabled(true, mResources);
|
||||
|
||||
int availability = mController.getAvailabilityStatus();
|
||||
|
||||
@@ -61,7 +79,7 @@ public class DeviceStateAutoRotateOverviewControllerTest {
|
||||
@Test
|
||||
public void getAvailabilityStatus_deviceStateRotationNotSupported_returnsUnsupportedOnDevice() {
|
||||
ShadowRotationPolicy.setRotationSupported(true);
|
||||
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
|
||||
setDeviceStateRotationLockEnabled(false, mResources);
|
||||
|
||||
int availability = mController.getAvailabilityStatus();
|
||||
|
||||
|
@@ -18,14 +18,17 @@ package com.android.settings.display;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
|
||||
import static com.android.settings.testutils.DeviceStateAutoRotateSettingTestUtils.setDeviceStateRotationLockEnabled;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.devicestate.DeviceState;
|
||||
import android.hardware.devicestate.DeviceStateManager;
|
||||
|
||||
@@ -34,10 +37,9 @@ import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
|
||||
import com.android.settings.testutils.shadow.ShadowRotationPolicy;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
|
||||
import com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManager;
|
||||
import com.android.settingslib.search.SearchIndexableRaw;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -54,10 +56,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
ShadowRotationPolicy.class,
|
||||
ShadowDeviceStateRotationLockSettingsManager.class
|
||||
})
|
||||
@Config(shadows = {ShadowRotationPolicy.class})
|
||||
public class DeviceStateAutoRotateSettingControllerTest {
|
||||
|
||||
private static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState(
|
||||
@@ -66,10 +65,11 @@ public class DeviceStateAutoRotateSettingControllerTest {
|
||||
private static final int DEFAULT_ORDER = -10;
|
||||
|
||||
private final Context mContext = Mockito.spy(RuntimeEnvironment.application);
|
||||
private DeviceStateRotationLockSettingsManager mAutoRotateSettingsManager;
|
||||
private DeviceStateAutoRotateSettingManager mAutoRotateSettingsManager;
|
||||
|
||||
@Mock private MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
@Mock private DeviceStateManager mDeviceStateManager;
|
||||
@Mock private Resources mResources;
|
||||
|
||||
private DeviceStateAutoRotateSettingController mController;
|
||||
|
||||
@@ -78,11 +78,14 @@ public class DeviceStateAutoRotateSettingControllerTest {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
doReturn(mContext).when(mContext).getApplicationContext();
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
doReturn(mDeviceStateManager).when(mContext).getSystemService(DeviceStateManager.class);
|
||||
doReturn(List.of(DEFAULT_DEVICE_STATE)).when(
|
||||
mDeviceStateManager).getSupportedDeviceStates();
|
||||
setDeviceStateRotationLockEnabled(false, mResources);
|
||||
mAutoRotateSettingsManager =
|
||||
DeviceStateRotationLockSettingsManager.getInstance(mContext);
|
||||
DeviceStateAutoRotateSettingManagerProvider.getSingletonInstance(mContext);
|
||||
|
||||
mController = new DeviceStateAutoRotateSettingController(
|
||||
mContext,
|
||||
DEFAULT_DEVICE_STATE.getIdentifier(),
|
||||
@@ -108,7 +111,7 @@ public class DeviceStateAutoRotateSettingControllerTest {
|
||||
@Test
|
||||
public void getAvailabilityStatus_rotationAndDeviceStateRotationEnabled_returnsAvailable() {
|
||||
ShadowRotationPolicy.setRotationSupported(true);
|
||||
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
|
||||
setDeviceStateRotationLockEnabled(true, mResources);
|
||||
|
||||
int availability = mController.getAvailabilityStatus();
|
||||
|
||||
@@ -118,7 +121,7 @@ public class DeviceStateAutoRotateSettingControllerTest {
|
||||
@Test
|
||||
public void getAvailabilityStatus_deviceStateRotationDisabled_returnsUnsupported() {
|
||||
ShadowRotationPolicy.setRotationSupported(true);
|
||||
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
|
||||
setDeviceStateRotationLockEnabled(false, mResources);
|
||||
|
||||
int availability = mController.getAvailabilityStatus();
|
||||
|
||||
@@ -128,7 +131,7 @@ public class DeviceStateAutoRotateSettingControllerTest {
|
||||
@Test
|
||||
public void getAvailabilityStatus_rotationDisabled_returnsUnsupported() {
|
||||
ShadowRotationPolicy.setRotationSupported(false);
|
||||
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
|
||||
setDeviceStateRotationLockEnabled(true, mResources);
|
||||
|
||||
int availability = mController.getAvailabilityStatus();
|
||||
|
||||
|
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.display;
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.hardware.devicestate.DeviceStateManager
|
||||
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
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.internal.R
|
||||
import com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManagerImpl
|
||||
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager
|
||||
import com.android.window.flags.Flags
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Assert.assertNotSame
|
||||
import org.junit.Assert.assertSame
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class DeviceStateAutoRotateSettingManagerProviderTest {
|
||||
|
||||
@get:Rule
|
||||
val setFlagsRule: SetFlagsRule = SetFlagsRule()
|
||||
@get:Rule
|
||||
val rule = MockitoJUnit.rule()
|
||||
|
||||
@Mock
|
||||
private lateinit var mockContext: Context
|
||||
@Mock
|
||||
private lateinit var mockDeviceStateManager: DeviceStateManager
|
||||
@Mock
|
||||
private lateinit var mockResources: Resources
|
||||
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
whenever(mockContext.contentResolver).thenReturn(context.contentResolver)
|
||||
whenever(mockContext.getSystemService(DeviceStateManager::class.java)).thenReturn(
|
||||
mockDeviceStateManager
|
||||
)
|
||||
whenever(mockContext.resources).thenReturn(mockResources)
|
||||
whenever(mockResources.getStringArray(R.array.config_perDeviceStateRotationLockDefaults))
|
||||
.thenReturn(arrayOf())
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
DeviceStateAutoRotateSettingManagerProvider.resetInstance()
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENABLE_DEVICE_STATE_AUTO_ROTATE_SETTING_REFACTOR)
|
||||
fun getSingletonInstance_refactorFlagEnabled_returnsRefactoredManager() {
|
||||
val manager = DeviceStateAutoRotateSettingManagerProvider.getSingletonInstance(mockContext)
|
||||
|
||||
assertThat(manager).isInstanceOf(DeviceStateAutoRotateSettingManagerImpl::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisableFlags(Flags.FLAG_ENABLE_DEVICE_STATE_AUTO_ROTATE_SETTING_REFACTOR)
|
||||
fun getSingletonInstance_refactorFlagDisabled_returnsLegacyManager() {
|
||||
val manager = DeviceStateAutoRotateSettingManagerProvider.getSingletonInstance(mockContext)
|
||||
|
||||
assertThat(manager).isInstanceOf(DeviceStateRotationLockSettingsManager::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENABLE_DEVICE_STATE_AUTO_ROTATE_SETTING_REFACTOR)
|
||||
fun getSingletonInstance_resetInstance_returnsNewInstance() {
|
||||
val manager1 = DeviceStateAutoRotateSettingManagerProvider.getSingletonInstance(mockContext)
|
||||
DeviceStateAutoRotateSettingManagerProvider.resetInstance()
|
||||
val manager2 = DeviceStateAutoRotateSettingManagerProvider.getSingletonInstance(mockContext)
|
||||
|
||||
assertNotSame(manager1, manager2)
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENABLE_DEVICE_STATE_AUTO_ROTATE_SETTING_REFACTOR)
|
||||
fun getSingletonInstance_getInstanceTwice_returnsSameInstance() {
|
||||
val manager1 = DeviceStateAutoRotateSettingManagerProvider.getSingletonInstance(mockContext)
|
||||
val manager2 = DeviceStateAutoRotateSettingManagerProvider.getSingletonInstance(mockContext)
|
||||
|
||||
assertSame(manager1, manager2)
|
||||
}
|
||||
}
|
@@ -19,6 +19,7 @@ package com.android.settings.display;
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
|
||||
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
|
||||
import static com.android.settings.testutils.DeviceStateAutoRotateSettingTestUtils.setDeviceStateRotationLockEnabled;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
@@ -33,6 +34,7 @@ import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.devicestate.DeviceState;
|
||||
import android.hardware.devicestate.DeviceStateManager;
|
||||
import android.os.UserHandle;
|
||||
@@ -41,11 +43,11 @@ import android.provider.Settings;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.testutils.ResolveInfoBuilder;
|
||||
import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
|
||||
import com.android.settings.testutils.shadow.ShadowDeviceStateAutoRotateSettingManager;
|
||||
import com.android.settings.testutils.shadow.ShadowRotationPolicy;
|
||||
import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
|
||||
import com.android.settings.testutils.shadow.ShadowSystemSettings;
|
||||
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
|
||||
import com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -73,17 +75,21 @@ public class SmartAutoRotateControllerTest {
|
||||
private Preference mPreference;
|
||||
@Mock
|
||||
private DeviceStateManager mDeviceStateManager;
|
||||
@Mock
|
||||
private Resources mResources;
|
||||
private ContentResolver mContentResolver;
|
||||
private DeviceStateRotationLockSettingsManager mDeviceStateAutoRotateSettingsManager;
|
||||
private DeviceStateAutoRotateSettingManager mDeviceStateAutoRotateSettingManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
final Context context = Mockito.spy(RuntimeEnvironment.application);
|
||||
mContentResolver = RuntimeEnvironment.application.getContentResolver();
|
||||
mResources = Mockito.spy(RuntimeEnvironment.application.getResources());
|
||||
|
||||
when(context.getPackageManager()).thenReturn(mPackageManager);
|
||||
when(context.getContentResolver()).thenReturn(mContentResolver);
|
||||
when(context.getResources()).thenReturn(mResources);
|
||||
doReturn(PACKAGE_NAME).when(mPackageManager).getRotationResolverPackageName();
|
||||
doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission(
|
||||
Manifest.permission.CAMERA, PACKAGE_NAME);
|
||||
@@ -91,8 +97,9 @@ public class SmartAutoRotateControllerTest {
|
||||
doReturn(context).when(context).getApplicationContext();
|
||||
doReturn(mDeviceStateManager).when(context).getSystemService(DeviceStateManager.class);
|
||||
doReturn(getDeviceStateList()).when(mDeviceStateManager).getSupportedDeviceStates();
|
||||
mDeviceStateAutoRotateSettingsManager = DeviceStateRotationLockSettingsManager.getInstance(
|
||||
context);
|
||||
setDeviceStateRotationLockEnabled(false, mResources);
|
||||
mDeviceStateAutoRotateSettingManager =
|
||||
DeviceStateAutoRotateSettingManagerProvider.getSingletonInstance(context);
|
||||
mController = Mockito.spy(new SmartAutoRotateController(context, "test_key"));
|
||||
|
||||
when(mController.isCameraLocked()).thenReturn(false);
|
||||
@@ -144,7 +151,7 @@ public class SmartAutoRotateControllerTest {
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
ShadowDeviceStateRotationLockSettingsManager.class,
|
||||
ShadowDeviceStateAutoRotateSettingManager.class,
|
||||
ShadowRotationPolicy.class
|
||||
})
|
||||
public void getAvailabilityStatus_deviceStateRotationLocked_returnDisableDependentSetting() {
|
||||
@@ -158,7 +165,7 @@ public class SmartAutoRotateControllerTest {
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
ShadowDeviceStateRotationLockSettingsManager.class,
|
||||
ShadowDeviceStateAutoRotateSettingManager.class,
|
||||
ShadowRotationPolicy.class
|
||||
})
|
||||
public void getAvailabilityStatus_deviceStateRotationUnlocked_returnAvailable() {
|
||||
@@ -182,18 +189,18 @@ public class SmartAutoRotateControllerTest {
|
||||
|
||||
private void enableDeviceStateRotation() {
|
||||
ShadowRotationPolicy.setRotationSupported(true);
|
||||
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
|
||||
setDeviceStateRotationLockEnabled(true, mResources);
|
||||
}
|
||||
|
||||
private void lockDeviceStateRotation() {
|
||||
ShadowDeviceStateRotationLockSettingsManager shadowManager =
|
||||
Shadow.extract(mDeviceStateAutoRotateSettingsManager);
|
||||
ShadowDeviceStateAutoRotateSettingManager shadowManager =
|
||||
Shadow.extract(mDeviceStateAutoRotateSettingManager);
|
||||
shadowManager.setRotationLockedForAllStates(true);
|
||||
}
|
||||
|
||||
private void unlockDeviceStateRotation() {
|
||||
ShadowDeviceStateRotationLockSettingsManager shadowManager =
|
||||
Shadow.extract(mDeviceStateAutoRotateSettingsManager);
|
||||
ShadowDeviceStateAutoRotateSettingManager shadowManager =
|
||||
Shadow.extract(mDeviceStateAutoRotateSettingManager);
|
||||
shadowManager.setRotationLockedForAllStates(false);
|
||||
}
|
||||
|
||||
|
@@ -18,6 +18,8 @@ package com.android.settings.display;
|
||||
|
||||
import static android.provider.Settings.Secure.CAMERA_AUTOROTATE;
|
||||
|
||||
import static com.android.settings.testutils.DeviceStateAutoRotateSettingTestUtils.setDeviceStateRotationLockEnabled;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -40,7 +42,6 @@ import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.ResolveInfoBuilder;
|
||||
import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
|
||||
import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
|
||||
import com.android.settings.testutils.shadow.ShadowSystemSettings;
|
||||
|
||||
@@ -57,8 +58,7 @@ import org.robolectric.annotation.Config;
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
ShadowSystemSettings.class,
|
||||
ShadowSensorPrivacyManager.class,
|
||||
ShadowDeviceStateRotationLockSettingsManager.class
|
||||
ShadowSensorPrivacyManager.class
|
||||
})
|
||||
public class SmartAutoRotatePreferenceControllerTest {
|
||||
|
||||
@@ -104,7 +104,7 @@ public class SmartAutoRotatePreferenceControllerTest {
|
||||
new SmartAutoRotatePreferenceController(mContext, "smart_auto_rotate"));
|
||||
when(mController.isCameraLocked()).thenReturn(false);
|
||||
when(mController.isPowerSaveMode()).thenReturn(false);
|
||||
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
|
||||
setDeviceStateRotationLockEnabled(false, mResources);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -213,7 +213,7 @@ public class SmartAutoRotatePreferenceControllerTest {
|
||||
@Test
|
||||
public void getAvailabilityStatus_deviceStateRotationEnabled_returnsUnsupported() {
|
||||
enableAutoRotationPreference();
|
||||
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
|
||||
setDeviceStateRotationLockEnabled(true, mResources);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.UNSUPPORTED_ON_DEVICE);
|
||||
|
@@ -27,6 +27,7 @@ import static android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_LOCKED
|
||||
|
||||
import static com.android.settings.display.SmartAutoRotatePreferenceFragment.AUTO_ROTATE_MAIN_SWITCH_PREFERENCE_KEY;
|
||||
import static com.android.settings.display.SmartAutoRotatePreferenceFragment.AUTO_ROTATE_SWITCH_PREFERENCE_KEY;
|
||||
import static com.android.settings.testutils.DeviceStateAutoRotateSettingTestUtils.setDeviceStateRotationLockEnabled;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
@@ -55,10 +56,8 @@ import androidx.preference.Preference;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.testutils.ResolveInfoBuilder;
|
||||
import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
|
||||
import com.android.settings.testutils.shadow.ShadowRotationPolicy;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -75,7 +74,6 @@ import java.util.Set;
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
com.android.settings.testutils.shadow.ShadowFragment.class,
|
||||
ShadowDeviceStateRotationLockSettingsManager.class,
|
||||
ShadowRotationPolicy.class
|
||||
})
|
||||
public class SmartAutoRotatePreferenceFragmentTest {
|
||||
@@ -174,7 +172,7 @@ public class SmartAutoRotatePreferenceFragmentTest {
|
||||
|
||||
@Test
|
||||
public void createHeader_faceDetectionSupported_switchBarIsEnabled() {
|
||||
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
|
||||
setDeviceStateRotationLockEnabled(false, mResources);
|
||||
mFragment.createHeader(mActivity);
|
||||
|
||||
verify(mRotateMainSwitchPreference, never()).setVisible(false);
|
||||
@@ -184,7 +182,7 @@ public class SmartAutoRotatePreferenceFragmentTest {
|
||||
@Test
|
||||
public void createHeader_deviceStateRotationSupported_switchBarIsDisabled() {
|
||||
ShadowRotationPolicy.setRotationSupported(true);
|
||||
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
|
||||
setDeviceStateRotationLockEnabled(true, mResources);
|
||||
|
||||
mFragment.createHeader(mActivity);
|
||||
|
||||
@@ -258,15 +256,14 @@ public class SmartAutoRotatePreferenceFragmentTest {
|
||||
private void enableDeviceStateSettableRotationStates(
|
||||
String[] settableStates, String[] settableStatesDescriptions) {
|
||||
when(mResources.getStringArray(
|
||||
com.android.internal.R.array.config_perDeviceStateRotationLockDefaults))
|
||||
com.android.internal.R.array.config_perDeviceStateRotationLockDefaults))
|
||||
.thenReturn(settableStates);
|
||||
when(mResources.getStringArray(R.array.config_settableAutoRotationDeviceStatesDescriptions))
|
||||
.thenReturn(settableStatesDescriptions);
|
||||
when(mResources.getBoolean(R.bool.config_auto_rotate_face_detection_available))
|
||||
.thenReturn(true);
|
||||
DeviceStateRotationLockSettingsManager.resetInstance();
|
||||
DeviceStateRotationLockSettingsManager.getInstance(mContext)
|
||||
.resetStateForTesting(mResources);
|
||||
DeviceStateAutoRotateSettingManagerProvider.resetInstance();
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
}
|
||||
|
||||
// Sets up posture mappings for PosturesHelper
|
||||
|
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.supervision
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.R
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class SupervisionSafeSearchPreferenceTest {
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
|
||||
private val searchFilterOnPreference = SupervisionSearchFilterOnPreference()
|
||||
|
||||
private val searchFilterOffPreference = SupervisionSearchFilterOffPreference()
|
||||
|
||||
@Test
|
||||
fun getTitle_filterOn() {
|
||||
assertThat(searchFilterOnPreference.title)
|
||||
.isEqualTo(R.string.supervision_web_content_filters_search_filter_on_title)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun getSummary_filterOn() {
|
||||
assertThat(searchFilterOnPreference.summary)
|
||||
.isEqualTo(R.string.supervision_web_content_filters_search_filter_on_summary)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getTitle_filterOff() {
|
||||
assertThat(searchFilterOffPreference.title)
|
||||
.isEqualTo(R.string.supervision_web_content_filters_search_filter_off_title)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getSummary_filterOff() {
|
||||
assertThat(searchFilterOffPreference.summary)
|
||||
.isEqualTo(
|
||||
R.string.supervision_web_content_filters_search_filter_off_summary
|
||||
)
|
||||
}
|
||||
}
|
@@ -16,20 +16,33 @@
|
||||
package com.android.settings.supervision
|
||||
|
||||
import android.content.Context
|
||||
import android.provider.Settings
|
||||
import android.provider.Settings.Secure.BROWSER_CONTENT_FILTERS_ENABLED
|
||||
import android.provider.Settings.SettingNotFoundException
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.R
|
||||
import com.android.settingslib.preference.createAndBindWidget
|
||||
import com.android.settingslib.widget.SelectorWithWidgetPreference
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Assert.assertThrows
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class SupervisionSafeSitesPreferenceTest {
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
private lateinit var dataStore: SupervisionSafeSitesDataStore
|
||||
private lateinit var allowAllSitesPreference: SupervisionAllowAllSitesPreference
|
||||
private lateinit var blockExplicitSitesPreference: SupervisionBlockExplicitSitesPreference
|
||||
|
||||
private val allowAllSitesPreference = SupervisionAllowAllSitesPreference()
|
||||
|
||||
private val blockExplicitSitesPreference = SupervisionBlockExplicitSitesPreference()
|
||||
@Before
|
||||
fun setUp() {
|
||||
dataStore = SupervisionSafeSitesDataStore(context)
|
||||
allowAllSitesPreference = SupervisionAllowAllSitesPreference(dataStore)
|
||||
blockExplicitSitesPreference = SupervisionBlockExplicitSitesPreference(dataStore)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getTitle_allowAllSites() {
|
||||
@@ -50,4 +63,64 @@ class SupervisionSafeSitesPreferenceTest {
|
||||
R.string.supervision_web_content_filters_browser_block_explicit_sites_summary
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun allowAllSitesIsChecked_whenNoValueIsSet() {
|
||||
assertThrows(SettingNotFoundException::class.java) {
|
||||
Settings.Secure.getInt(context.getContentResolver(), BROWSER_CONTENT_FILTERS_ENABLED)
|
||||
}
|
||||
assertThat(getBlockExplicitSitesWidget().isChecked).isFalse()
|
||||
assertThat(getAllowAllSitesWidget().isChecked).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun blockExplicitSitesIsChecked_whenPreviouslyEnabled() {
|
||||
Settings.Secure.putInt(context.getContentResolver(), BROWSER_CONTENT_FILTERS_ENABLED, 1)
|
||||
assertThat(getAllowAllSitesWidget().isChecked).isFalse()
|
||||
assertThat(getBlockExplicitSitesWidget().isChecked).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun clickBlockExplicitSites_enablesFilter() {
|
||||
Settings.Secure.putInt(context.getContentResolver(), BROWSER_CONTENT_FILTERS_ENABLED, 0)
|
||||
val blockExplicitSitesWidget = getBlockExplicitSitesWidget()
|
||||
assertThat(blockExplicitSitesWidget.isChecked).isFalse()
|
||||
|
||||
blockExplicitSitesWidget.performClick()
|
||||
|
||||
assertThat(
|
||||
Settings.Secure.getInt(
|
||||
context.getContentResolver(),
|
||||
BROWSER_CONTENT_FILTERS_ENABLED,
|
||||
)
|
||||
)
|
||||
.isEqualTo(1)
|
||||
assertThat(blockExplicitSitesWidget.isChecked).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun clickAllowAllSites_disablesFilter() {
|
||||
Settings.Secure.putInt(context.getContentResolver(), BROWSER_CONTENT_FILTERS_ENABLED, 1)
|
||||
val allowAllSitesWidget = getAllowAllSitesWidget()
|
||||
assertThat(allowAllSitesWidget.isChecked).isFalse()
|
||||
|
||||
allowAllSitesWidget.performClick()
|
||||
|
||||
assertThat(
|
||||
Settings.Secure.getInt(
|
||||
context.getContentResolver(),
|
||||
BROWSER_CONTENT_FILTERS_ENABLED,
|
||||
)
|
||||
)
|
||||
.isEqualTo(0)
|
||||
assertThat(allowAllSitesWidget.isChecked).isTrue()
|
||||
}
|
||||
|
||||
private fun getBlockExplicitSitesWidget(): SelectorWithWidgetPreference {
|
||||
return blockExplicitSitesPreference.createAndBindWidget(context)
|
||||
}
|
||||
|
||||
private fun getAllowAllSitesWidget(): SelectorWithWidgetPreference {
|
||||
return allowAllSitesPreference.createAndBindWidget(context)
|
||||
}
|
||||
}
|
||||
|
@@ -15,18 +15,32 @@
|
||||
*/
|
||||
package com.android.settings.supervision
|
||||
|
||||
import android.app.supervision.flags.Flags
|
||||
import android.content.Context
|
||||
import android.platform.test.annotations.DisableFlags
|
||||
import android.platform.test.annotations.EnableFlags
|
||||
import android.platform.test.flag.junit.SetFlagsRule
|
||||
import androidx.fragment.app.testing.FragmentScenario
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.R
|
||||
import com.android.settingslib.widget.SelectorWithWidgetPreference
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class SupervisionWebContentFiltersScreenTest {
|
||||
@get:Rule val setFlagsRule = SetFlagsRule()
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
private val supervisionWebContentFiltersScreen = SupervisionWebContentFiltersScreen()
|
||||
private lateinit var supervisionWebContentFiltersScreen: SupervisionWebContentFiltersScreen
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
supervisionWebContentFiltersScreen = SupervisionWebContentFiltersScreen()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun key() {
|
||||
@@ -39,4 +53,40 @@ class SupervisionWebContentFiltersScreenTest {
|
||||
assertThat(supervisionWebContentFiltersScreen.title)
|
||||
.isEqualTo(R.string.supervision_web_content_filters_title)
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENABLE_WEB_CONTENT_FILTERS_SCREEN)
|
||||
fun flagEnabled() {
|
||||
assertThat(supervisionWebContentFiltersScreen.isFlagEnabled(context)).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisableFlags(Flags.FLAG_ENABLE_WEB_CONTENT_FILTERS_SCREEN)
|
||||
fun flagDisabled() {
|
||||
assertThat(supervisionWebContentFiltersScreen.isFlagEnabled(context)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENABLE_WEB_CONTENT_FILTERS_SCREEN)
|
||||
fun switchSafeSitesPreferences() {
|
||||
FragmentScenario.launchInContainer(supervisionWebContentFiltersScreen.fragmentClass())
|
||||
.onFragment { fragment ->
|
||||
val allowAllSitesPreference =
|
||||
fragment.findPreference<SelectorWithWidgetPreference>(
|
||||
SupervisionAllowAllSitesPreference.KEY
|
||||
)!!
|
||||
val blockExplicitSitesPreference =
|
||||
fragment.findPreference<SelectorWithWidgetPreference>(
|
||||
SupervisionBlockExplicitSitesPreference.KEY
|
||||
)!!
|
||||
|
||||
assertThat(allowAllSitesPreference.isChecked).isTrue()
|
||||
assertThat(blockExplicitSitesPreference.isChecked).isFalse()
|
||||
|
||||
blockExplicitSitesPreference.performClick()
|
||||
|
||||
assertThat(blockExplicitSitesPreference.isChecked).isTrue()
|
||||
assertThat(allowAllSitesPreference.isChecked).isFalse()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.testutils;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.res.Resources;
|
||||
|
||||
/**
|
||||
* Helper for testing device state auto rotate setting
|
||||
*/
|
||||
public class DeviceStateAutoRotateSettingTestUtils {
|
||||
|
||||
/**
|
||||
* Mock {@link mockResources} to return device state auto rotate enabled or disabled based on
|
||||
* value passed for {@link enable}.
|
||||
*/
|
||||
public static void setDeviceStateRotationLockEnabled(boolean enable, Resources mockResources) {
|
||||
String[] perDeviceStateRotationLockDefaults = new String[0];
|
||||
if (enable) {
|
||||
perDeviceStateRotationLockDefaults = new String[]{"test_value"};
|
||||
}
|
||||
when(mockResources.getStringArray(
|
||||
com.android.internal.R.array.config_perDeviceStateRotationLockDefaults))
|
||||
.thenReturn(perDeviceStateRotationLockDefaults);
|
||||
}
|
||||
}
|
@@ -16,28 +16,16 @@
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(DeviceStateRotationLockSettingsManager.class)
|
||||
public class ShadowDeviceStateRotationLockSettingsManager {
|
||||
public class ShadowDeviceStateAutoRotateSettingManager {
|
||||
|
||||
private static boolean sDeviceStateRotationLockEnabled;
|
||||
private boolean mIsRotationLockedForAllStates;
|
||||
|
||||
@Implementation
|
||||
public static boolean isDeviceStateRotationLockEnabled(Context context) {
|
||||
return sDeviceStateRotationLockEnabled;
|
||||
}
|
||||
|
||||
public static void setDeviceStateRotationLockEnabled(boolean enabled) {
|
||||
sDeviceStateRotationLockEnabled = enabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean isRotationLockedForAllStates() {
|
||||
return mIsRotationLockedForAllStates;
|
@@ -18,24 +18,48 @@ package com.android.settings.testutils.shadow;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settings.bluetooth.Utils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/** Robolectric shadow for the bluetooth utils. */
|
||||
@Implements(Utils.class)
|
||||
public class ShadowBluetoothUtils {
|
||||
|
||||
public static LocalBluetoothManager sLocalBluetoothManager;
|
||||
private static final Map<CachedBluetoothDevice, Boolean> sLeAudioState = new HashMap<>();
|
||||
|
||||
@Implementation
|
||||
protected static LocalBluetoothManager getLocalBtManager(Context context) {
|
||||
return sLocalBluetoothManager;
|
||||
}
|
||||
|
||||
/** Sets le audio state for the device. */
|
||||
@Implementation
|
||||
public static void setLeAudioEnabled(
|
||||
@NonNull LocalBluetoothManager manager,
|
||||
@NonNull CachedBluetoothDevice cachedDevice,
|
||||
boolean enable) {
|
||||
sLeAudioState.put(cachedDevice, enable);
|
||||
}
|
||||
|
||||
/** Checks whether le audio is enabled for the device. */
|
||||
public static boolean isLeAudioEnabled(@NonNull CachedBluetoothDevice cachedDevice) {
|
||||
if (sLeAudioState.containsKey(cachedDevice)) {
|
||||
return sLeAudioState.get(cachedDevice);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Resets the local bluetooth manager to null. */
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
|
Reference in New Issue
Block a user