Merge "Update error dialog text for SIM switching" into main
diff --git a/res/xml/mobile_network_settings.xml b/res/xml/mobile_network_settings.xml
index fc99ae2..29e7c25 100644
--- a/res/xml/mobile_network_settings.xml
+++ b/res/xml/mobile_network_settings.xml
@@ -98,9 +98,11 @@
settings:searchable="false"
settings:controller="com.android.settings.network.telephony.DataUsagePreferenceController"/>
+ <!-- Settings search is handled by BillingCycleSearchItem. -->
<com.android.settings.datausage.BillingCyclePreference
android:key="billing_preference"
android:title="@string/billing_cycle"
+ settings:searchable="false"
settings:controller="com.android.settings.datausage.BillingCyclePreferenceController"/>
<SwitchPreferenceCompat
diff --git a/src/com/android/settings/accessibility/HearingAidCompatibilityPreferenceController.java b/src/com/android/settings/accessibility/HearingAidCompatibilityPreferenceController.java
index 727cdd5..821fddd 100644
--- a/src/com/android/settings/accessibility/HearingAidCompatibilityPreferenceController.java
+++ b/src/com/android/settings/accessibility/HearingAidCompatibilityPreferenceController.java
@@ -25,6 +25,7 @@
import com.android.internal.telephony.flags.Flags;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
/** Preference controller for Hearing Aid Compatibility (HAC) settings */
public class HearingAidCompatibilityPreferenceController extends TogglePreferenceController {
@@ -73,6 +74,8 @@
@Override
public boolean setChecked(boolean isChecked) {
+ FeatureFactory.getFeatureFactory().getMetricsFeatureProvider().changed(
+ getMetricsCategory(), getPreferenceKey(), isChecked ? 1 : 0);
setAudioParameterHacEnabled(isChecked);
return Settings.System.putInt(mContext.getContentResolver(), Settings.System.HEARING_AID,
(isChecked ? HAC_ENABLED : HAC_DISABLED));
diff --git a/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceController.java b/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceController.java
index 818eb5e..45a19b7 100644
--- a/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceController.java
+++ b/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceController.java
@@ -27,6 +27,7 @@
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
+import android.os.Looper;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
@@ -69,7 +70,8 @@
public KeyboardVibrationTogglePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mVibrator = context.getSystemService(Vibrator.class);
- mContentObserver = new ContentObserver(new Handler(/* async= */ true)) {
+ Handler handler = Looper.myLooper() != null ? new Handler(/* async= */ true) : null;
+ mContentObserver = new ContentObserver(handler) {
@Override
public void onChange(boolean selfChange, Uri uri) {
if (uri.equals(MAIN_VIBRATION_SWITCH_URI)) {
diff --git a/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceController.java b/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceController.java
index db184bf..5b553e3 100644
--- a/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceController.java
+++ b/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceController.java
@@ -23,6 +23,7 @@
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
+import android.os.Looper;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
@@ -49,7 +50,8 @@
public VibrationMainSwitchPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mVibrator = context.getSystemService(Vibrator.class);
- mSettingObserver = new ContentObserver(new Handler(/* async= */ true)) {
+ Handler handler = Looper.myLooper() != null ? new Handler(/* async= */ true) : null;
+ mSettingObserver = new ContentObserver(handler) {
@Override
public void onChange(boolean selfChange, Uri uri) {
updateState(mSwitchPreference);
diff --git a/src/com/android/settings/accessibility/VibrationPreferenceConfig.java b/src/com/android/settings/accessibility/VibrationPreferenceConfig.java
index ec1fab1..3887cec 100644
--- a/src/com/android/settings/accessibility/VibrationPreferenceConfig.java
+++ b/src/com/android/settings/accessibility/VibrationPreferenceConfig.java
@@ -27,6 +27,7 @@
import android.media.AudioManager;
import android.net.Uri;
import android.os.Handler;
+import android.os.Looper;
import android.os.VibrationAttributes;
import android.os.VibrationEffect;
import android.os.Vibrator;
@@ -165,7 +166,7 @@
/** Creates observer for given preference. */
public SettingObserver(VibrationPreferenceConfig preferenceConfig) {
- super(new Handler(/* async= */ true));
+ super(Looper.myLooper() != null ? new Handler(/* async= */ true) : null);
mUri = Settings.System.getUriFor(preferenceConfig.getSettingKey());
if (preferenceConfig.isRestrictedByRingerModeSilent()) {
diff --git a/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceController.java b/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceController.java
index 149bed3..69b1e15 100644
--- a/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceController.java
+++ b/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceController.java
@@ -21,6 +21,7 @@
import android.media.AudioManager;
import android.net.Uri;
import android.os.Handler;
+import android.os.Looper;
import android.os.Vibrator;
import android.provider.DeviceConfig;
import android.provider.Settings;
@@ -74,7 +75,8 @@
mRingVibrationPreferenceConfig = new RingVibrationPreferenceConfig(context);
mRingSettingObserver = new VibrationPreferenceConfig.SettingObserver(
mRingVibrationPreferenceConfig);
- mSettingObserver = new ContentObserver(new Handler(/* async= */ true)) {
+ Handler handler = Looper.myLooper() != null ? new Handler(/* async= */ true) : null;
+ mSettingObserver = new ContentObserver(handler) {
@Override
public void onChange(boolean selfChange, Uri uri) {
updateState(mPreference);
diff --git a/src/com/android/settings/accessibility/ViewAllBluetoothDevicesPreferenceController.java b/src/com/android/settings/accessibility/ViewAllBluetoothDevicesPreferenceController.java
index 622d5d8..b35575e 100644
--- a/src/com/android/settings/accessibility/ViewAllBluetoothDevicesPreferenceController.java
+++ b/src/com/android/settings/accessibility/ViewAllBluetoothDevicesPreferenceController.java
@@ -26,6 +26,7 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.overlay.FeatureFactory;
/** Preference controller for all bluetooth device preference. */
public class ViewAllBluetoothDevicesPreferenceController extends BasePreferenceController {
@@ -52,6 +53,8 @@
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
+ FeatureFactory.getFeatureFactory().getMetricsFeatureProvider().clicked(
+ getMetricsCategory(), getPreferenceKey());
launchConnectedDevicePage();
return true;
}
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsHearingAidsPresetsController.java b/src/com/android/settings/bluetooth/BluetoothDetailsHearingAidsPresetsController.java
index f7ccc61..25a99ed 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsHearingAidsPresetsController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsHearingAidsPresetsController.java
@@ -38,6 +38,7 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.HapClientProfile;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -111,6 +112,7 @@
final int index = listPreference.findIndexOfValue(value);
final String presetName = listPreference.getEntries()[index].toString();
final int presetIndex = Integer.parseInt(value);
+ logPresetChangedIfNeeded();
listPreference.setSummary(presetName);
if (DEBUG) {
Log.d(TAG, "onPreferenceChange"
@@ -373,4 +375,15 @@
mHapClientProfile.selectPreset(memberDevice.getDevice(), presetIndex);
}
}
+
+ private void logPresetChangedIfNeeded() {
+ if (mPreference == null || mPreference.getEntries() == null) {
+ return;
+ }
+ if (mFragment instanceof BluetoothDeviceDetailsFragment) {
+ int category = ((BluetoothDeviceDetailsFragment) mFragment).getMetricsCategory();
+ FeatureFactory.getFeatureFactory().getMetricsFeatureProvider().changed(category,
+ getPreferenceKey(), mPreference.getEntries().length);
+ }
+ }
}
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
index 5d9b124..4cb540c 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
@@ -65,15 +65,14 @@
public class BluetoothDetailsProfilesController extends BluetoothDetailsController
implements Preference.OnPreferenceClickListener,
LocalBluetoothProfileManager.ServiceListener {
+ public static final String HIGH_QUALITY_AUDIO_PREF_TAG = "A2dpProfileHighQualityAudio";
+
private static final String TAG = "BtDetailsProfilesCtrl";
private static final String KEY_PROFILES_GROUP = "bluetooth_profiles";
private static final String KEY_BOTTOM_PREFERENCE = "bottom_preference";
private static final int ORDINAL = 99;
- @VisibleForTesting
- static final String HIGH_QUALITY_AUDIO_PREF_TAG = "A2dpProfileHighQualityAudio";
-
private static final String ENABLE_DUAL_MODE_AUDIO =
"persist.bluetooth.enable_dual_mode_audio";
private static final String LE_AUDIO_CONNECTION_BY_DEFAULT_PROPERTY =
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
index c0d67cc..6501084 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
@@ -25,6 +25,7 @@
import android.bluetooth.BluetoothLeBroadcastAssistant;
import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.bluetooth.BluetoothLeBroadcastReceiveState;
+import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -52,7 +53,10 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.SettingsMainSwitchBar;
+import com.android.settingslib.bluetooth.BluetoothCallback;
+import com.android.settingslib.bluetooth.BluetoothEventManager;
import com.android.settingslib.bluetooth.BluetoothUtils;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -75,7 +79,8 @@
public class AudioSharingSwitchBarController extends BasePreferenceController
implements DefaultLifecycleObserver,
OnCheckedChangeListener,
- LocalBluetoothProfileManager.ServiceListener {
+ LocalBluetoothProfileManager.ServiceListener,
+ BluetoothCallback {
private static final String TAG = "AudioSharingSwitchCtlr";
private static final String PREF_KEY = "audio_sharing_main_switch";
@@ -99,6 +104,7 @@
private final SettingsMainSwitchBar mSwitchBar;
private final BluetoothAdapter mBluetoothAdapter;
@Nullable private final LocalBluetoothManager mBtManager;
+ @Nullable private final BluetoothEventManager mEventManager;
@Nullable private final LocalBluetoothProfileManager mProfileManager;
@Nullable private final LocalBluetoothLeBroadcast mBroadcast;
@Nullable private final LocalBluetoothLeBroadcastAssistant mAssistant;
@@ -302,6 +308,7 @@
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
mBtManager = Utils.getLocalBtManager(context);
+ mEventManager = mBtManager == null ? null : mBtManager.getEventManager();
mProfileManager = mBtManager == null ? null : mBtManager.getProfileManager();
mBroadcast = mProfileManager == null ? null : mProfileManager.getLeAudioBroadcastProfile();
mAssistant =
@@ -427,6 +434,13 @@
// Do nothing.
}
+ @Override
+ public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
+ if (activeDevice != null && bluetoothProfile == BluetoothProfile.LE_AUDIO) {
+ updateSwitch();
+ }
+ }
+
/**
* Initialize the controller.
*
@@ -447,7 +461,7 @@
Log.d(TAG, "Skip registerCallbacks(). Feature is not available.");
return;
}
- if (mBroadcast == null || mAssistant == null) {
+ if (mBroadcast == null || mAssistant == null || mEventManager == null) {
Log.d(TAG, "Skip registerCallbacks(). Profile not support on this device.");
return;
}
@@ -456,6 +470,7 @@
mSwitchBar.addOnSwitchChangeListener(this);
mBroadcast.registerServiceCallBack(mExecutor, mBroadcastCallback);
mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback);
+ mEventManager.registerCallback(this);
mCallbacksRegistered.set(true);
}
}
@@ -465,7 +480,7 @@
Log.d(TAG, "Skip unregisterCallbacks(). Feature is not available.");
return;
}
- if (mBroadcast == null || mAssistant == null) {
+ if (mBroadcast == null || mAssistant == null || mEventManager == null) {
Log.d(TAG, "Skip unregisterCallbacks(). Profile not support on this device.");
return;
}
@@ -474,6 +489,7 @@
mSwitchBar.removeOnSwitchChangeListener(this);
mBroadcast.unregisterServiceCallBack(mBroadcastCallback);
mAssistant.unregisterServiceCallBack(mBroadcastAssistantCallback);
+ mEventManager.unregisterCallback(this);
mCallbacksRegistered.set(false);
}
}
@@ -518,10 +534,15 @@
ThreadUtils.postOnBackgroundThread(
() -> {
boolean isBroadcasting = BluetoothUtils.isBroadcasting(mBtManager);
+ boolean hasActiveDevice =
+ AudioSharingUtils.hasActiveConnectedLeadDevice(mBtManager);
boolean isStateReady =
isBluetoothOn()
&& AudioSharingUtils.isAudioSharingProfileReady(
- mProfileManager);
+ mProfileManager)
+ // Disable toggle till device gets active after
+ // broadcast ends.
+ && (isBroadcasting || hasActiveDevice);
AudioSharingUtils.postOnMainThread(
mContext,
() -> {
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
index 0c2dc36..43256bc 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
@@ -115,7 +115,7 @@
* sharing. The active device is placed in the first place if it exists. The devices can be
* filtered by whether it is already in the audio sharing session.
*
- * @param localBtManager The BT manager to provide BT functions. *
+ * @param localBtManager The BT manager to provide BT functions.
* @param groupedConnectedDevices devices connected to broadcast assistant grouped by CSIP group
* id.
* @param filterByInSharing Whether to filter the device by if is already in the sharing
@@ -190,7 +190,7 @@
* sharing. The active device is placed in the first place if it exists. The devices can be
* filtered by whether it is already in the audio sharing session.
*
- * @param localBtManager The BT manager to provide BT functions. *
+ * @param localBtManager The BT manager to provide BT functions.
* @param groupedConnectedDevices devices connected to broadcast assistant grouped by CSIP group
* id.
* @param filterByInSharing Whether to filter the device by if is already in the sharing
@@ -210,6 +210,22 @@
.collect(toList());
}
+ /** Return if there exists active connected lead device. */
+ public static boolean hasActiveConnectedLeadDevice(
+ @Nullable LocalBluetoothManager localBtManager) {
+ CachedBluetoothDeviceManager deviceManager =
+ localBtManager == null ? null : localBtManager.getCachedDeviceManager();
+ Map<Integer, List<BluetoothDevice>> groupedConnectedDevices =
+ fetchConnectedDevicesByGroupId(localBtManager);
+ for (List<BluetoothDevice> devices : groupedConnectedDevices.values()) {
+ CachedBluetoothDevice leadDevice = getLeadDevice(deviceManager, devices);
+ if (isActiveLeAudioDevice(leadDevice)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/** Build {@link AudioSharingDeviceItem} from {@link CachedBluetoothDevice}. */
public static AudioSharingDeviceItem buildAudioSharingDeviceItem(
CachedBluetoothDevice cachedDevice) {
@@ -225,8 +241,8 @@
* @param cachedDevice The cached bluetooth device to check.
* @return Whether the device is an active le audio device.
*/
- public static boolean isActiveLeAudioDevice(CachedBluetoothDevice cachedDevice) {
- return BluetoothUtils.isActiveLeAudioDevice(cachedDevice);
+ public static boolean isActiveLeAudioDevice(@Nullable CachedBluetoothDevice cachedDevice) {
+ return cachedDevice != null && BluetoothUtils.isActiveLeAudioDevice(cachedDevice);
}
/** Toast message on main thread. */
diff --git a/src/com/android/settings/datausage/BillingCyclePreferenceController.java b/src/com/android/settings/datausage/BillingCyclePreferenceController.java
deleted file mode 100644
index 8b55585..0000000
--- a/src/com/android/settings/datausage/BillingCyclePreferenceController.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2019 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.datausage;
-
-import android.content.Context;
-import android.net.NetworkTemplate;
-
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.core.BasePreferenceController;
-import com.android.settings.datausage.lib.DataUsageLib;
-
-public class BillingCyclePreferenceController extends BasePreferenceController {
- private int mSubscriptionId;
-
- public BillingCyclePreferenceController(Context context, String preferenceKey) {
- super(context, preferenceKey);
- }
-
- public void init(int subscriptionId) {
- mSubscriptionId = subscriptionId;
- }
-
- @Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- BillingCyclePreference preference = screen.findPreference(getPreferenceKey());
-
- NetworkTemplate template = DataUsageLib.getMobileTemplate(mContext, mSubscriptionId);
-
- preference.setTemplate(template, mSubscriptionId);
- }
-
- @Override
- public int getAvailabilityStatus() {
- return DataUsageUtils.hasMobileData(mContext) ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
- }
-}
diff --git a/src/com/android/settings/datausage/BillingCyclePreferenceController.kt b/src/com/android/settings/datausage/BillingCyclePreferenceController.kt
new file mode 100644
index 0000000..f699743
--- /dev/null
+++ b/src/com/android/settings/datausage/BillingCyclePreferenceController.kt
@@ -0,0 +1,58 @@
+/*
+ * 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.datausage
+
+import android.content.Context
+import android.telephony.SubscriptionManager
+import androidx.preference.PreferenceScreen
+import com.android.settings.R
+import com.android.settings.core.BasePreferenceController
+import com.android.settings.datausage.lib.DataUsageLib.getMobileTemplate
+import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
+import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchResult
+
+class BillingCyclePreferenceController(context: Context, preferenceKey: String) :
+ BasePreferenceController(context, preferenceKey) {
+ private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID
+
+ fun init(subId: Int) {
+ this.subId = subId
+ }
+
+ override fun getAvailabilityStatus() =
+ if (DataUsageUtils.hasMobileData(mContext)) AVAILABLE else CONDITIONALLY_UNAVAILABLE
+
+ override fun displayPreference(screen: PreferenceScreen) {
+ super.displayPreference(screen)
+ val preference = screen.findPreference<BillingCyclePreference>(preferenceKey)
+ val template = getMobileTemplate(mContext, subId)
+ preference?.setTemplate(template, subId)
+ }
+
+ companion object {
+ class BillingCycleSearchItem(private val context: Context) :
+ MobileNetworkSettingsSearchItem {
+ override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? {
+ if (!DataUsageUtils.hasMobileData(context)) return null
+ return MobileNetworkSettingsSearchResult(
+ key = "billing_preference",
+ title = context.getString(R.string.billing_cycle),
+ )
+ }
+ }
+ }
+}
diff --git a/src/com/android/settings/development/DevelopmentMemtagFooterPreferenceController.java b/src/com/android/settings/development/DevelopmentMemtagFooterPreferenceController.java
index a5612ca..f2c9f59 100644
--- a/src/com/android/settings/development/DevelopmentMemtagFooterPreferenceController.java
+++ b/src/com/android/settings/development/DevelopmentMemtagFooterPreferenceController.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.settings.security;
+package com.android.settings.development;
import android.content.Context;
import android.text.TextUtils;
diff --git a/src/com/android/settings/deviceinfo/StorageItemPreference.java b/src/com/android/settings/deviceinfo/StorageItemPreference.java
index 91102a0..62c0a6a 100644
--- a/src/com/android/settings/deviceinfo/StorageItemPreference.java
+++ b/src/com/android/settings/deviceinfo/StorageItemPreference.java
@@ -22,6 +22,7 @@
import android.util.AttributeSet;
import android.widget.ProgressBar;
+import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
@@ -48,6 +49,7 @@
setLayoutResource(R.layout.storage_item);
}
+ @VisibleForTesting
public void setStorageSize(long size, long total) {
setStorageSize(size, total, false /* animate */);
}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt b/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt
index 4f31e0f..83e3a31 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt
@@ -20,6 +20,7 @@
import android.provider.Settings
import android.telephony.SubscriptionInfo
import com.android.settings.R
+import com.android.settings.datausage.BillingCyclePreferenceController.Companion.BillingCycleSearchItem
import com.android.settings.network.SubscriptionUtil
import com.android.settings.network.telephony.CarrierSettingsVersionPreferenceController.Companion.CarrierSettingsVersionSearchItem
import com.android.settings.network.telephony.DataUsagePreferenceController.Companion.DataUsageSearchItem
@@ -117,6 +118,7 @@
fun createSearchItems(context: Context): List<MobileNetworkSettingsSearchItem> =
listOf(
+ BillingCycleSearchItem(context),
CarrierSettingsVersionSearchItem(context),
DataUsageSearchItem(context),
MmsMessageSearchItem(context),
diff --git a/src/com/android/settings/notification/modes/InterruptionFilterPreferenceController.java b/src/com/android/settings/notification/modes/InterruptionFilterPreferenceController.java
index d69b317..e5c6570 100644
--- a/src/com/android/settings/notification/modes/InterruptionFilterPreferenceController.java
+++ b/src/com/android/settings/notification/modes/InterruptionFilterPreferenceController.java
@@ -44,8 +44,8 @@
@Override
public void updateState(Preference preference, @NonNull ZenMode zenMode) {
- preference.setEnabled(zenMode.isEnabled());
- boolean allowingAll = zenMode.getRule().getInterruptionFilter() == INTERRUPTION_FILTER_ALL;
+ preference.setEnabled(zenMode.isEnabled() && zenMode.canEditPolicy());
+ boolean allowingAll = zenMode.getInterruptionFilter() == INTERRUPTION_FILTER_ALL;
((TwoStatePreference) preference).setChecked(allowingAll);
preference.setSummary(allowingAll
@@ -57,7 +57,7 @@
public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) {
final boolean allowAll = ((Boolean) newValue);
return saveMode(zenMode -> {
- zenMode.getRule().setInterruptionFilter(allowAll
+ zenMode.setInterruptionFilter(allowAll
? INTERRUPTION_FILTER_ALL
: INTERRUPTION_FILTER_PRIORITY);
return zenMode;
diff --git a/src/com/android/settings/notification/modes/SetupInterstitialActivity.java b/src/com/android/settings/notification/modes/SetupInterstitialActivity.java
index c5beb36..fcd5fd5 100644
--- a/src/com/android/settings/notification/modes/SetupInterstitialActivity.java
+++ b/src/com/android/settings/notification/modes/SetupInterstitialActivity.java
@@ -228,7 +228,7 @@
return false;
}
- modeToUpdate.getRule().setEnabled(true);
+ modeToUpdate.setEnabled(true);
mBackend.updateMode(modeToUpdate);
return true;
}
diff --git a/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java
index 7b17f0c..c133f51 100644
--- a/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java
@@ -92,7 +92,7 @@
@Override
public boolean isAvailable(ZenMode zenMode) {
- return zenMode.getRule().getInterruptionFilter() != INTERRUPTION_FILTER_ALL;
+ return zenMode.getInterruptionFilter() != INTERRUPTION_FILTER_ALL;
}
@Override
@@ -102,7 +102,7 @@
preference.setIntent(
ZenSubSettingLauncher.forModeFragment(mContext, ZenModeAppsFragment.class,
zenMode.getId(), SettingsEnums.ZEN_PRIORITY_MODE).toIntent());
- preference.setEnabled(zenMode.isEnabled());
+ preference.setEnabled(zenMode.isEnabled() && zenMode.canEditPolicy());
mZenMode = zenMode;
mPreference = (CircularIconsPreference) preference;
diff --git a/src/com/android/settings/notification/modes/ZenModeDisplayEffectPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeDisplayEffectPreferenceController.java
index b0d3952..afd9b76 100644
--- a/src/com/android/settings/notification/modes/ZenModeDisplayEffectPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeDisplayEffectPreferenceController.java
@@ -74,7 +74,7 @@
updatedEffects.setShouldUseNightMode(allow);
break;
}
- zenMode.getRule().setDeviceEffects(updatedEffects.build());
+ zenMode.setDeviceEffects(updatedEffects.build());
return zenMode;
});
}
diff --git a/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceController.java
index 57dce89..14c8cb6 100644
--- a/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceController.java
@@ -45,7 +45,7 @@
preference.setIntent(
ZenSubSettingLauncher.forModeFragment(mContext, ZenModeDisplayFragment.class,
zenMode.getId(), SettingsEnums.ZEN_PRIORITY_MODE).toIntent());
- preference.setEnabled(zenMode.isEnabled());
+ preference.setEnabled(zenMode.isEnabled() && zenMode.canEditPolicy());
}
@Override
diff --git a/src/com/android/settings/notification/modes/ZenModeExitAtAlarmPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeExitAtAlarmPreferenceController.java
index 326bc97..18e3fc1 100644
--- a/src/com/android/settings/notification/modes/ZenModeExitAtAlarmPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeExitAtAlarmPreferenceController.java
@@ -50,7 +50,8 @@
if (mSchedule.exitAtAlarm != exitAtAlarm) {
mSchedule.exitAtAlarm = exitAtAlarm;
return saveMode(mode -> {
- mode.getRule().setConditionId(ZenModeConfig.toScheduleConditionId(mSchedule));
+ mode.setCustomModeConditionId(mContext,
+ ZenModeConfig.toScheduleConditionId(mSchedule));
return mode;
});
}
diff --git a/src/com/android/settings/notification/modes/ZenModeFragment.java b/src/com/android/settings/notification/modes/ZenModeFragment.java
index 8eef708..08075b4 100644
--- a/src/com/android/settings/notification/modes/ZenModeFragment.java
+++ b/src/com/android/settings/notification/modes/ZenModeFragment.java
@@ -171,7 +171,7 @@
} else if (menuItem.getItemId() == DELETE_MODE) {
new AlertDialog.Builder(mContext)
.setTitle(mContext.getString(R.string.zen_mode_delete_mode_confirmation,
- mZenMode.getRule().getName()))
+ mZenMode.getName()))
.setPositiveButton(R.string.zen_mode_schedule_delete,
(dialog, which) -> {
// start finishing before calling removeMode() so that we
diff --git a/src/com/android/settings/notification/modes/ZenModeNotifVisLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeNotifVisLinkPreferenceController.java
index cd1e8c7..f08a05d 100644
--- a/src/com/android/settings/notification/modes/ZenModeNotifVisLinkPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeNotifVisLinkPreferenceController.java
@@ -41,7 +41,7 @@
@Override
public boolean isAvailable(ZenMode zenMode) {
- return zenMode.getRule().getInterruptionFilter() != INTERRUPTION_FILTER_ALL;
+ return zenMode.getInterruptionFilter() != INTERRUPTION_FILTER_ALL;
}
@Override
diff --git a/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java
index 9613d98..9adc768 100644
--- a/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java
@@ -61,7 +61,7 @@
@Override
public boolean isAvailable(ZenMode zenMode) {
- return zenMode.getRule().getInterruptionFilter() != INTERRUPTION_FILTER_ALL;
+ return zenMode.getInterruptionFilter() != INTERRUPTION_FILTER_ALL;
}
@Override
@@ -70,7 +70,7 @@
ZenSubSettingLauncher.forModeFragment(mContext, ZenModeOtherFragment.class,
zenMode.getId(), SettingsEnums.ZEN_PRIORITY_MODE).toIntent());
- preference.setEnabled(zenMode.isEnabled());
+ preference.setEnabled(zenMode.isEnabled() && zenMode.canEditPolicy());
preference.setSummary(mSummaryHelper.getOtherSoundCategoriesSummary(zenMode));
((CircularIconsPreference) preference).setIcons(getSoundIcons(zenMode.getPolicy()));
}
diff --git a/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java
index bf55471..c635ad8 100644
--- a/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java
@@ -84,7 +84,7 @@
@Override
public boolean isAvailable(ZenMode zenMode) {
- return zenMode.getRule().getInterruptionFilter() != INTERRUPTION_FILTER_ALL;
+ return zenMode.getInterruptionFilter() != INTERRUPTION_FILTER_ALL;
}
@Override
@@ -94,7 +94,7 @@
ZenSubSettingLauncher.forModeFragment(mContext, ZenModePeopleFragment.class,
zenMode.getId(), SettingsEnums.ZEN_PRIORITY_MODE).toIntent());
- preference.setEnabled(zenMode.isEnabled());
+ preference.setEnabled(zenMode.isEnabled() && zenMode.canEditPolicy());
preference.setSummary(mSummaryHelper.getPeopleSummary(zenMode.getPolicy()));
((CircularIconsPreference) preference).setIcons(getPeopleIcons(zenMode.getPolicy()),
PEOPLE_ITEM_EQUIVALENCE);
diff --git a/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java b/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java
index c5300da..483b8f0 100644
--- a/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java
+++ b/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java
@@ -209,48 +209,46 @@
boolean isFirst = true;
List<String> enabledEffects = new ArrayList<>();
if (!zenMode.getPolicy().shouldShowAllVisualEffects()
- && zenMode.getRule().getInterruptionFilter() != INTERRUPTION_FILTER_ALL) {
+ && zenMode.getInterruptionFilter() != INTERRUPTION_FILTER_ALL) {
enabledEffects.add(getBlockedEffectsSummary(zenMode));
isFirst = false;
}
- ZenDeviceEffects currEffects = zenMode.getRule().getDeviceEffects();
- if (currEffects != null) {
- if (currEffects.shouldDisplayGrayscale()) {
- if (isFirst) {
- enabledEffects.add(mContext.getString(R.string.mode_grayscale_title));
- } else {
- enabledEffects.add(mContext.getString(
- R.string.mode_grayscale_title_secondary_list));
- }
- isFirst = false;
+ ZenDeviceEffects currEffects = zenMode.getDeviceEffects();
+ if (currEffects.shouldDisplayGrayscale()) {
+ if (isFirst) {
+ enabledEffects.add(mContext.getString(R.string.mode_grayscale_title));
+ } else {
+ enabledEffects.add(mContext.getString(
+ R.string.mode_grayscale_title_secondary_list));
}
- if (currEffects.shouldSuppressAmbientDisplay()) {
- if (isFirst) {
- enabledEffects.add(mContext.getString(R.string.mode_aod_title));
- } else {
- enabledEffects.add(mContext.getString(
- R.string.mode_aod_title_secondary_list));
- }
- isFirst = false;
+ isFirst = false;
+ }
+ if (currEffects.shouldSuppressAmbientDisplay()) {
+ if (isFirst) {
+ enabledEffects.add(mContext.getString(R.string.mode_aod_title));
+ } else {
+ enabledEffects.add(mContext.getString(
+ R.string.mode_aod_title_secondary_list));
}
- if (currEffects.shouldDimWallpaper()) {
- if (isFirst) {
- enabledEffects.add(mContext.getString(R.string.mode_wallpaper_title));
- } else {
- enabledEffects.add(mContext.getString(
- R.string.mode_wallpaper_title_secondary_list));
- }
- isFirst = false;
+ isFirst = false;
+ }
+ if (currEffects.shouldDimWallpaper()) {
+ if (isFirst) {
+ enabledEffects.add(mContext.getString(R.string.mode_wallpaper_title));
+ } else {
+ enabledEffects.add(mContext.getString(
+ R.string.mode_wallpaper_title_secondary_list));
}
- if (currEffects.shouldUseNightMode()) {
- if (isFirst) {
- enabledEffects.add(mContext.getString(R.string.mode_dark_theme_title));
- } else {
- enabledEffects.add(mContext.getString(
- R.string.mode_dark_theme_title_secondary_list));
- }
- isFirst = false;
+ isFirst = false;
+ }
+ if (currEffects.shouldUseNightMode()) {
+ if (isFirst) {
+ enabledEffects.add(mContext.getString(R.string.mode_dark_theme_title));
+ } else {
+ enabledEffects.add(mContext.getString(
+ R.string.mode_dark_theme_title_secondary_list));
}
+ isFirst = false;
}
int numCategories = enabledEffects.size();
diff --git a/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceController.java b/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceController.java
index f2302c0..1933635 100644
--- a/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceController.java
@@ -87,7 +87,7 @@
mModeName = zenMode.getName();
PrimarySwitchPreference triggerPref = (PrimarySwitchPreference) preference;
- triggerPref.setChecked(zenMode.getRule().isEnabled());
+ triggerPref.setChecked(zenMode.isEnabled());
triggerPref.setOnPreferenceChangeListener(mSwitchChangeListener);
if (zenMode.isSystemOwned()) {
setUpForSystemOwnedTrigger(triggerPref, zenMode);
@@ -213,7 +213,7 @@
private void setModeEnabled(boolean enabled) {
saveMode((zenMode) -> {
- if (enabled != zenMode.getRule().isEnabled()) {
+ if (enabled != zenMode.isEnabled()) {
zenMode.getRule().setEnabled(enabled);
}
return zenMode;
diff --git a/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java b/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java
index 5e36469..75d4ee3 100644
--- a/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java
@@ -118,7 +118,7 @@
for (ZenMode mode : mBackend.getModes()) {
SearchIndexableRaw data = new SearchIndexableRaw(mContext);
data.key = mode.getId();
- data.title = mode.getRule().getName();
+ data.title = mode.getName();
data.screenTitle = res.getString(R.string.zen_modes_list_title);
rawData.add(data);
}
diff --git a/src/com/android/settings/utils/FileSizeFormatter.java b/src/com/android/settings/utils/FileSizeFormatter.java
deleted file mode 100644
index 5950d5d..0000000
--- a/src/com/android/settings/utils/FileSizeFormatter.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2017 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.utils;
-
-import android.content.Context;
-import android.icu.text.DecimalFormat;
-import android.icu.text.MeasureFormat;
-import android.icu.text.NumberFormat;
-import android.icu.util.Measure;
-import android.icu.util.MeasureUnit;
-import android.text.BidiFormatter;
-import android.text.TextUtils;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.math.BigDecimal;
-import java.util.Locale;
-
-/**
- * Utility class to aid in formatting file sizes always with the same unit. This is modified from
- * android.text.format.Formatter to fit this purpose.
- */
-public final class FileSizeFormatter {
- public static final long KILOBYTE_IN_BYTES = 1000;
- public static final long MEGABYTE_IN_BYTES = KILOBYTE_IN_BYTES * 1000;
- public static final long GIGABYTE_IN_BYTES = MEGABYTE_IN_BYTES * 1000;
-
- private static class RoundedBytesResult {
- public final float value;
- public final MeasureUnit units;
- public final int fractionDigits;
- public final long roundedBytes;
-
- private RoundedBytesResult(
- float value, MeasureUnit units, int fractionDigits, long roundedBytes) {
- this.value = value;
- this.units = units;
- this.fractionDigits = fractionDigits;
- this.roundedBytes = roundedBytes;
- }
- }
-
- private static Locale localeFromContext(@NonNull Context context) {
- return context.getResources().getConfiguration().locale;
- }
-
- private static String bidiWrap(@NonNull Context context, String source) {
- final Locale locale = localeFromContext(context);
- if (TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL) {
- return BidiFormatter.getInstance(true /* RTL*/).unicodeWrap(source);
- } else {
- return source;
- }
- }
-
- private static NumberFormat getNumberFormatter(Locale locale, int fractionDigits) {
- final NumberFormat numberFormatter = NumberFormat.getInstance(locale);
- numberFormatter.setMinimumFractionDigits(fractionDigits);
- numberFormatter.setMaximumFractionDigits(fractionDigits);
- numberFormatter.setGroupingUsed(false);
- if (numberFormatter instanceof DecimalFormat) {
- // We do this only for DecimalFormat, since in the general NumberFormat case, calling
- // setRoundingMode may throw an exception.
- numberFormatter.setRoundingMode(BigDecimal.ROUND_HALF_UP);
- }
- return numberFormatter;
- }
-
- private static String formatMeasureShort(Locale locale, NumberFormat numberFormatter,
- float value, MeasureUnit units) {
- final MeasureFormat measureFormatter = MeasureFormat.getInstance(
- locale, MeasureFormat.FormatWidth.SHORT, numberFormatter);
- return measureFormatter.format(new Measure(value, units));
- }
-
- private static String formatRoundedBytesResult(
- @NonNull Context context, @NonNull RoundedBytesResult input) {
- final Locale locale = localeFromContext(context);
- final NumberFormat numberFormatter = getNumberFormatter(locale, input.fractionDigits);
- return formatMeasureShort(locale, numberFormatter, input.value, input.units);
- }
-
- /**
- * Formats a content size to be in the form of bytes, kilobytes, megabytes, etc.
- *
- * <p>As of O, the prefixes are used in their standard meanings in the SI system, so kB = 1000
- * bytes, MB = 1,000,000 bytes, etc.
- *
- * <p class="note">In {@link android.os.Build.VERSION_CODES#N} and earlier, powers of 1024 are
- * used instead, with KB = 1024 bytes, MB = 1,048,576 bytes, etc.
- *
- * <p>If the context has a right-to-left locale, the returned string is wrapped in bidi
- * formatting characters to make sure it's displayed correctly if inserted inside a
- * right-to-left string. (This is useful in cases where the unit strings, like "MB", are
- * left-to-right, but the locale is right-to-left.)
- *
- * @param context Context to use to load the localized units
- * @param sizeBytes size value to be formatted, in bytes
- * @param unit The unit used for formatting.
- * @param mult Amount of bytes in the unit.
- * @return formatted string with the number
- */
- public static String formatFileSize(
- @Nullable Context context, long sizeBytes, MeasureUnit unit, long mult) {
- if (context == null) {
- return "";
- }
- final RoundedBytesResult res = formatBytes(sizeBytes, unit, mult);
- return bidiWrap(context, formatRoundedBytesResult(context, res));
- }
-
- /**
- * A simplified version of the SettingsLib file size formatter. The primary difference is that
- * this version always assumes it is doing a "short file size" and allows for a suffix to be
- * provided.
- *
- * @param res Resources to fetch strings with.
- * @param sizeBytes File size in bytes to format.
- * @param suffix String id for the unit suffix.
- * @param mult Amount of bytes in the unit.
- */
- private static RoundedBytesResult formatBytes(
- long sizeBytes, MeasureUnit unit, long mult) {
- final boolean isNegative = (sizeBytes < 0);
- float result = isNegative ? -sizeBytes : sizeBytes;
- result = result / mult;
- // Note we calculate the rounded long by ourselves, but still let String.format()
- // compute the rounded value. String.format("%f", 0.1) might not return "0.1" due to
- // floating point errors.
- final int roundFactor;
- final int roundDigits;
- if (mult == 1) {
- roundFactor = 1;
- roundDigits = 0;
- } else if (result < 1) {
- roundFactor = 100;
- roundDigits = 2;
- } else if (result < 10) {
- roundFactor = 10;
- roundDigits = 1;
- } else { // 10 <= result < 100
- roundFactor = 1;
- roundDigits = 0;
- }
-
- if (isNegative) {
- result = -result;
- }
-
- // Note this might overflow if abs(result) >= Long.MAX_VALUE / 100, but that's like 80PB so
- // it's okay (for now)...
- final long roundedBytes = (((long) Math.round(result * roundFactor)) * mult / roundFactor);
-
- return new RoundedBytesResult(result, unit, roundDigits, roundedBytes);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java
index 5073119..d1533c9 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java
@@ -75,6 +75,8 @@
import com.android.settings.testutils.shadow.ShadowThreadUtils;
import com.android.settings.widget.SettingsMainSwitchBar;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.bluetooth.BluetoothCallback;
+import com.android.settingslib.bluetooth.BluetoothEventManager;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
@@ -117,6 +119,8 @@
public class AudioSharingSwitchBarControllerTest {
private static final String TEST_DEVICE_NAME1 = "test1";
private static final String TEST_DEVICE_NAME2 = "test2";
+ private static final String TEST_DEVICE_ANONYMIZED_ADDR1 = "XX:XX:01";
+ private static final String TEST_DEVICE_ANONYMIZED_ADDR2 = "XX:XX:02";
private static final int TEST_DEVICE_GROUP_ID1 = 1;
private static final int TEST_DEVICE_GROUP_ID2 = 2;
private static final Correspondence<Fragment, String> TAG_EQUALS =
@@ -133,6 +137,7 @@
@Spy Context mContext = ApplicationProvider.getApplicationContext();
@Mock private LocalBluetoothManager mLocalBtManager;
@Mock private CachedBluetoothDeviceManager mDeviceManager;
+ @Mock private BluetoothEventManager mEventManager;
@Mock private LocalBluetoothProfileManager mBtProfileManager;
@Mock private LocalBluetoothLeBroadcast mBroadcast;
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
@@ -168,11 +173,14 @@
mFeatureFactory = FakeFeatureFactory.setupForTest();
when(localBluetoothManager.getProfileManager()).thenReturn(mBtProfileManager);
when(localBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
+ when(localBluetoothManager.getEventManager()).thenReturn(mEventManager);
+ when(mDevice1.getAnonymizedAddress()).thenReturn(TEST_DEVICE_ANONYMIZED_ADDR1);
when(mDeviceManager.findDevice(mDevice1)).thenReturn(mCachedDevice1);
when(mCachedDevice1.getDevice()).thenReturn(mDevice1);
when(mCachedDevice1.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1);
when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1);
when(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(false);
+ when(mDevice2.getAnonymizedAddress()).thenReturn(TEST_DEVICE_ANONYMIZED_ADDR2);
when(mDeviceManager.findDevice(mDevice2)).thenReturn(mCachedDevice2);
when(mCachedDevice2.getDevice()).thenReturn(mDevice2);
when(mCachedDevice2.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID2);
@@ -308,6 +316,7 @@
verify(mAssistant, never())
.registerServiceCallBack(
any(Executor.class), any(BluetoothLeBroadcastAssistant.Callback.class));
+ verify(mEventManager, never()).registerCallback(any(BluetoothCallback.class));
verify(mBtProfileManager).addServiceListener(mController);
assertThat(mSwitchBar.isChecked()).isFalse();
assertThat(mSwitchBar.isEnabled()).isFalse();
@@ -328,6 +337,7 @@
verify(mAssistant)
.registerServiceCallBack(
any(Executor.class), any(BluetoothLeBroadcastAssistant.Callback.class));
+ verify(mEventManager).registerCallback(any(BluetoothCallback.class));
verify(mBtProfileManager, never()).addServiceListener(mController);
assertThat(mSwitchBar.isChecked()).isTrue();
assertThat(mSwitchBar.isEnabled()).isTrue();
@@ -342,6 +352,7 @@
.unregisterServiceCallBack(any(BluetoothLeBroadcast.Callback.class));
verify(mAssistant, never())
.unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class));
+ verify(mEventManager, never()).unregisterCallback(any(BluetoothCallback.class));
verify(mBtProfileManager, never()).removeServiceListener(mController);
}
@@ -358,6 +369,7 @@
.unregisterServiceCallBack(any(BluetoothLeBroadcast.Callback.class));
verify(mAssistant, never())
.unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class));
+ verify(mEventManager, never()).unregisterCallback(any(BluetoothCallback.class));
}
@Test
@@ -374,6 +386,7 @@
verify(mBroadcast).unregisterServiceCallBack(any(BluetoothLeBroadcast.Callback.class));
verify(mAssistant)
.unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class));
+ verify(mEventManager).unregisterCallback(any(BluetoothCallback.class));
}
@Test
@@ -599,9 +612,11 @@
mOnAudioSharingStateChanged = false;
mSwitchBar.setChecked(false);
when(mBroadcast.isEnabled(any())).thenReturn(false);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1, mDevice2));
mController.mBroadcastCallback.onBroadcastStartFailed(/* reason= */ 1);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mSwitchBar.isChecked()).isFalse();
+ assertThat(mSwitchBar.isEnabled()).isTrue();
assertThat(mOnAudioSharingStateChanged).isFalse();
verify(mFeatureFactory.metricsFeatureProvider)
.action(
@@ -613,6 +628,7 @@
mController.mBroadcastCallback.onBroadcastStarted(/* reason= */ 1, /* broadcastId= */ 1);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mSwitchBar.isChecked()).isTrue();
+ assertThat(mSwitchBar.isEnabled()).isTrue();
assertThat(mOnAudioSharingStateChanged).isTrue();
mOnAudioSharingStateChanged = false;
@@ -627,9 +643,11 @@
SettingsEnums.AUDIO_SHARING_SETTINGS);
when(mBroadcast.isEnabled(any())).thenReturn(false);
+ when(mCachedDevice2.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(false);
mController.mBroadcastCallback.onBroadcastStopped(/* reason= */ 1, /* broadcastId= */ 1);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mSwitchBar.isChecked()).isFalse();
+ assertThat(mSwitchBar.isEnabled()).isFalse();
assertThat(mOnAudioSharingStateChanged).isTrue();
}
@@ -683,6 +701,34 @@
}
@Test
+ public void onActiveDeviceChanged_leaProfile_updateSwitch() {
+ mSwitchBar.setChecked(true);
+ mSwitchBar.setEnabled(false);
+ when(mBroadcast.isEnabled(null)).thenReturn(false);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
+ mController.onActiveDeviceChanged(mCachedDevice2, BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
+ assertThat(mSwitchBar.isChecked()).isFalse();
+ verify(mSwitchBar).setEnabled(true);
+ }
+
+ @Test
+ public void onActiveDeviceChanged_nullActiveDevice_doNothing() {
+ mController.onActiveDeviceChanged(/* activeDevice= */ null, BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
+ verify(mSwitchBar, never()).setEnabled(anyBoolean());
+ verify(mSwitchBar, never()).setChecked(anyBoolean());
+ }
+
+ @Test
+ public void onActiveDeviceChanged_notLeaProfile_doNothing() {
+ mController.onActiveDeviceChanged(mCachedDevice2, BluetoothProfile.HEADSET);
+ shadowOf(Looper.getMainLooper()).idle();
+ verify(mSwitchBar, never()).setEnabled(anyBoolean());
+ verify(mSwitchBar, never()).setChecked(anyBoolean());
+ }
+
+ @Test
public void testAccessibilityDelegate() {
View view = new View(mContext);
AccessibilityEvent event =
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/StorageItemPreferenceTest.java b/tests/robotests/src/com/android/settings/deviceinfo/StorageItemPreferenceTest.java
index 984d945..eba8e11 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/StorageItemPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/StorageItemPreferenceTest.java
@@ -15,8 +15,6 @@
*/
package com.android.settings.deviceinfo;
-import static com.android.settings.utils.FileSizeFormatter.MEGABYTE_IN_BYTES;
-
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
@@ -36,6 +34,7 @@
@RunWith(RobolectricTestRunner.class)
public class StorageItemPreferenceTest {
+ private static final long MEGABYTE_IN_BYTES = 1000_000;
private Context mContext;
private StorageItemPreference mPreference;
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/NonCurrentUserControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/NonCurrentUserControllerTest.java
index 61d3bed..34cc4fd 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/NonCurrentUserControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/NonCurrentUserControllerTest.java
@@ -16,8 +16,6 @@
package com.android.settings.deviceinfo.storage;
-import static com.android.settings.utils.FileSizeFormatter.MEGABYTE_IN_BYTES;
-
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
@@ -61,6 +59,7 @@
private static final String TEST_NAME = "Fred";
private static final String TARGET_PREFERENCE_GROUP_KEY = "pref_secondary_users";
+ private static final long MEGABYTE_IN_BYTES = 1000_000;
@Mock
private UserManager mUserManager;
@Mock
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
index 306d80c..a9e9eac 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
@@ -16,9 +16,6 @@
package com.android.settings.deviceinfo.storage;
import static com.android.settings.applications.manageapplications.ManageApplications.EXTRA_WORK_ID;
-import static com.android.settings.utils.FileSizeFormatter.GIGABYTE_IN_BYTES;
-import static com.android.settings.utils.FileSizeFormatter.KILOBYTE_IN_BYTES;
-import static com.android.settings.utils.FileSizeFormatter.MEGABYTE_IN_BYTES;
import static com.google.common.truth.Truth.assertThat;
@@ -74,6 +71,10 @@
})
public class StorageItemPreferenceControllerTest {
+ private static final long KILOBYTE_IN_BYTES = 1000;
+ private static final long MEGABYTE_IN_BYTES = KILOBYTE_IN_BYTES * 1000;
+ private static final long GIGABYTE_IN_BYTES = MEGABYTE_IN_BYTES * 1000;
+
private Context mContext;
private VolumeInfo mVolume;
@Mock
diff --git a/tests/robotests/src/com/android/settings/notification/modes/InterruptionFilterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/InterruptionFilterPreferenceControllerTest.java
index 777d213..8653d95 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/InterruptionFilterPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/InterruptionFilterPreferenceControllerTest.java
@@ -17,6 +17,7 @@
package com.android.settings.notification.modes;
import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
import static android.service.notification.ZenPolicy.STATE_DISALLOW;
@@ -68,6 +69,26 @@
}
@Test
+ public void updateState_dnd_enabled() {
+ TwoStatePreference preference = mock(TwoStatePreference.class);
+ ZenMode dnd = TestModeBuilder.MANUAL_DND_ACTIVE;
+
+ mController.updateState(preference, dnd);
+
+ verify(preference).setEnabled(true);
+ }
+
+ @Test
+ public void updateState_specialDnd_disabled() {
+ TwoStatePreference preference = mock(TwoStatePreference.class);
+ ZenMode specialDnd = TestModeBuilder.manualDnd(INTERRUPTION_FILTER_NONE, true);
+
+ mController.updateState(preference, specialDnd);
+
+ verify(preference).setEnabled(false);
+ }
+
+ @Test
public void testUpdateState_disabled() {
TwoStatePreference preference = mock(TwoStatePreference.class);
ZenMode zenMode = new TestModeBuilder()
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java
index 4148fa3..fa83f30 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java
@@ -16,6 +16,7 @@
package com.android.settings.notification.modes;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
import static android.provider.Settings.EXTRA_AUTOMATIC_ZEN_RULE_ID;
@@ -150,6 +151,20 @@
}
@Test
+ public void updateState_dnd_enabled() {
+ ZenMode dnd = TestModeBuilder.MANUAL_DND_ACTIVE;
+ mController.updateState(mPreference, dnd);
+ assertThat(mPreference.isEnabled()).isTrue();
+ }
+
+ @Test
+ public void updateState_specialDnd_disabled() {
+ ZenMode specialDnd = TestModeBuilder.manualDnd(INTERRUPTION_FILTER_NONE, true);
+ mController.updateState(mPreference, specialDnd);
+ assertThat(mPreference.isEnabled()).isFalse();
+ }
+
+ @Test
public void testUpdateState_disabled() {
ZenMode zenMode = new TestModeBuilder()
.setEnabled(false)
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceControllerTest.java
index 7cf0109..05486e0 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceControllerTest.java
@@ -16,6 +16,8 @@
package com.android.settings.notification.modes;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -64,6 +66,26 @@
}
@Test
+ public void updateState_dnd_enabled() {
+ Preference preference = mock(Preference.class);
+ ZenMode dnd = TestModeBuilder.MANUAL_DND_ACTIVE;
+
+ mController.updateState(preference, dnd);
+
+ verify(preference).setEnabled(true);
+ }
+
+ @Test
+ public void updateState_specialDnd_disabled() {
+ Preference preference = mock(Preference.class);
+ ZenMode specialDnd = TestModeBuilder.manualDnd(INTERRUPTION_FILTER_NONE, true);
+
+ mController.updateState(preference, specialDnd);
+
+ verify(preference).setEnabled(false);
+ }
+
+ @Test
public void testUpdateState_disabled() {
Preference preference = mock(Preference.class);
ZenMode zenMode = new TestModeBuilder()
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeExitAtAlarmPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeExitAtAlarmPreferenceControllerTest.java
index 3efa5f0..c949fb8 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeExitAtAlarmPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeExitAtAlarmPreferenceControllerTest.java
@@ -16,6 +16,8 @@
package com.android.settings.notification.modes;
+import static android.service.notification.SystemZenRules.PACKAGE_ANDROID;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
@@ -77,6 +79,7 @@
scheduleInfo.exitAtAlarm = false;
ZenMode mode = new TestModeBuilder()
+ .setPackage(PACKAGE_ANDROID)
.setConditionId(ZenModeConfig.toScheduleConditionId(scheduleInfo))
.build();
@@ -105,6 +108,7 @@
scheduleInfo.exitAtAlarm = true;
ZenMode mode = new TestModeBuilder()
+ .setPackage(PACKAGE_ANDROID)
.setConditionId(ZenModeConfig.toScheduleConditionId(scheduleInfo))
.build();
mPrefController.updateZenMode(preference, mode);
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceControllerTest.java
index 3db70fa..38790b2 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceControllerTest.java
@@ -16,6 +16,8 @@
package com.android.settings.notification.modes;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock;
@@ -62,6 +64,26 @@
}
@Test
+ public void updateState_dnd_enabled() {
+ CircularIconsPreference preference = mock(CircularIconsPreference.class);
+ ZenMode dnd = TestModeBuilder.MANUAL_DND_ACTIVE;
+
+ mController.updateState(preference, dnd);
+
+ verify(preference).setEnabled(true);
+ }
+
+ @Test
+ public void updateState_specialDnd_disabled() {
+ CircularIconsPreference preference = mock(CircularIconsPreference.class);
+ ZenMode specialDnd = TestModeBuilder.manualDnd(INTERRUPTION_FILTER_NONE, true);
+
+ mController.updateState(preference, specialDnd);
+
+ verify(preference).setEnabled(false);
+ }
+
+ @Test
public void updateState_disabled() {
CircularIconsPreference pref = mock(CircularIconsPreference.class);
ZenMode zenMode = new TestModeBuilder()
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceControllerTest.java
index 8555d71..85fd004 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceControllerTest.java
@@ -16,6 +16,7 @@
package com.android.settings.notification.modes;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_IMPORTANT;
import static android.service.notification.ZenPolicy.PEOPLE_TYPE_ANYONE;
import static android.service.notification.ZenPolicy.PEOPLE_TYPE_CONTACTS;
@@ -117,6 +118,20 @@
}
@Test
+ public void updateState_dnd_enabled() {
+ ZenMode dnd = TestModeBuilder.MANUAL_DND_ACTIVE;
+ mController.updateState(mPreference, dnd);
+ assertThat(mPreference.isEnabled()).isTrue();
+ }
+
+ @Test
+ public void updateState_specialDnd_disabled() {
+ ZenMode specialDnd = TestModeBuilder.manualDnd(INTERRUPTION_FILTER_NONE, true);
+ mController.updateState(mPreference, specialDnd);
+ assertThat(mPreference.isEnabled()).isFalse();
+ }
+
+ @Test
public void updateState_disabled() {
ZenMode zenMode = new TestModeBuilder()
.setEnabled(false)