Snap for 12210778 from dbbcdd6ebe
to 24Q4-release
Change-Id: I31a7d1a612f87f2f310d7c32f0c43c18e6d7038a
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@null"
|
||||
android:paddingBottom="24dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
|
@@ -152,6 +152,7 @@
|
||||
android:summary="@string/contact_discovery_opt_in_summary"
|
||||
settings:controller="com.android.settings.network.telephony.ContactDiscoveryPreferenceController"/>
|
||||
|
||||
<!-- Settings search is handled by PreferredNetworkModeSearchItem. -->
|
||||
<ListPreference
|
||||
android:key="preferred_network_mode_key"
|
||||
android:title="@string/preferred_network_mode_title"
|
||||
@@ -159,8 +160,10 @@
|
||||
android:entries="@array/preferred_network_mode_choices"
|
||||
android:entryValues="@array/preferred_network_mode_values"
|
||||
android:dialogTitle="@string/preferred_network_mode_dialogtitle"
|
||||
settings:searchable="false"
|
||||
settings:controller="com.android.settings.network.telephony.PreferredNetworkModePreferenceController"/>
|
||||
|
||||
<!-- Settings search is handled by EnabledNetworkModeSearchItem. -->
|
||||
<ListPreference
|
||||
android:key="enabled_networks_key"
|
||||
android:title="@string/preferred_network_mode_title"
|
||||
@@ -168,6 +171,7 @@
|
||||
android:entries="@array/enabled_networks_choices"
|
||||
android:entryValues="@array/enabled_networks_values"
|
||||
android:dialogTitle="@string/preferred_network_mode_dialogtitle"
|
||||
settings:searchable="false"
|
||||
settings:controller="com.android.settings.network.telephony.EnabledNetworkModePreferenceController"/>
|
||||
|
||||
<Preference
|
||||
|
@@ -89,7 +89,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
|
||||
private LocalBluetoothManager mManager;
|
||||
private LocalBluetoothProfileManager mProfileManager;
|
||||
private CachedBluetoothDevice mCachedDevice;
|
||||
private List<CachedBluetoothDevice> mAllOfCachedDevices;
|
||||
private Set<CachedBluetoothDevice> mCachedDeviceGroup;
|
||||
private Map<String, List<CachedBluetoothDevice>> mProfileDeviceMap =
|
||||
new HashMap<String, List<CachedBluetoothDevice>>();
|
||||
private boolean mIsLeContactSharingEnabled = false;
|
||||
@@ -105,7 +105,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
|
||||
mManager = manager;
|
||||
mProfileManager = mManager.getProfileManager();
|
||||
mCachedDevice = device;
|
||||
mAllOfCachedDevices = Utils.getAllOfCachedBluetoothDevices(mManager, mCachedDevice);
|
||||
mCachedDeviceGroup = Utils.findAllCachedBluetoothDevicesByGroupId(mManager, mCachedDevice);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -310,10 +310,10 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
|
||||
private List<LocalBluetoothProfile> getProfiles() {
|
||||
List<LocalBluetoothProfile> result = new ArrayList<>();
|
||||
mProfileDeviceMap.clear();
|
||||
if (mAllOfCachedDevices == null || mAllOfCachedDevices.isEmpty()) {
|
||||
if (mCachedDeviceGroup == null || mCachedDeviceGroup.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
for (CachedBluetoothDevice cachedItem : mAllOfCachedDevices) {
|
||||
for (CachedBluetoothDevice cachedItem : mCachedDeviceGroup) {
|
||||
List<LocalBluetoothProfile> tmpResult = cachedItem.getUiAccessibleProfiles();
|
||||
for (LocalBluetoothProfile profile : tmpResult) {
|
||||
if (mProfileDeviceMap.containsKey(profile.toString())) {
|
||||
@@ -514,7 +514,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
for (CachedBluetoothDevice item : mAllOfCachedDevices) {
|
||||
for (CachedBluetoothDevice item : mCachedDeviceGroup) {
|
||||
item.unregisterCallback(this);
|
||||
}
|
||||
mProfileManager.removeServiceListener(this);
|
||||
@@ -523,7 +523,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
|
||||
@Override
|
||||
public void onResume() {
|
||||
updateLeAudioConfig();
|
||||
for (CachedBluetoothDevice item : mAllOfCachedDevices) {
|
||||
for (CachedBluetoothDevice item : mCachedDeviceGroup) {
|
||||
item.registerCallback(this);
|
||||
}
|
||||
mProfileManager.addServiceListener(this);
|
||||
@@ -545,11 +545,11 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
|
||||
|
||||
@Override
|
||||
public void onDeviceAttributesChanged() {
|
||||
for (CachedBluetoothDevice item : mAllOfCachedDevices) {
|
||||
for (CachedBluetoothDevice item : mCachedDeviceGroup) {
|
||||
item.unregisterCallback(this);
|
||||
}
|
||||
mAllOfCachedDevices = Utils.getAllOfCachedBluetoothDevices(mManager, mCachedDevice);
|
||||
for (CachedBluetoothDevice item : mAllOfCachedDevices) {
|
||||
mCachedDeviceGroup = Utils.findAllCachedBluetoothDevicesByGroupId(mManager, mCachedDevice);
|
||||
for (CachedBluetoothDevice item : mCachedDeviceGroup) {
|
||||
item.registerCallback(this);
|
||||
}
|
||||
|
||||
|
@@ -46,6 +46,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.widget.GearPreference;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
@@ -55,6 +56,7 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* BluetoothDevicePreference is the preference type used to display each remote
|
||||
@@ -76,7 +78,10 @@ public final class BluetoothDevicePreference extends GearPreference {
|
||||
}
|
||||
|
||||
private final CachedBluetoothDevice mCachedDevice;
|
||||
private Set<CachedBluetoothDevice> mCachedDeviceGroup;
|
||||
|
||||
private final UserManager mUserManager;
|
||||
private final LocalBluetoothManager mLocalBtManager;
|
||||
|
||||
private Set<BluetoothDevice> mBluetoothDevices;
|
||||
@VisibleForTesting
|
||||
@@ -113,6 +118,21 @@ public final class BluetoothDevicePreference extends GearPreference {
|
||||
@Override
|
||||
public void onDeviceAttributesChanged() {
|
||||
onPreferenceAttributesChanged();
|
||||
Set<CachedBluetoothDevice> newCachedDeviceGroup = new HashSet<>(
|
||||
Utils.findAllCachedBluetoothDevicesByGroupId(mLocalBtManager, mCachedDevice));
|
||||
if (!mCachedDeviceGroup.equals(newCachedDeviceGroup)) {
|
||||
for (CachedBluetoothDevice cachedBluetoothDevice : mCachedDeviceGroup) {
|
||||
cachedBluetoothDevice.unregisterCallback(this);
|
||||
}
|
||||
unregisterMetadataChangedListener();
|
||||
|
||||
mCachedDeviceGroup = newCachedDeviceGroup;
|
||||
|
||||
for (CachedBluetoothDevice cachedBluetoothDevice : mCachedDeviceGroup) {
|
||||
cachedBluetoothDevice.registerCallback(getContext().getMainExecutor(), this);
|
||||
}
|
||||
registerMetadataChangedListener();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +141,7 @@ public final class BluetoothDevicePreference extends GearPreference {
|
||||
super(context, null);
|
||||
mResources = getContext().getResources();
|
||||
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
mLocalBtManager = Utils.getLocalBluetoothManager(context);
|
||||
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
mShowDevicesWithoutNames = showDeviceWithoutNames;
|
||||
|
||||
@@ -131,6 +152,8 @@ public final class BluetoothDevicePreference extends GearPreference {
|
||||
}
|
||||
|
||||
mCachedDevice = cachedDevice;
|
||||
mCachedDeviceGroup = new HashSet<>(
|
||||
Utils.findAllCachedBluetoothDevicesByGroupId(mLocalBtManager, mCachedDevice));
|
||||
mCallback = new BluetoothDevicePreferenceCallback();
|
||||
mId = sNextId.getAndIncrement();
|
||||
mType = type;
|
||||
@@ -164,7 +187,9 @@ public final class BluetoothDevicePreference extends GearPreference {
|
||||
protected void onPrepareForRemoval() {
|
||||
super.onPrepareForRemoval();
|
||||
if (!mIsCallbackRemoved) {
|
||||
mCachedDevice.unregisterCallback(mCallback);
|
||||
for (CachedBluetoothDevice cachedBluetoothDevice : mCachedDeviceGroup) {
|
||||
cachedBluetoothDevice.unregisterCallback(mCallback);
|
||||
}
|
||||
unregisterMetadataChangedListener();
|
||||
mIsCallbackRemoved = true;
|
||||
}
|
||||
@@ -178,7 +203,9 @@ public final class BluetoothDevicePreference extends GearPreference {
|
||||
public void onAttached() {
|
||||
super.onAttached();
|
||||
if (mIsCallbackRemoved) {
|
||||
mCachedDevice.registerCallback(mCallback);
|
||||
for (CachedBluetoothDevice cachedBluetoothDevice : mCachedDeviceGroup) {
|
||||
cachedBluetoothDevice.registerCallback(getContext().getMainExecutor(), mCallback);
|
||||
}
|
||||
registerMetadataChangedListener();
|
||||
mIsCallbackRemoved = false;
|
||||
}
|
||||
@@ -189,7 +216,9 @@ public final class BluetoothDevicePreference extends GearPreference {
|
||||
public void onDetached() {
|
||||
super.onDetached();
|
||||
if (!mIsCallbackRemoved) {
|
||||
mCachedDevice.unregisterCallback(mCallback);
|
||||
for (CachedBluetoothDevice cachedBluetoothDevice : mCachedDeviceGroup) {
|
||||
cachedBluetoothDevice.unregisterCallback(mCallback);
|
||||
}
|
||||
unregisterMetadataChangedListener();
|
||||
mIsCallbackRemoved = true;
|
||||
}
|
||||
@@ -200,16 +229,11 @@ public final class BluetoothDevicePreference extends GearPreference {
|
||||
Log.d(TAG, "No mBluetoothAdapter");
|
||||
return;
|
||||
}
|
||||
if (mBluetoothDevices == null) {
|
||||
mBluetoothDevices = new HashSet<>();
|
||||
}
|
||||
mBluetoothDevices.clear();
|
||||
if (mCachedDevice.getDevice() != null) {
|
||||
mBluetoothDevices.add(mCachedDevice.getDevice());
|
||||
}
|
||||
for (CachedBluetoothDevice cbd : mCachedDevice.getMemberDevice()) {
|
||||
mBluetoothDevices.add(cbd.getDevice());
|
||||
}
|
||||
|
||||
mBluetoothDevices = mCachedDeviceGroup.stream()
|
||||
.map(CachedBluetoothDevice::getDevice)
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
|
||||
if (mBluetoothDevices.isEmpty()) {
|
||||
Log.d(TAG, "No BT device to register.");
|
||||
return;
|
||||
|
@@ -47,7 +47,7 @@ import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
import com.android.settingslib.widget.LayoutPreference;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class adds a header with device name and status (connected/disconnected, etc.).
|
||||
@@ -90,7 +90,7 @@ public class LeAudioBluetoothDetailsHeaderController extends BasePreferenceContr
|
||||
LayoutPreference mLayoutPreference;
|
||||
LocalBluetoothManager mManager;
|
||||
private CachedBluetoothDevice mCachedDevice;
|
||||
private List<CachedBluetoothDevice> mAllOfCachedDevices;
|
||||
private Set<CachedBluetoothDevice> mCachedDeviceGroup;
|
||||
@VisibleForTesting
|
||||
Handler mHandler = new Handler(Looper.getMainLooper());
|
||||
@VisibleForTesting
|
||||
@@ -128,7 +128,7 @@ public class LeAudioBluetoothDetailsHeaderController extends BasePreferenceContr
|
||||
return;
|
||||
}
|
||||
mIsRegisterCallback = true;
|
||||
for (CachedBluetoothDevice item : mAllOfCachedDevices) {
|
||||
for (CachedBluetoothDevice item : mCachedDeviceGroup) {
|
||||
item.registerCallback(this);
|
||||
}
|
||||
refresh();
|
||||
@@ -139,7 +139,7 @@ public class LeAudioBluetoothDetailsHeaderController extends BasePreferenceContr
|
||||
if (!mIsRegisterCallback) {
|
||||
return;
|
||||
}
|
||||
for (CachedBluetoothDevice item : mAllOfCachedDevices) {
|
||||
for (CachedBluetoothDevice item : mCachedDeviceGroup) {
|
||||
item.unregisterCallback(this);
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ public class LeAudioBluetoothDetailsHeaderController extends BasePreferenceContr
|
||||
mCachedDevice = cachedBluetoothDevice;
|
||||
mManager = bluetoothManager;
|
||||
mProfileManager = bluetoothManager.getProfileManager();
|
||||
mAllOfCachedDevices = Utils.getAllOfCachedBluetoothDevices(mManager, mCachedDevice);
|
||||
mCachedDeviceGroup = Utils.findAllCachedBluetoothDevicesByGroupId(mManager, mCachedDevice);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -230,7 +230,7 @@ public class LeAudioBluetoothDetailsHeaderController extends BasePreferenceContr
|
||||
// Init the battery layouts.
|
||||
hideAllOfBatteryLayouts();
|
||||
LeAudioProfile leAudioProfile = mProfileManager.getLeAudioProfile();
|
||||
if (mAllOfCachedDevices.isEmpty()) {
|
||||
if (mCachedDeviceGroup.isEmpty()) {
|
||||
Log.e(TAG, "There is no LeAudioProfile.");
|
||||
return;
|
||||
}
|
||||
@@ -244,7 +244,7 @@ public class LeAudioBluetoothDetailsHeaderController extends BasePreferenceContr
|
||||
return;
|
||||
}
|
||||
|
||||
for (CachedBluetoothDevice cachedDevice : mAllOfCachedDevices) {
|
||||
for (CachedBluetoothDevice cachedDevice : mCachedDeviceGroup) {
|
||||
int deviceId = leAudioProfile.getAudioLocation(cachedDevice.getDevice());
|
||||
Log.d(TAG, "LeAudioDevices:" + cachedDevice.getDevice().getAnonymizedAddress()
|
||||
+ ", deviceId:" + deviceId);
|
||||
@@ -300,15 +300,15 @@ public class LeAudioBluetoothDetailsHeaderController extends BasePreferenceContr
|
||||
|
||||
@Override
|
||||
public void onDeviceAttributesChanged() {
|
||||
for (CachedBluetoothDevice item : mAllOfCachedDevices) {
|
||||
for (CachedBluetoothDevice item : mCachedDeviceGroup) {
|
||||
item.unregisterCallback(this);
|
||||
}
|
||||
mAllOfCachedDevices = Utils.getAllOfCachedBluetoothDevices(mManager, mCachedDevice);
|
||||
for (CachedBluetoothDevice item : mAllOfCachedDevices) {
|
||||
mCachedDeviceGroup = Utils.findAllCachedBluetoothDevicesByGroupId(mManager, mCachedDevice);
|
||||
for (CachedBluetoothDevice item : mCachedDeviceGroup) {
|
||||
item.registerCallback(this);
|
||||
}
|
||||
|
||||
if (!mAllOfCachedDevices.isEmpty()) {
|
||||
if (!mCachedDeviceGroup.isEmpty()) {
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
@@ -48,8 +48,9 @@ import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
@@ -239,12 +240,12 @@ public final class Utils {
|
||||
* @param cachedBluetoothDevice The main cachedBluetoothDevice.
|
||||
* @return all cachedBluetoothDevices with the same groupId.
|
||||
*/
|
||||
public static List<CachedBluetoothDevice> getAllOfCachedBluetoothDevices(
|
||||
public static Set<CachedBluetoothDevice> findAllCachedBluetoothDevicesByGroupId(
|
||||
LocalBluetoothManager localBtMgr,
|
||||
CachedBluetoothDevice cachedBluetoothDevice) {
|
||||
List<CachedBluetoothDevice> cachedBluetoothDevices = new ArrayList<>();
|
||||
Set<CachedBluetoothDevice> cachedBluetoothDevices = new HashSet<>();
|
||||
if (cachedBluetoothDevice == null) {
|
||||
Log.e(TAG, "getAllOfCachedBluetoothDevices: no cachedBluetoothDevice");
|
||||
Log.e(TAG, "findAllCachedBluetoothDevicesByGroupId: no cachedBluetoothDevice");
|
||||
return cachedBluetoothDevices;
|
||||
}
|
||||
int deviceGroupId = cachedBluetoothDevice.getGroupId();
|
||||
@@ -254,7 +255,7 @@ public final class Utils {
|
||||
}
|
||||
|
||||
if (localBtMgr == null) {
|
||||
Log.e(TAG, "getAllOfCachedBluetoothDevices: no LocalBluetoothManager");
|
||||
Log.e(TAG, "findAllCachedBluetoothDevicesByGroupId: no LocalBluetoothManager");
|
||||
return cachedBluetoothDevices;
|
||||
}
|
||||
CachedBluetoothDevice mainDevice =
|
||||
@@ -262,16 +263,14 @@ public final class Utils {
|
||||
.filter(cachedDevice -> cachedDevice.getGroupId() == deviceGroupId)
|
||||
.findFirst().orElse(null);
|
||||
if (mainDevice == null) {
|
||||
Log.e(TAG, "getAllOfCachedBluetoothDevices: groupId = " + deviceGroupId
|
||||
Log.e(TAG, "findAllCachedBluetoothDevicesByGroupId: groupId = " + deviceGroupId
|
||||
+ ", no main device.");
|
||||
return cachedBluetoothDevices;
|
||||
}
|
||||
cachedBluetoothDevice = mainDevice;
|
||||
cachedBluetoothDevices.add(cachedBluetoothDevice);
|
||||
for (CachedBluetoothDevice member : cachedBluetoothDevice.getMemberDevice()) {
|
||||
cachedBluetoothDevices.add(member);
|
||||
}
|
||||
Log.d(TAG, "getAllOfCachedBluetoothDevices: groupId = " + deviceGroupId
|
||||
cachedBluetoothDevices.addAll(cachedBluetoothDevice.getMemberDevice());
|
||||
Log.d(TAG, "findAllCachedBluetoothDevicesByGroupId: groupId = " + deviceGroupId
|
||||
+ " , cachedBluetoothDevice = " + cachedBluetoothDevice
|
||||
+ " , deviceList = " + cachedBluetoothDevices);
|
||||
return cachedBluetoothDevices;
|
||||
|
@@ -30,6 +30,9 @@ import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.BluetoothPairingDetail;
|
||||
import com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsQrCodeFragment;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
|
||||
@@ -130,9 +133,27 @@ public class AudioSharingDialogFragment extends InstrumentedDialogFragment {
|
||||
builder.setTitle(R.string.audio_sharing_share_dialog_title)
|
||||
.setCustomImage(R.drawable.audio_sharing_guidance)
|
||||
.setCustomMessage(R.string.audio_sharing_dialog_connect_device_content)
|
||||
.setNegativeButton(
|
||||
R.string.audio_sharing_close_button_label,
|
||||
(dig, which) -> onCancelClick());
|
||||
.setCustomPositiveButton(
|
||||
R.string.audio_sharing_pair_button_label,
|
||||
v -> {
|
||||
dismiss();
|
||||
new SubSettingLauncher(getContext())
|
||||
.setDestination(BluetoothPairingDetail.class.getName())
|
||||
.setSourceMetricsCategory(getMetricsCategory())
|
||||
.launch();
|
||||
logDialogPositiveBtnClick();
|
||||
})
|
||||
.setCustomNegativeButton(
|
||||
R.string.audio_sharing_qrcode_button_label,
|
||||
v -> {
|
||||
dismiss();
|
||||
new SubSettingLauncher(getContext())
|
||||
.setTitleRes(R.string.audio_streams_qr_code_page_title)
|
||||
.setDestination(AudioStreamsQrCodeFragment.class.getName())
|
||||
.setSourceMetricsCategory(getMetricsCategory())
|
||||
.launch();
|
||||
logDialogNegativeBtnClick();
|
||||
});
|
||||
} else if (deviceItems.size() == 1) {
|
||||
AudioSharingDeviceItem deviceItem = Iterables.getOnlyElement(deviceItems);
|
||||
builder.setTitle(
|
||||
@@ -145,11 +166,7 @@ public class AudioSharingDialogFragment extends InstrumentedDialogFragment {
|
||||
v -> {
|
||||
if (sListener != null) {
|
||||
sListener.onItemClick(deviceItem);
|
||||
mMetricsFeatureProvider.action(
|
||||
getContext(),
|
||||
SettingsEnums
|
||||
.ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED,
|
||||
sEventData);
|
||||
logDialogPositiveBtnClick();
|
||||
}
|
||||
dismiss();
|
||||
})
|
||||
@@ -165,6 +182,7 @@ public class AudioSharingDialogFragment extends InstrumentedDialogFragment {
|
||||
(AudioSharingDeviceItem item) -> {
|
||||
if (sListener != null) {
|
||||
sListener.onItemClick(item);
|
||||
logDialogPositiveBtnClick();
|
||||
}
|
||||
dismiss();
|
||||
},
|
||||
@@ -178,11 +196,22 @@ public class AudioSharingDialogFragment extends InstrumentedDialogFragment {
|
||||
private void onCancelClick() {
|
||||
if (sListener != null) {
|
||||
sListener.onCancelClick();
|
||||
mMetricsFeatureProvider.action(
|
||||
getContext(),
|
||||
SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED,
|
||||
sEventData);
|
||||
logDialogNegativeBtnClick();
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
|
||||
private void logDialogPositiveBtnClick() {
|
||||
mMetricsFeatureProvider.action(
|
||||
getContext(),
|
||||
SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED,
|
||||
sEventData);
|
||||
}
|
||||
|
||||
private void logDialogNegativeBtnClick() {
|
||||
mMetricsFeatureProvider.action(
|
||||
getContext(),
|
||||
SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED,
|
||||
sEventData);
|
||||
}
|
||||
}
|
||||
|
@@ -499,7 +499,7 @@ public class AudioSharingDialogHandler {
|
||||
private void removeSourceForGroup(
|
||||
int groupId, Map<Integer, List<BluetoothDevice>> groupedDevices) {
|
||||
if (mAssistant == null) {
|
||||
Log.d(TAG, "Fail to add source due to null profiles, group = " + groupId);
|
||||
Log.d(TAG, "Fail to remove source due to null profiles, group = " + groupId);
|
||||
return;
|
||||
}
|
||||
if (!groupedDevices.containsKey(groupId)) {
|
||||
|
@@ -81,9 +81,15 @@ public class AudioSharingReceiver extends BroadcastReceiver {
|
||||
break;
|
||||
case ACTION_LE_AUDIO_SHARING_STOP:
|
||||
LocalBluetoothManager manager = Utils.getLocalBtManager(context);
|
||||
AudioSharingUtils.stopBroadcasting(manager);
|
||||
metricsFeatureProvider.action(
|
||||
context, SettingsEnums.ACTION_STOP_AUDIO_SHARING_FROM_NOTIFICATION);
|
||||
if (BluetoothUtils.isBroadcasting(manager)) {
|
||||
AudioSharingUtils.stopBroadcasting(manager);
|
||||
metricsFeatureProvider.action(
|
||||
context, SettingsEnums.ACTION_STOP_AUDIO_SHARING_FROM_NOTIFICATION);
|
||||
} else {
|
||||
cancelSharingNotification(context);
|
||||
metricsFeatureProvider.action(
|
||||
context, SettingsEnums.ACTION_CANCEL_AUDIO_SHARING_NOTIFICATION);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log.w(TAG, "Received unexpected intent " + intent.getAction());
|
||||
|
@@ -39,6 +39,11 @@ public class AutoTimePreferenceController extends TogglePreferenceController {
|
||||
public AutoTimePreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mTimeManager = context.getSystemService(TimeManager.class);
|
||||
// This is a no-op implementation of UpdateTimeAndDateCallback to avoid a NPE when
|
||||
// setTimeAndDateCallback() isn't called, e.g. for slices and other cases where the
|
||||
// controller is instantiated outside of the context of the real Date & Time settings
|
||||
// screen.
|
||||
mCallback = (c) -> {};
|
||||
}
|
||||
|
||||
public void setDateAndTimeCallback(UpdateTimeAndDateCallback callback) {
|
||||
|
@@ -40,6 +40,11 @@ public class AutoTimeZonePreferenceController extends TogglePreferenceController
|
||||
public AutoTimeZonePreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mTimeManager = context.getSystemService(TimeManager.class);
|
||||
// This is a no-op implementation of UpdateTimeAndDateCallback to avoid a NPE when
|
||||
// setTimeAndDateCallback() isn't called, e.g. for slices and other cases where the
|
||||
// controller is instantiated outside of the context of the real Date & Time settings
|
||||
// screen.
|
||||
mCallback = (c) -> {};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -43,6 +43,11 @@ public class TimeFormatPreferenceController extends TogglePreferenceController {
|
||||
public TimeFormatPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mDummyDate = Calendar.getInstance();
|
||||
// This is a no-op implementation of UpdateTimeAndDateCallback to avoid a NPE when
|
||||
// setTimeAndDateCallback() isn't called, e.g. for slices and other cases where the
|
||||
// controller is instantiated outside of the context of the real Date & Time settings
|
||||
// screen.
|
||||
mUpdateTimeAndDateCallback = (c) -> {};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -78,6 +78,11 @@ public class DynamicDenylistManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mNetworkPolicyManager == null) {
|
||||
Log.w(TAG, "syncPolicyIfNeeded: invalid mNetworkPolicyManager");
|
||||
return;
|
||||
}
|
||||
|
||||
final SharedPreferences.Editor editor = getManualDenylistPref().edit();
|
||||
final int[] existedUids = mNetworkPolicyManager
|
||||
.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND);
|
||||
@@ -91,6 +96,11 @@ public class DynamicDenylistManager {
|
||||
|
||||
/** Set policy flags for specific UID. */
|
||||
public void setUidPolicyLocked(int uid, int policy) {
|
||||
if (mNetworkPolicyManager == null) {
|
||||
Log.w(TAG, "setUidPolicyLocked: invalid mNetworkPolicyManager");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.i(TAG, "setUidPolicyLocked: uid=" + uid + " policy=" + policy);
|
||||
synchronized (mLock) {
|
||||
mNetworkPolicyManager.setUidPolicy(uid, policy);
|
||||
@@ -100,7 +110,7 @@ public class DynamicDenylistManager {
|
||||
|
||||
/** Suggest a list of package to set as POLICY_REJECT. */
|
||||
public void setDenylist(Set<Integer> denylistTargetUids) {
|
||||
if (denylistTargetUids == null) {
|
||||
if (denylistTargetUids == null || mNetworkPolicyManager == null) {
|
||||
return;
|
||||
}
|
||||
final Set<Integer> manualDenylistUids = getDenylistAllUids(getManualDenylistPref());
|
||||
@@ -164,6 +174,12 @@ public class DynamicDenylistManager {
|
||||
Log.w(TAG, "resetDenylistIfNeeded: invalid conditions");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mNetworkPolicyManager == null) {
|
||||
Log.w(TAG, "setUidPolicyLocked: invalid mNetworkPolicyManager");
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
final int[] uids = mNetworkPolicyManager
|
||||
.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND);
|
||||
|
@@ -19,9 +19,11 @@ package com.android.settings.network.telephony;
|
||||
import static androidx.lifecycle.Lifecycle.Event.ON_START;
|
||||
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
|
||||
|
||||
import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.getNetworkModePreferenceType;
|
||||
import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.setAllowedNetworkTypes;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.PersistableBundle;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
@@ -44,6 +46,7 @@ import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.telephony.flags.Flags;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.network.AllowedNetworkTypesListener;
|
||||
import com.android.settings.network.CarrierConfigCache;
|
||||
import com.android.settings.network.SubscriptionsChangeListener;
|
||||
@@ -61,16 +64,17 @@ import java.util.stream.Stream;
|
||||
* Preference controller for "Enabled network mode"
|
||||
*/
|
||||
public class EnabledNetworkModePreferenceController extends
|
||||
TelephonyBasePreferenceController implements
|
||||
BasePreferenceController implements
|
||||
ListPreference.OnPreferenceChangeListener, LifecycleObserver,
|
||||
SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
|
||||
|
||||
private static final String LOG_TAG = "EnabledNetworkMode";
|
||||
|
||||
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
private AllowedNetworkTypesListener mAllowedNetworkTypesListener;
|
||||
private Preference mPreference;
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
private TelephonyManager mTelephonyManager;
|
||||
private CarrierConfigCache mCarrierConfigCache;
|
||||
private PreferenceEntriesBuilder mBuilder;
|
||||
private SubscriptionsChangeListener mSubscriptionsListener;
|
||||
private int mCallState = TelephonyManager.CALL_STATE_IDLE;
|
||||
@@ -81,36 +85,16 @@ public class EnabledNetworkModePreferenceController extends
|
||||
public EnabledNetworkModePreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mSubscriptionsListener = new SubscriptionsChangeListener(context, this);
|
||||
mCarrierConfigCache = CarrierConfigCache.getInstance(context);
|
||||
if (mTelephonyCallback == null) {
|
||||
mTelephonyCallback = new PhoneCallStateTelephonyCallback();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus(int subId) {
|
||||
boolean visible;
|
||||
|
||||
final PersistableBundle carrierConfig = mCarrierConfigCache.getConfigForSubId(subId);
|
||||
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
visible = false;
|
||||
} else if (carrierConfig == null
|
||||
|| !CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
|
||||
visible = false;
|
||||
} else if (carrierConfig.getBoolean(
|
||||
CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL)
|
||||
|| carrierConfig.getBoolean(
|
||||
CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL)) {
|
||||
visible = false;
|
||||
} else if (carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) {
|
||||
visible = false;
|
||||
} else if (!isCallStateIdle()) {
|
||||
return AVAILABLE_UNSEARCHABLE;
|
||||
} else {
|
||||
visible = true;
|
||||
}
|
||||
|
||||
return visible ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
public int getAvailabilityStatus() {
|
||||
return getNetworkModePreferenceType(mContext, mSubId)
|
||||
== NetworkModePreferenceType.EnabledNetworkMode
|
||||
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
protected boolean isCallStateIdle() {
|
||||
@@ -953,9 +937,14 @@ public class EnabledNetworkModePreferenceController extends
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resources associated with Subscription.
|
||||
*
|
||||
* @return Resources associated with Subscription.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
PhoneCallStateTelephonyCallback getTelephonyCallback() {
|
||||
return mTelephonyCallback;
|
||||
Resources getResourcesForSubId() {
|
||||
return SubscriptionManager.getResourcesForSubId(mContext, mSubId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -16,9 +16,15 @@
|
||||
|
||||
package com.android.settings.network.telephony
|
||||
|
||||
import android.content.Context
|
||||
import android.telephony.CarrierConfigManager
|
||||
import android.telephony.SubscriptionManager
|
||||
import android.telephony.TelephonyManager
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.android.settings.R
|
||||
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
|
||||
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchResult
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -33,3 +39,62 @@ fun TelephonyManager.setAllowedNetworkTypes(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
enum class NetworkModePreferenceType {
|
||||
EnabledNetworkMode,
|
||||
PreferredNetworkMode,
|
||||
None,
|
||||
}
|
||||
|
||||
fun getNetworkModePreferenceType(context: Context, subId: Int): NetworkModePreferenceType {
|
||||
if (!SubscriptionManager.isValidSubscriptionId(subId)) return NetworkModePreferenceType.None
|
||||
data class Config(
|
||||
val carrierConfigApplied: Boolean,
|
||||
val hideCarrierNetworkSettings: Boolean,
|
||||
val hidePreferredNetworkType: Boolean,
|
||||
val worldPhone: Boolean,
|
||||
)
|
||||
|
||||
val config =
|
||||
CarrierConfigRepository(context).transformConfig(subId) {
|
||||
Config(
|
||||
carrierConfigApplied =
|
||||
getBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL),
|
||||
hideCarrierNetworkSettings =
|
||||
getBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL),
|
||||
hidePreferredNetworkType =
|
||||
getBoolean(CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL),
|
||||
worldPhone = getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL),
|
||||
)
|
||||
}
|
||||
|
||||
return when {
|
||||
!config.carrierConfigApplied ||
|
||||
config.hideCarrierNetworkSettings ||
|
||||
config.hidePreferredNetworkType -> NetworkModePreferenceType.None
|
||||
config.worldPhone -> NetworkModePreferenceType.PreferredNetworkMode
|
||||
else -> NetworkModePreferenceType.EnabledNetworkMode
|
||||
}
|
||||
}
|
||||
|
||||
class PreferredNetworkModeSearchItem(private val context: Context) :
|
||||
MobileNetworkSettingsSearchItem {
|
||||
private val title: String = context.getString(R.string.preferred_network_mode_title)
|
||||
|
||||
override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? =
|
||||
when (getNetworkModePreferenceType(context, subId)) {
|
||||
NetworkModePreferenceType.PreferredNetworkMode ->
|
||||
MobileNetworkSettingsSearchResult(
|
||||
key = "preferred_network_mode_key",
|
||||
title = title,
|
||||
)
|
||||
|
||||
NetworkModePreferenceType.EnabledNetworkMode ->
|
||||
MobileNetworkSettingsSearchResult(
|
||||
key = "enabled_networks_key",
|
||||
title = title,
|
||||
)
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
@@ -20,11 +20,13 @@ import android.content.Context
|
||||
import android.telephony.SubscriptionManager
|
||||
import android.telephony.TelephonyManager
|
||||
import android.telephony.data.ApnSetting
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.preference.PreferenceScreen
|
||||
import com.android.settings.R
|
||||
import com.android.settings.Settings.MobileNetworkActivity.EXTRA_MMS_MESSAGE
|
||||
import com.android.settings.core.TogglePreferenceController
|
||||
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchResult
|
||||
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
|
||||
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
|
||||
import kotlinx.coroutines.flow.combine
|
||||
@@ -109,7 +111,7 @@ constructor(
|
||||
}
|
||||
|
||||
class MmsMessageSearchItem(
|
||||
context: Context,
|
||||
private val context: Context,
|
||||
private val getDefaultDataSubId: () -> Int = {
|
||||
SubscriptionManager.getDefaultDataSubscriptionId()
|
||||
},
|
||||
@@ -117,12 +119,18 @@ constructor(
|
||||
private var telephonyManager: TelephonyManager =
|
||||
context.getSystemService(TelephonyManager::class.java)!!
|
||||
|
||||
override val key: String = EXTRA_MMS_MESSAGE
|
||||
override val title: String = context.getString(R.string.mms_message_title)
|
||||
|
||||
override fun isAvailable(subId: Int): Boolean =
|
||||
@VisibleForTesting
|
||||
fun isAvailable(subId: Int): Boolean =
|
||||
getAvailabilityStatus(
|
||||
telephonyManager.createForSubscriptionId(subId), subId, getDefaultDataSubId)
|
||||
|
||||
override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? {
|
||||
if (!isAvailable(subId)) return null
|
||||
return MobileNetworkSettingsSearchResult(
|
||||
key = EXTRA_MMS_MESSAGE,
|
||||
title = context.getString(R.string.mms_message_title),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -39,15 +39,14 @@ class MobileNetworkSettingsSearchIndex(
|
||||
private val searchItemsFactory: (context: Context) -> List<MobileNetworkSettingsSearchItem> =
|
||||
::createSearchItems,
|
||||
) {
|
||||
data class MobileNetworkSettingsSearchResult(
|
||||
val key: String,
|
||||
val title: String,
|
||||
val keywords: String? = null,
|
||||
)
|
||||
|
||||
interface MobileNetworkSettingsSearchItem {
|
||||
val key: String
|
||||
|
||||
val title: String
|
||||
|
||||
val keywords: String?
|
||||
get() = null
|
||||
|
||||
fun isAvailable(subId: Int): Boolean
|
||||
fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult?
|
||||
}
|
||||
|
||||
fun createSearchIndexableData(): SearchIndexableData {
|
||||
@@ -71,13 +70,15 @@ class MobileNetworkSettingsSearchIndex(
|
||||
searchItem: MobileNetworkSettingsSearchItem,
|
||||
subInfos: List<SubscriptionInfo>
|
||||
): List<SearchIndexableRaw> =
|
||||
subInfos
|
||||
.filter { searchItem.isAvailable(it.subscriptionId) }
|
||||
.map { subInfo -> searchIndexableRaw(context, searchItem, subInfo) }
|
||||
subInfos.mapNotNull { subInfo ->
|
||||
searchItem.getSearchResult(subInfo.subscriptionId)?.let { searchResult ->
|
||||
searchIndexableRaw(context, searchResult, subInfo)
|
||||
}
|
||||
}
|
||||
|
||||
private fun searchIndexableRaw(
|
||||
context: Context,
|
||||
searchItem: MobileNetworkSettingsSearchItem,
|
||||
searchResult: MobileNetworkSettingsSearchResult,
|
||||
subInfo: SubscriptionInfo,
|
||||
): SearchIndexableRaw {
|
||||
val key =
|
||||
@@ -85,7 +86,7 @@ class MobileNetworkSettingsSearchIndex(
|
||||
.setFragment(
|
||||
SpaSearchLandingFragment.newBuilder()
|
||||
.setFragmentName(MobileNetworkSettings::class.java.name)
|
||||
.setPreferenceKey(searchItem.key)
|
||||
.setPreferenceKey(searchResult.key)
|
||||
.putArguments(
|
||||
Settings.EXTRA_SUB_ID,
|
||||
BundleValue.newBuilder().setIntValue(subInfo.subscriptionId).build()))
|
||||
@@ -94,8 +95,8 @@ class MobileNetworkSettingsSearchIndex(
|
||||
return createSearchIndexableRaw(
|
||||
context = context,
|
||||
spaSearchLandingKey = key,
|
||||
itemTitle = searchItem.title,
|
||||
keywords = searchItem.keywords,
|
||||
itemTitle = searchResult.title,
|
||||
keywords = searchResult.keywords,
|
||||
indexableClass = MobileNetworkSettings::class.java,
|
||||
pageTitle = "$simsTitle > ${subInfo.displayName}",
|
||||
)
|
||||
@@ -115,6 +116,7 @@ class MobileNetworkSettingsSearchIndex(
|
||||
listOf(
|
||||
MmsMessageSearchItem(context),
|
||||
NrAdvancedCallingSearchItem(context),
|
||||
PreferredNetworkModeSearchItem(context),
|
||||
RoamingSearchItem(context),
|
||||
WifiCallingSearchItem(context),
|
||||
)
|
||||
|
@@ -25,6 +25,7 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.android.settings.R
|
||||
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchResult
|
||||
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
|
||||
import com.android.settings.spa.preference.ComposePreferenceController
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreference
|
||||
@@ -79,12 +80,17 @@ class NrAdvancedCallingPreferenceController @JvmOverloads constructor(
|
||||
companion object {
|
||||
class NrAdvancedCallingSearchItem(private val context: Context) :
|
||||
MobileNetworkSettingsSearchItem {
|
||||
override val key = "nr_advanced_calling"
|
||||
override val title: String = context.getString(R.string.nr_advanced_calling_title)
|
||||
override val keywords: String = context.getString(R.string.keywords_nr_advanced_calling)
|
||||
|
||||
override fun isAvailable(subId: Int): Boolean =
|
||||
VoNrRepository(context, subId).isVoNrAvailable()
|
||||
fun isAvailable(subId: Int): Boolean = VoNrRepository(context, subId).isVoNrAvailable()
|
||||
|
||||
override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? {
|
||||
if (!isAvailable(subId)) return null
|
||||
return MobileNetworkSettingsSearchResult(
|
||||
key = "nr_advanced_calling",
|
||||
title = context.getString(R.string.nr_advanced_calling_title),
|
||||
keywords = context.getString(R.string.keywords_nr_advanced_calling),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.network.telephony;
|
||||
|
||||
import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.getNetworkModePreferenceType;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.PersistableBundle;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
@@ -27,16 +29,18 @@ import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.network.CarrierConfigCache;
|
||||
import com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants;
|
||||
|
||||
/**
|
||||
* Preference controller for "Preferred network mode"
|
||||
*/
|
||||
public class PreferredNetworkModePreferenceController extends TelephonyBasePreferenceController
|
||||
public class PreferredNetworkModePreferenceController extends BasePreferenceController
|
||||
implements ListPreference.OnPreferenceChangeListener {
|
||||
private static final String TAG = "PrefNetworkModeCtrl";
|
||||
|
||||
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
private CarrierConfigCache mCarrierConfigCache;
|
||||
private TelephonyManager mTelephonyManager;
|
||||
private boolean mIsGlobalCdma;
|
||||
@@ -47,25 +51,10 @@ public class PreferredNetworkModePreferenceController extends TelephonyBasePrefe
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus(int subId) {
|
||||
final PersistableBundle carrierConfig = mCarrierConfigCache.getConfigForSubId(subId);
|
||||
boolean visible;
|
||||
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
visible = false;
|
||||
} else if (carrierConfig == null) {
|
||||
visible = false;
|
||||
} else if (carrierConfig.getBoolean(
|
||||
CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL)
|
||||
|| carrierConfig.getBoolean(
|
||||
CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL)) {
|
||||
visible = false;
|
||||
} else if (carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) {
|
||||
visible = true;
|
||||
} else {
|
||||
visible = false;
|
||||
}
|
||||
|
||||
return visible ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
public int getAvailabilityStatus() {
|
||||
return getNetworkModePreferenceType(mContext, mSubId)
|
||||
== NetworkModePreferenceType.PreferredNetworkMode
|
||||
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -29,6 +29,7 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.android.settings.R
|
||||
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchResult
|
||||
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
|
||||
import com.android.settings.spa.preference.ComposePreferenceController
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
|
||||
@@ -98,16 +99,21 @@ constructor(
|
||||
companion object {
|
||||
private const val DIALOG_TAG = "MobileDataDialog"
|
||||
|
||||
class RoamingSearchItem(context: Context) : MobileNetworkSettingsSearchItem {
|
||||
override val key = "button_roaming_key"
|
||||
override val title: String = context.getString(R.string.roaming)
|
||||
|
||||
class RoamingSearchItem(private val context: Context) : MobileNetworkSettingsSearchItem {
|
||||
private val carrierConfigRepository = CarrierConfigRepository(context)
|
||||
|
||||
override fun isAvailable(subId: Int): Boolean =
|
||||
fun isAvailable(subId: Int): Boolean =
|
||||
SubscriptionManager.isValidSubscriptionId(subId) &&
|
||||
!carrierConfigRepository.getBoolean(
|
||||
subId, CarrierConfigManager.KEY_FORCE_HOME_NETWORK_BOOL)
|
||||
|
||||
override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? {
|
||||
if (!isAvailable(subId)) return null
|
||||
return MobileNetworkSettingsSearchResult(
|
||||
key = "button_roaming_key",
|
||||
title = context.getString(R.string.roaming),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -17,9 +17,6 @@
|
||||
package com.android.settings.network.telephony;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.PersistableBundle;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
@@ -59,29 +56,4 @@ public abstract class TelephonyBasePreferenceController extends BasePreferenceCo
|
||||
public void unsetAvailabilityStatus() {
|
||||
mSetSessionCount.getAndDecrement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get carrier config based on specific subscription id.
|
||||
*
|
||||
* @param subId is the subscription id
|
||||
* @return {@link PersistableBundle} of carrier config, or {@code null} when carrier config
|
||||
* is not available.
|
||||
*/
|
||||
public PersistableBundle getCarrierConfigForSubId(int subId) {
|
||||
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
|
||||
return null;
|
||||
}
|
||||
final CarrierConfigManager carrierConfigMgr =
|
||||
mContext.getSystemService(CarrierConfigManager.class);
|
||||
return carrierConfigMgr.getConfigForSubId(subId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resources associated with Subscription.
|
||||
*
|
||||
* @return Resources associated with Subscription.
|
||||
*/
|
||||
public Resources getResourcesForSubId() {
|
||||
return SubscriptionManager.getResourcesForSubId(mContext, mSubId);
|
||||
}
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@ import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import com.android.settings.R
|
||||
import com.android.settings.core.BasePreferenceController
|
||||
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchResult
|
||||
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
|
||||
import com.android.settings.network.telephony.wificalling.WifiCallingRepository
|
||||
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
|
||||
@@ -132,12 +133,17 @@ open class WifiCallingPreferenceController @JvmOverloads constructor(
|
||||
class WifiCallingSearchItem(
|
||||
private val context: Context,
|
||||
) : MobileNetworkSettingsSearchItem {
|
||||
override val key: String = "wifi_calling"
|
||||
override val title: String = context.getString(R.string.wifi_calling_settings_title)
|
||||
|
||||
override fun isAvailable(subId: Int): Boolean = runBlocking {
|
||||
private fun isAvailable(subId: Int): Boolean = runBlocking {
|
||||
WifiCallingRepository(context, subId).wifiCallingReadyFlow().first()
|
||||
}
|
||||
|
||||
override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? {
|
||||
if (!isAvailable(subId)) return null
|
||||
return MobileNetworkSettingsSearchResult(
|
||||
key = "wifi_calling",
|
||||
title = context.getString(R.string.wifi_calling_settings_title),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -124,9 +124,7 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo
|
||||
|
||||
@Override
|
||||
public void launchChooseLock(Bundle chooseLockFingerprintExtras) {
|
||||
final boolean isInSetupWizard = WizardManagerHelper.isAnySetupWizard(getIntent());
|
||||
Intent intent = isInSetupWizard ? new Intent(this, SetupChooseLockGeneric.class)
|
||||
: new Intent(this, ChooseLockGeneric.class);
|
||||
final Intent intent = new Intent(this, SetupChooseLockGeneric.class);
|
||||
intent.setAction(mNewPasswordAction);
|
||||
intent.putExtras(chooseLockFingerprintExtras);
|
||||
intent.putExtra(EXTRA_KEY_CHOOSE_LOCK_SCREEN_TITLE,
|
||||
|
@@ -919,7 +919,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
d = mCreateUserDialogController.createDialog(
|
||||
getActivity(),
|
||||
this::startActivityForResult,
|
||||
UserManager.isMultipleAdminEnabled(),
|
||||
canCreateAdminUser(),
|
||||
(userName, userIcon, isAdmin) -> {
|
||||
mPendingUserIcon = userIcon;
|
||||
mPendingUserName = userName;
|
||||
@@ -937,6 +937,19 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the creation of a new admin user is allowed.
|
||||
* @return {@code true} if creating a new admin is allowed, {@code false} otherwise.
|
||||
*/
|
||||
private boolean canCreateAdminUser() {
|
||||
if (Flags.unicornModeRefactoringForHsumReadOnly()) {
|
||||
return UserManager.isMultipleAdminEnabled()
|
||||
&& !mUserManager.hasUserRestriction(UserManager.DISALLOW_GRANT_ADMIN);
|
||||
} else {
|
||||
return UserManager.isMultipleAdminEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDialogMetricsCategory(int dialogId) {
|
||||
switch (dialogId) {
|
||||
|
@@ -46,6 +46,7 @@ import android.util.Log;
|
||||
*
|
||||
*/
|
||||
public class WifiQrCode {
|
||||
private static final String TAG = "WifiQrCode";
|
||||
static final String SCHEME_DPP = "DPP";
|
||||
static final String SCHEME_ZXING_WIFI_NETWORK_CONFIG = "WIFI";
|
||||
static final String PREFIX_DPP = "DPP:";
|
||||
@@ -119,13 +120,13 @@ public class WifiQrCode {
|
||||
try {
|
||||
wifiQrCode = new WifiQrCode(qrCode);
|
||||
} catch(IllegalArgumentException e) {
|
||||
Log.e(TAG, "Failed to create WifiQrCode!", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (SCHEME_DPP.equals(wifiQrCode.getScheme())) {
|
||||
return wifiQrCode;
|
||||
if (wifiQrCode.getScheme() != UriParserResults.URI_SCHEME_DPP) {
|
||||
Log.e(TAG, "wifiQrCode scheme is not DPP!");
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
return wifiQrCode;
|
||||
}
|
||||
}
|
||||
|
@@ -18,10 +18,10 @@ package com.android.settings.bluetooth;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -32,22 +32,31 @@ import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.UserManager;
|
||||
import android.util.Pair;
|
||||
import android.view.ContextThemeWrapper;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@@ -57,18 +66,21 @@ import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowAlertDialogCompat.class})
|
||||
@Config(shadows = {ShadowAlertDialogCompat.class,
|
||||
com.android.settings.testutils.shadow.ShadowBluetoothUtils.class})
|
||||
public class BluetoothDevicePreferenceTest {
|
||||
private static final boolean SHOW_DEVICES_WITHOUT_NAMES = true;
|
||||
private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
|
||||
private static final String MAC_ADDRESS_2 = "05:52:C7:0B:D8:3C";
|
||||
private static final String MAC_ADDRESS_3 = "06:52:C7:0B:D8:3C";
|
||||
private static final String MAC_ADDRESS_4 = "07:52:C7:0B:D8:3C";
|
||||
private static final String TEST_MAC_ADDRESS = "04:52:C7:0B:D8:3C";
|
||||
private static final String TEST_MAC_ADDRESS_1 = "05:52:C7:0B:D8:3C";
|
||||
private static final String TEST_MAC_ADDRESS_2 = "06:52:C7:0B:D8:3C";
|
||||
private static final String TEST_MAC_ADDRESS_3 = "07:52:C7:0B:D8:3C";
|
||||
private static final Comparator<BluetoothDevicePreference> COMPARATOR =
|
||||
Comparator.naturalOrder();
|
||||
private static final String FAKE_DESCRIPTION = "fake_description";
|
||||
private static final int TEST_DEVICE_GROUP_ID = 1;
|
||||
|
||||
private Context mContext;
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@Mock
|
||||
private CachedBluetoothDevice mCachedBluetoothDevice;
|
||||
@Mock
|
||||
@@ -89,35 +101,37 @@ public class BluetoothDevicePreferenceTest {
|
||||
private Drawable mDrawable;
|
||||
@Mock
|
||||
private BluetoothAdapter mBluetoothAdapter;
|
||||
@Mock
|
||||
private LocalBluetoothManager mLocalBluetoothManager;
|
||||
@Mock
|
||||
private CachedBluetoothDeviceManager mDeviceManager;
|
||||
|
||||
private Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private FakeFeatureFactory mFakeFeatureFactory;
|
||||
private MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
|
||||
private BluetoothDevicePreference mPreference;
|
||||
private List<BluetoothDevicePreference> mPreferenceList = new ArrayList<>();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
Context context = spy(RuntimeEnvironment.application.getApplicationContext());
|
||||
mContext = new ContextThemeWrapper(context, R.style.Theme_Settings);
|
||||
mContext.setTheme(R.style.Theme_Settings);
|
||||
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mMetricsFeatureProvider = mFakeFeatureFactory.getMetricsFeatureProvider();
|
||||
when(mCachedBluetoothDevice.getAddress()).thenReturn(MAC_ADDRESS);
|
||||
when(mCachedBluetoothDevice.getDrawableWithDescription())
|
||||
.thenReturn(new Pair<>(mDrawable, FAKE_DESCRIPTION));
|
||||
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
|
||||
when(mCachedDevice1.getAddress()).thenReturn(MAC_ADDRESS_2);
|
||||
when(mCachedDevice1.getDrawableWithDescription())
|
||||
.thenReturn(new Pair<>(mDrawable, FAKE_DESCRIPTION));
|
||||
when(mCachedDevice1.getDevice()).thenReturn(mBluetoothDevice1);
|
||||
when(mCachedDevice2.getAddress()).thenReturn(MAC_ADDRESS_3);
|
||||
when(mCachedDevice2.getDrawableWithDescription())
|
||||
.thenReturn(new Pair<>(mDrawable, FAKE_DESCRIPTION));
|
||||
when(mCachedDevice2.getDevice()).thenReturn(mBluetoothDevice2);
|
||||
when(mCachedDevice3.getAddress()).thenReturn(MAC_ADDRESS_4);
|
||||
when(mCachedDevice3.getDrawableWithDescription())
|
||||
.thenReturn(new Pair<>(mDrawable, FAKE_DESCRIPTION));
|
||||
when(mCachedDevice3.getDevice()).thenReturn(mBluetoothDevice3);
|
||||
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
|
||||
mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
|
||||
when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
|
||||
prepareCachedBluetoothDevice(mCachedBluetoothDevice, TEST_MAC_ADDRESS,
|
||||
new Pair<>(mDrawable, FAKE_DESCRIPTION), TEST_DEVICE_GROUP_ID, mBluetoothDevice);
|
||||
prepareCachedBluetoothDevice(mCachedDevice1, TEST_MAC_ADDRESS_1,
|
||||
new Pair<>(mDrawable, FAKE_DESCRIPTION), TEST_DEVICE_GROUP_ID, mBluetoothDevice1);
|
||||
prepareCachedBluetoothDevice(mCachedDevice2, TEST_MAC_ADDRESS_2,
|
||||
new Pair<>(mDrawable, FAKE_DESCRIPTION), TEST_DEVICE_GROUP_ID, mBluetoothDevice2);
|
||||
prepareCachedBluetoothDevice(mCachedDevice3, TEST_MAC_ADDRESS_3,
|
||||
new Pair<>(mDrawable, FAKE_DESCRIPTION), TEST_DEVICE_GROUP_ID, mBluetoothDevice3);
|
||||
when(mDeviceManager.getCachedDevicesCopy()).thenReturn(
|
||||
ImmutableList.of(mCachedBluetoothDevice));
|
||||
|
||||
mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
|
||||
SHOW_DEVICES_WITHOUT_NAMES, BluetoothDevicePreference.SortType.TYPE_DEFAULT);
|
||||
mPreference.mBluetoothAdapter = mBluetoothAdapter;
|
||||
@@ -301,7 +315,8 @@ public class BluetoothDevicePreferenceTest {
|
||||
// callback is not removed.
|
||||
mPreference.onAttached();
|
||||
|
||||
verify(mCachedBluetoothDevice, times(1)).registerCallback(any());
|
||||
verify(mCachedBluetoothDevice, times(1)).registerCallback(eq(mContext.getMainExecutor()),
|
||||
any());
|
||||
verify(mBluetoothAdapter, times(1)).addOnMetadataChangedListener(any(), any(), any());
|
||||
}
|
||||
|
||||
@@ -313,7 +328,99 @@ public class BluetoothDevicePreferenceTest {
|
||||
mPreference.onAttached();
|
||||
|
||||
verify(mCachedBluetoothDevice, times(1)).unregisterCallback(any());
|
||||
verify(mCachedBluetoothDevice, times(2)).registerCallback(any());
|
||||
verify(mCachedBluetoothDevice, times(2)).registerCallback(eq(mContext.getMainExecutor()),
|
||||
any());
|
||||
verify(mBluetoothAdapter, times(2)).addOnMetadataChangedListener(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceAttributesChanged_updatePreference() {
|
||||
when(mCachedBluetoothDevice.getName()).thenReturn("Name");
|
||||
mPreference.onAttached();
|
||||
final String updatedName = "updatedName";
|
||||
when(mCachedBluetoothDevice.getName()).thenReturn(updatedName);
|
||||
|
||||
getCachedBluetoothDeviceCallback().onDeviceAttributesChanged();
|
||||
|
||||
assertThat(mPreference.getTitle().toString()).isEqualTo(updatedName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAttached_memberDevicesAdded_registerAllCallback() {
|
||||
when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(
|
||||
ImmutableSet.of(mCachedDevice1, mCachedDevice2, mCachedDevice3));
|
||||
when(mDeviceManager.getCachedDevicesCopy()).thenReturn(
|
||||
ImmutableList.of(mCachedBluetoothDevice, mCachedDevice1, mCachedDevice2,
|
||||
mCachedDevice3));
|
||||
mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
|
||||
SHOW_DEVICES_WITHOUT_NAMES, BluetoothDevicePreference.SortType.TYPE_DEFAULT);
|
||||
|
||||
mPreference.onAttached();
|
||||
|
||||
verify(mCachedBluetoothDevice).registerCallback(eq(mContext.getMainExecutor()), any());
|
||||
verify(mCachedDevice1).registerCallback(eq(mContext.getMainExecutor()), any());
|
||||
verify(mCachedDevice2).registerCallback(eq(mContext.getMainExecutor()), any());
|
||||
verify(mCachedDevice3).registerCallback(eq(mContext.getMainExecutor()), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDetached_memberDevicesAdded_unregisterAllCallback() {
|
||||
when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(
|
||||
ImmutableSet.of(mCachedDevice1, mCachedDevice2, mCachedDevice3));
|
||||
when(mDeviceManager.getCachedDevicesCopy()).thenReturn(
|
||||
ImmutableList.of(mCachedBluetoothDevice, mCachedDevice1, mCachedDevice2,
|
||||
mCachedDevice3));
|
||||
mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
|
||||
SHOW_DEVICES_WITHOUT_NAMES, BluetoothDevicePreference.SortType.TYPE_DEFAULT);
|
||||
|
||||
mPreference.onAttached();
|
||||
mPreference.onDetached();
|
||||
|
||||
verify(mCachedBluetoothDevice).unregisterCallback(any());
|
||||
verify(mCachedDevice1).unregisterCallback(any());
|
||||
verify(mCachedDevice2).unregisterCallback(any());
|
||||
verify(mCachedDevice3).unregisterCallback(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceAttributesChanged_memberDevicesChanged_registerOnlyExistDeviceCallback() {
|
||||
when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(
|
||||
ImmutableSet.of(mCachedDevice1, mCachedDevice2, mCachedDevice3));
|
||||
when(mDeviceManager.getCachedDevicesCopy()).thenReturn(
|
||||
ImmutableList.of(mCachedBluetoothDevice, mCachedDevice1, mCachedDevice2,
|
||||
mCachedDevice3));
|
||||
mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
|
||||
SHOW_DEVICES_WITHOUT_NAMES, BluetoothDevicePreference.SortType.TYPE_DEFAULT);
|
||||
mPreference.onAttached();
|
||||
when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(
|
||||
ImmutableSet.of(mCachedDevice1, mCachedDevice2));
|
||||
when(mDeviceManager.getCachedDevicesCopy()).thenReturn(
|
||||
ImmutableList.of(mCachedBluetoothDevice, mCachedDevice1, mCachedDevice2));
|
||||
|
||||
getCachedBluetoothDeviceCallback().onDeviceAttributesChanged();
|
||||
|
||||
verify(mCachedBluetoothDevice, times(2)).registerCallback(eq(mContext.getMainExecutor()),
|
||||
any());
|
||||
verify(mCachedDevice1, times(2)).registerCallback(eq(mContext.getMainExecutor()), any());
|
||||
verify(mCachedDevice2, times(2)).registerCallback(eq(mContext.getMainExecutor()), any());
|
||||
verify(mCachedDevice3, times(1)).registerCallback(eq(mContext.getMainExecutor()), any());
|
||||
}
|
||||
|
||||
private void prepareCachedBluetoothDevice(CachedBluetoothDevice cachedDevice, String address,
|
||||
Pair<Drawable, String> drawableWithDescription, int groupId,
|
||||
BluetoothDevice bluetoothDevice) {
|
||||
when(cachedDevice.getAddress()).thenReturn(address);
|
||||
when(cachedDevice.getDrawableWithDescription()).thenReturn(drawableWithDescription);
|
||||
when(cachedDevice.getGroupId()).thenReturn(groupId);
|
||||
when(cachedDevice.getDevice()).thenReturn(bluetoothDevice);
|
||||
}
|
||||
|
||||
private CachedBluetoothDevice.Callback getCachedBluetoothDeviceCallback() {
|
||||
ArgumentCaptor<CachedBluetoothDevice.Callback> callbackCaptor = ArgumentCaptor.forClass(
|
||||
CachedBluetoothDevice.Callback.class);
|
||||
verify(mCachedBluetoothDevice).registerCallback(eq(mContext.getMainExecutor()),
|
||||
callbackCaptor.capture());
|
||||
|
||||
return callbackCaptor.getValue();
|
||||
}
|
||||
}
|
||||
|
@@ -93,7 +93,6 @@ public class AudioSharingDialogFragmentTest {
|
||||
new Pair[] {TEST_EVENT_DATA};
|
||||
|
||||
private Fragment mParent;
|
||||
private AudioSharingDialogFragment mFragment;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
|
||||
@Before
|
||||
@@ -107,7 +106,6 @@ public class AudioSharingDialogFragmentTest {
|
||||
shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
|
||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mFragment = new AudioSharingDialogFragment();
|
||||
mParent = new Fragment();
|
||||
FragmentController.setupFragment(
|
||||
mParent, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
|
||||
@@ -120,7 +118,8 @@ public class AudioSharingDialogFragmentTest {
|
||||
|
||||
@Test
|
||||
public void getMetricsCategory_correctValue() {
|
||||
assertThat(mFragment.getMetricsCategory())
|
||||
AudioSharingDialogFragment fragment = new AudioSharingDialogFragment();
|
||||
assertThat(fragment.getMetricsCategory())
|
||||
.isEqualTo(SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE);
|
||||
}
|
||||
|
||||
@@ -145,7 +144,7 @@ public class AudioSharingDialogFragmentTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreateDialog_flagOn_noConnectedDevice() {
|
||||
public void onCreateDialog_flagOn_noExtraConnectedDevice() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
AudioSharingDialogFragment.show(
|
||||
mParent, new ArrayList<>(), EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
|
||||
@@ -157,42 +156,67 @@ public class AudioSharingDialogFragmentTest {
|
||||
assertThat(description).isNotNull();
|
||||
ImageView image = dialog.findViewById(R.id.description_image);
|
||||
assertThat(image).isNotNull();
|
||||
Button shareBtn = dialog.findViewById(R.id.positive_btn);
|
||||
assertThat(shareBtn).isNotNull();
|
||||
Button cancelBtn = dialog.findViewById(R.id.negative_btn);
|
||||
assertThat(cancelBtn).isNotNull();
|
||||
Button positiveBtn = dialog.findViewById(R.id.positive_btn);
|
||||
assertThat(positiveBtn).isNotNull();
|
||||
Button negativeBtn = dialog.findViewById(R.id.negative_btn);
|
||||
assertThat(negativeBtn).isNotNull();
|
||||
assertThat(dialog.isShowing()).isTrue();
|
||||
assertThat(description.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(description.getText().toString())
|
||||
.isEqualTo(mParent.getString(R.string.audio_sharing_dialog_connect_device_content));
|
||||
assertThat(image.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(shareBtn.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(cancelBtn.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(positiveBtn.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(positiveBtn.getText().toString())
|
||||
.isEqualTo(mParent.getString(R.string.audio_sharing_pair_button_label));
|
||||
assertThat(negativeBtn.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(negativeBtn.getText().toString())
|
||||
.isEqualTo(mParent.getString(R.string.audio_sharing_qrcode_button_label));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreateDialog_noConnectedDevice_dialogDismiss() {
|
||||
public void onCreateDialog_noExtraConnectedDevice_pairNewDevice() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
AudioSharingDialogFragment.show(
|
||||
mParent, new ArrayList<>(), EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
|
||||
shadowMainLooper().idle();
|
||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
View btnView = dialog.findViewById(android.R.id.button2);
|
||||
assertThat(btnView).isNotNull();
|
||||
btnView.performClick();
|
||||
Button pairBtn = dialog.findViewById(R.id.positive_btn);
|
||||
assertThat(pairBtn).isNotNull();
|
||||
pairBtn.performClick();
|
||||
shadowMainLooper().idle();
|
||||
|
||||
verify(mFeatureFactory.metricsFeatureProvider)
|
||||
.action(
|
||||
any(Context.class),
|
||||
eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED),
|
||||
eq(TEST_EVENT_DATA));
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreateDialog_noExtraConnectedDevice_showQRCode() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
AudioSharingDialogFragment.show(
|
||||
mParent, new ArrayList<>(), EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
|
||||
shadowMainLooper().idle();
|
||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
Button qrCodeBtn = dialog.findViewById(R.id.negative_btn);
|
||||
assertThat(qrCodeBtn).isNotNull();
|
||||
qrCodeBtn.performClick();
|
||||
shadowMainLooper().idle();
|
||||
|
||||
verify(mFeatureFactory.metricsFeatureProvider)
|
||||
.action(
|
||||
any(Context.class),
|
||||
eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED),
|
||||
eq(TEST_EVENT_DATA));
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreateDialog_flagOn_singleConnectedDevice() {
|
||||
public void onCreateDialog_flagOn_singleExtraConnectedDevice() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
|
||||
list.add(TEST_DEVICE_ITEM1);
|
||||
@@ -207,10 +231,10 @@ public class AudioSharingDialogFragmentTest {
|
||||
assertThat(description).isNotNull();
|
||||
ImageView image = dialog.findViewById(R.id.description_image);
|
||||
assertThat(image).isNotNull();
|
||||
Button shareBtn = dialog.findViewById(R.id.positive_btn);
|
||||
assertThat(shareBtn).isNotNull();
|
||||
Button cancelBtn = dialog.findViewById(R.id.negative_btn);
|
||||
assertThat(cancelBtn).isNotNull();
|
||||
Button positiveBtn = dialog.findViewById(R.id.positive_btn);
|
||||
assertThat(positiveBtn).isNotNull();
|
||||
Button negativeBtn = dialog.findViewById(R.id.negative_btn);
|
||||
assertThat(negativeBtn).isNotNull();
|
||||
assertThat(dialog.isShowing()).isTrue();
|
||||
assertThat(title.getText().toString())
|
||||
.isEqualTo(
|
||||
@@ -220,12 +244,16 @@ public class AudioSharingDialogFragmentTest {
|
||||
assertThat(description.getText().toString())
|
||||
.isEqualTo(mParent.getString(R.string.audio_sharing_dialog_share_content));
|
||||
assertThat(image.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(shareBtn.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(cancelBtn.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(positiveBtn.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(positiveBtn.getText().toString())
|
||||
.isEqualTo(mParent.getString(R.string.audio_sharing_share_button_label));
|
||||
assertThat(negativeBtn.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(negativeBtn.getText().toString())
|
||||
.isEqualTo(mParent.getString(R.string.audio_sharing_no_thanks_button_label));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreateDialog_singleConnectedDevice_dialogDismiss() {
|
||||
public void onCreateDialog_singleExtraConnectedDevice_dialogDismiss() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
|
||||
list.add(TEST_DEVICE_ITEM1);
|
||||
@@ -248,7 +276,7 @@ public class AudioSharingDialogFragmentTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreateDialog_singleConnectedDevice_shareClicked() {
|
||||
public void onCreateDialog_singleExtraConnectedDevice_shareClicked() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
|
||||
list.add(TEST_DEVICE_ITEM1);
|
||||
@@ -285,7 +313,7 @@ public class AudioSharingDialogFragmentTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreateDialog_flagOn_multipleConnectedDevice() {
|
||||
public void onCreateDialog_flagOn_multipleExtraConnectedDevice() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
|
||||
list.add(TEST_DEVICE_ITEM1);
|
||||
@@ -313,12 +341,14 @@ public class AudioSharingDialogFragmentTest {
|
||||
assertThat(image.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(shareBtn.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(cancelBtn.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(cancelBtn.getText().toString())
|
||||
.isEqualTo(mParent.getString(com.android.settings.R.string.cancel));
|
||||
assertThat(recyclerView.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(recyclerView.getAdapter().getItemCount()).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreateDialog_multipleConnectedDevice_dialogDismiss() {
|
||||
public void onCreateDialog_multipleExtraConnectedDevice_dialogDismiss() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
|
||||
list.add(TEST_DEVICE_ITEM1);
|
||||
|
@@ -25,7 +25,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -164,8 +164,7 @@ public class AudioSharingReceiverTest {
|
||||
AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent);
|
||||
audioSharingReceiver.onReceive(mContext, intent);
|
||||
|
||||
verify(mNm, times(1))
|
||||
.notify(eq(R.drawable.ic_bt_le_audio_sharing), any(Notification.class));
|
||||
verify(mNm).notify(eq(R.drawable.ic_bt_le_audio_sharing), any(Notification.class));
|
||||
verify(mFeatureFactory.metricsFeatureProvider)
|
||||
.action(mContext, SettingsEnums.ACTION_SHOW_AUDIO_SHARING_NOTIFICATION);
|
||||
}
|
||||
@@ -181,7 +180,7 @@ public class AudioSharingReceiverTest {
|
||||
AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent);
|
||||
audioSharingReceiver.onReceive(mContext, intent);
|
||||
|
||||
verify(mNm, times(1)).cancel(R.drawable.ic_bt_le_audio_sharing);
|
||||
verify(mNm).cancel(R.drawable.ic_bt_le_audio_sharing);
|
||||
verify(mFeatureFactory.metricsFeatureProvider)
|
||||
.action(mContext, SettingsEnums.ACTION_CANCEL_AUDIO_SHARING_NOTIFICATION);
|
||||
}
|
||||
@@ -199,8 +198,10 @@ public class AudioSharingReceiverTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void broadcastReceiver_receiveAudioSharingStopIntent_stopBroadcast() {
|
||||
public void
|
||||
broadcastReceiver_receiveAudioSharingStopIntent_notInBroadcast_cancelNotification() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
when(mBroadcast.isEnabled(null)).thenReturn(false);
|
||||
int broadcastId = 1;
|
||||
when(mBroadcast.getLatestBroadcastId()).thenReturn(broadcastId);
|
||||
|
||||
@@ -209,7 +210,25 @@ public class AudioSharingReceiverTest {
|
||||
AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent);
|
||||
audioSharingReceiver.onReceive(mContext, intent);
|
||||
|
||||
verify(mBroadcast, times(1)).stopBroadcast(broadcastId);
|
||||
verify(mBroadcast, never()).stopBroadcast(broadcastId);
|
||||
verify(mNm).cancel(R.drawable.ic_bt_le_audio_sharing);
|
||||
verify(mFeatureFactory.metricsFeatureProvider)
|
||||
.action(mContext, SettingsEnums.ACTION_CANCEL_AUDIO_SHARING_NOTIFICATION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void broadcastReceiver_receiveAudioSharingStopIntent_inBroadcast_stopBroadcast() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
when(mBroadcast.isEnabled(null)).thenReturn(true);
|
||||
int broadcastId = 1;
|
||||
when(mBroadcast.getLatestBroadcastId()).thenReturn(broadcastId);
|
||||
|
||||
Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_STOP);
|
||||
intent.setPackage(mContext.getPackageName());
|
||||
AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent);
|
||||
audioSharingReceiver.onReceive(mContext, intent);
|
||||
|
||||
verify(mBroadcast).stopBroadcast(broadcastId);
|
||||
verify(mFeatureFactory.metricsFeatureProvider)
|
||||
.action(mContext, SettingsEnums.ACTION_STOP_AUDIO_SHARING_FROM_NOTIFICATION);
|
||||
}
|
||||
|
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.network.telephony
|
||||
|
||||
import android.content.Context
|
||||
import android.telephony.CarrierConfigManager
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.spy
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class EnabledNetworkModePreferenceControllerHelperTest {
|
||||
|
||||
private var context: Context = spy(ApplicationProvider.getApplicationContext()) {}
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
CarrierConfigRepository.resetForTest()
|
||||
CarrierConfigRepository.setBooleanForTest(
|
||||
SUB_ID, CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNetworkModePreferenceType_hideCarrierNetworkSettings_returnNone() {
|
||||
CarrierConfigRepository.setBooleanForTest(
|
||||
SUB_ID, CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL, true)
|
||||
|
||||
val networkModePreferenceType = getNetworkModePreferenceType(context, SUB_ID)
|
||||
|
||||
assertThat(networkModePreferenceType).isEqualTo(NetworkModePreferenceType.None)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNetworkModePreferenceType_hidePreferredNetworkType_returnNone() {
|
||||
CarrierConfigRepository.setBooleanForTest(
|
||||
SUB_ID, CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL, true)
|
||||
|
||||
val networkModePreferenceType = getNetworkModePreferenceType(context, SUB_ID)
|
||||
|
||||
assertThat(networkModePreferenceType).isEqualTo(NetworkModePreferenceType.None)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNetworkModePreferenceType_carrierConfigNotReady_returnNone() {
|
||||
CarrierConfigRepository.setBooleanForTest(
|
||||
SUB_ID, CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, false)
|
||||
|
||||
val networkModePreferenceType = getNetworkModePreferenceType(context, SUB_ID)
|
||||
|
||||
assertThat(networkModePreferenceType).isEqualTo(NetworkModePreferenceType.None)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNetworkModePreferenceType_isWorldPhone_returnPreferredNetworkMode() {
|
||||
CarrierConfigRepository.setBooleanForTest(
|
||||
SUB_ID, CarrierConfigManager.KEY_WORLD_PHONE_BOOL, true)
|
||||
|
||||
val networkModePreferenceType = getNetworkModePreferenceType(context, SUB_ID)
|
||||
|
||||
assertThat(networkModePreferenceType)
|
||||
.isEqualTo(NetworkModePreferenceType.PreferredNetworkMode)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNetworkModePreferenceType_notWorldPhone_returnEnabledNetworkMode() {
|
||||
CarrierConfigRepository.setBooleanForTest(
|
||||
SUB_ID, CarrierConfigManager.KEY_WORLD_PHONE_BOOL, false)
|
||||
|
||||
val networkModePreferenceType = getNetworkModePreferenceType(context, SUB_ID)
|
||||
|
||||
assertThat(networkModePreferenceType)
|
||||
.isEqualTo(NetworkModePreferenceType.EnabledNetworkMode)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val SUB_ID = 10
|
||||
}
|
||||
}
|
@@ -25,6 +25,7 @@ import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.R
|
||||
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.Companion.isMobileNetworkSettingsSearchable
|
||||
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchResult
|
||||
import com.android.settings.spa.SpaSearchLanding.BundleValue
|
||||
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingFragment
|
||||
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
|
||||
@@ -62,10 +63,12 @@ class MobileNetworkSettingsSearchIndexTest {
|
||||
private val mobileNetworkSettingsSearchIndex = MobileNetworkSettingsSearchIndex {
|
||||
listOf(
|
||||
object : MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem {
|
||||
override val key = KEY
|
||||
override val title = TITLE
|
||||
|
||||
override fun isAvailable(subId: Int) = subId == SUB_ID_1
|
||||
override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? =
|
||||
if (subId == SUB_ID_1) {
|
||||
MobileNetworkSettingsSearchResult(key = KEY, title = TITLE)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@@ -20,8 +20,8 @@ import android.content.Context
|
||||
import android.content.pm.ApplicationInfo
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.assertIsNotEnabled
|
||||
import androidx.compose.ui.test.hasText
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.onRoot
|
||||
@@ -34,36 +34,35 @@ import com.android.settings.applications.appinfo.AppInfoDashboardFragment
|
||||
import com.android.settings.notification.app.AppNotificationSettings
|
||||
import com.android.settings.spa.notification.IAppNotificationRepository
|
||||
import com.android.settingslib.spa.testutils.delay
|
||||
import com.android.settingslib.spa.testutils.waitUntilExists
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.MockitoSession
|
||||
import org.mockito.Spy
|
||||
import org.mockito.quality.Strictness
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class AppNotificationPreferenceTest {
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
@get:Rule val composeTestRule = createComposeRule()
|
||||
|
||||
private lateinit var mockSession: MockitoSession
|
||||
|
||||
@Spy
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
|
||||
private val repository = object : IAppNotificationRepository {
|
||||
override fun getNotificationSummary(app: ApplicationInfo) = SUMMARY
|
||||
}
|
||||
private val repository =
|
||||
object : IAppNotificationRepository {
|
||||
override fun getNotificationSummary(app: ApplicationInfo) = SUMMARY
|
||||
}
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mockSession = ExtendedMockito.mockitoSession()
|
||||
.initMocks(this)
|
||||
.mockStatic(AppInfoDashboardFragment::class.java)
|
||||
.strictness(Strictness.LENIENT)
|
||||
.startMocking()
|
||||
mockSession =
|
||||
ExtendedMockito.mockitoSession()
|
||||
.mockStatic(AppInfoDashboardFragment::class.java)
|
||||
.strictness(Strictness.LENIENT)
|
||||
.startMocking()
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -75,25 +74,26 @@ class AppNotificationPreferenceTest {
|
||||
fun title_displayed() {
|
||||
setContent(APP)
|
||||
|
||||
composeTestRule.onNodeWithText(context.getString(R.string.notifications_label))
|
||||
.assertIsDisplayed()
|
||||
composeTestRule.waitUntilExists(hasText(context.getString(R.string.notifications_label)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun summary_displayed() {
|
||||
setContent(APP)
|
||||
|
||||
composeTestRule.onNodeWithText(SUMMARY).assertIsDisplayed()
|
||||
composeTestRule.waitUntilExists(hasText(SUMMARY))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenNotInstalled_disable() {
|
||||
setContent(ApplicationInfo().apply {
|
||||
packageName = PACKAGE_NAME
|
||||
uid = UID
|
||||
})
|
||||
setContent(
|
||||
ApplicationInfo().apply {
|
||||
packageName = PACKAGE_NAME
|
||||
uid = UID
|
||||
})
|
||||
|
||||
composeTestRule.onNodeWithText(context.getString(R.string.notifications_label))
|
||||
composeTestRule
|
||||
.onNodeWithText(context.getString(R.string.notifications_label))
|
||||
.assertIsNotEnabled()
|
||||
}
|
||||
|
||||
@@ -125,11 +125,12 @@ class AppNotificationPreferenceTest {
|
||||
private companion object {
|
||||
const val PACKAGE_NAME = "package.name"
|
||||
const val UID = 123
|
||||
val APP = ApplicationInfo().apply {
|
||||
packageName = PACKAGE_NAME
|
||||
uid = UID
|
||||
flags = ApplicationInfo.FLAG_INSTALLED
|
||||
}
|
||||
val APP =
|
||||
ApplicationInfo().apply {
|
||||
packageName = PACKAGE_NAME
|
||||
uid = UID
|
||||
flags = ApplicationInfo.FLAG_INSTALLED
|
||||
}
|
||||
const val SUMMARY = "Summary"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -18,9 +18,6 @@ package com.android.settings.network.telephony;
|
||||
|
||||
import static androidx.lifecycle.Lifecycle.Event.ON_START;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
|
||||
import static com.android.settings.network.telephony.MobileNetworkUtils.getRafFromNetworkType;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.CDMA;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.EVDO;
|
||||
@@ -33,8 +30,6 @@ import static com.android.settings.network.telephony.TelephonyConstants.RadioAcc
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -123,79 +118,6 @@ public class EnabledNetworkModePreferenceControllerTest {
|
||||
mPreference.setKey(mController.getPreferenceKey());
|
||||
}
|
||||
|
||||
@UiThreadTest
|
||||
@Test
|
||||
public void getAvailabilityStatus_hideCarrierNetworkSettings_returnUnavailable() {
|
||||
mPersistableBundle.putBoolean(
|
||||
CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL,
|
||||
true);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@UiThreadTest
|
||||
@Test
|
||||
public void getAvailabilityStatus_hidePreferredNetworkType_returnUnavailable() {
|
||||
mPersistableBundle.putBoolean(CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL,
|
||||
true);
|
||||
|
||||
when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
|
||||
when(mServiceState.getDataRegistrationState()).thenReturn(
|
||||
ServiceState.STATE_OUT_OF_SERVICE);
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
|
||||
when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);
|
||||
when(mServiceState.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE);
|
||||
|
||||
when(mServiceState.getRoaming()).thenReturn(false);
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
|
||||
when(mServiceState.getRoaming()).thenReturn(true);
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@UiThreadTest
|
||||
@Test
|
||||
public void getAvailabilityStatus_carrierConfigNotReady_returnUnavailable() {
|
||||
mPersistableBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, false);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@UiThreadTest
|
||||
@Test
|
||||
public void getAvailabilityStatus_notWorldPhone_returnAvailable() {
|
||||
mPersistableBundle.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL,
|
||||
false);
|
||||
mPersistableBundle.putBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL, false);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@UiThreadTest
|
||||
@Test
|
||||
public void getAvailabilityStatus_callStateIsIdle_returnAvailable() {
|
||||
mockEnabledNetworkMode(TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA);
|
||||
mController.getTelephonyCallback().onCallStateChanged(TelephonyManager.CALL_STATE_IDLE);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
assertTrue(mPreference.isEnabled());
|
||||
}
|
||||
|
||||
@UiThreadTest
|
||||
@Test
|
||||
public void getAvailabilityStatus_duringCalling_returnAvailable() {
|
||||
mockEnabledNetworkMode(TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA);
|
||||
mController.getTelephonyCallback().onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
|
||||
assertFalse(mPreference.isEnabled());
|
||||
}
|
||||
|
||||
@UiThreadTest
|
||||
@Test
|
||||
public void updateState_LteWorldPhone_GlobalHasLte() {
|
||||
|
@@ -16,8 +16,6 @@
|
||||
|
||||
package com.android.settings.network.telephony;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.GSM;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.RAF_TD_SCDMA;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.WCDMA;
|
||||
@@ -32,7 +30,6 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.PersistableBundle;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
@@ -91,43 +88,6 @@ public class PreferredNetworkModePreferenceControllerTest {
|
||||
mPreference.setKey(mController.getPreferenceKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_hideCarrierNetworkSettings_returnUnavailable() {
|
||||
mPersistableBundle.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL,
|
||||
true);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_worldPhone_returnAvailable() {
|
||||
mPersistableBundle.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL,
|
||||
false);
|
||||
mPersistableBundle.putBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL, true);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_hidePreferredNetworkType_returnUnavailable() {
|
||||
mPersistableBundle.putBoolean(CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL,
|
||||
true);
|
||||
|
||||
when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
|
||||
when(mServiceState.getDataRegistrationState()).thenReturn(
|
||||
ServiceState.STATE_OUT_OF_SERVICE);
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
|
||||
when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);
|
||||
when(mServiceState.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE);
|
||||
|
||||
when(mServiceState.getRoaming()).thenReturn(false);
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
|
||||
when(mServiceState.getRoaming()).thenReturn(true);
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_updateByNetworkMode() {
|
||||
// NETWORK_MODE_TDSCDMA_GSM_WCDMA = RAF_TD_SCDMA | GSM | WCDMA
|
||||
|
Reference in New Issue
Block a user