Merge "[Use] Replace settings LocalePreference with androidx LocalePreference" into udc-dev
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 836806c..4e85cb8 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -2,6 +2,20 @@
"presubmit": [
{
"name": "SettingsSpaUnitTests"
+ },
+ {
+ "name": "SettingsUnitTests",
+ "options": [
+ {
+ "include-filter": "com.android.settings.password"
+ },
+ {
+ "include-filter": "com.android.settings.biometrics"
+ },
+ {
+ "include-filter": "com.android.settings.biometrics2"
+ }
+ ]
}
],
"postsubmit": [
diff --git a/protos/fuelgauge_log.proto b/protos/fuelgauge_log.proto
index 8512cb8..150c2e2 100644
--- a/protos/fuelgauge_log.proto
+++ b/protos/fuelgauge_log.proto
@@ -20,6 +20,7 @@
RESET = 3;
RESTORE = 4;
BACKUP = 5;
+ FORCE_RESET = 6;
}
optional string package_name = 1;
diff --git a/res/drawable/ic_check_circle_filled_24dp.xml b/res/drawable/ic_check_circle_filled_24dp.xml
index 9d2e296..507bf67 100644
--- a/res/drawable/ic_check_circle_filled_24dp.xml
+++ b/res/drawable/ic_check_circle_filled_24dp.xml
@@ -20,7 +20,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?androidprv:attr/materialColorPrimaryContainer">
+ android:tint="?android:attr/colorPrimary">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10c5.52,0 10,-4.48 10,-10S17.52,2 12,2zM10.59,16.6l-4.24,-4.24l1.41,-1.41l2.83,2.83l5.66,-5.66l1.41,1.41L10.59,16.6z"/>
diff --git a/res/values/config.xml b/res/values/config.xml
index 52d7183..334d4e5 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -526,6 +526,10 @@
<item>content://com.android.settings.slices/intent/media_output_indicator</item>
</string-array>
+ <!-- List containing the apps cannot be changed the battery optimize modes -->
+ <string-array name="config_disable_optimization_mode_apps" translatable="false">
+ </string-array>
+
<!-- Uri to query non-public Slice Uris. -->
<string name="config_non_public_slice_query_uri" translatable="false"></string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index add226a..405960b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -129,7 +129,9 @@
<!-- Title for all hearing devices related controls section. [CHAR LIMIT=60] -->
<string name="bluetooth_device_controls_general">For all available hearing devices</string>
<!-- Connected devices settings. Title of the preference to show the entrance of the hearing device controls related page. [CHAR LIMIT=65] -->
- <string name="bluetooth_device_controls_title">Shortcuts & hearing aid compatibility</string>
+ <string name="bluetooth_device_controls_title">Hearing device settings</string>
+ <!-- Connected devices settings. Title of the preference to show the entrance of the hearing device controls related page. [CHAR LIMIT=65] -->
+ <string name="bluetooth_device_controls_summary">Audio output, shortcut, hearing aid compatibility</string>
<!-- Title for this device specific controls section. [CHAR LIMIT=30] -->
<string name="bluetooth_device_controls_specific">For this device</string>
<!-- Connected devices settings. Title of the preference to show the entrance of the audio output page. It can change different types of audio are played on phone or other bluetooth devices. [CHAR LIMIT=35] -->
@@ -5877,12 +5879,8 @@
<string name="add_account_label">Add account</string>
<!-- Label for the state of the work profile [CHAR LIMIT=80] -->
<string name="managed_profile_not_available_label">Work profile isn\u2019t available yet</string>
- <!-- This string is the title of a setting. If a user taps the setting, they can turn their work profile on or off. The work profile is a section of their phone that's managed by their employer. "Work" is an adjective. -->
- <string name="work_mode_label">Work profile</string>
- <!-- This string is located under a setting and describes what the setting does. It's letting a user know whether their work profile is on or off, and they can use the setting to turn it on or off. The work profile is a section of their phone that's managed by their employer. "Work" is an adjective.-->
- <string name="work_mode_on_summary">Managed by your organization</string>
- <!-- This string is located under a setting and describes what the setting does. It's letting a user know whether their work profile is on or off, and they can use the setting to turn it on or off. The work profile is a section of their phone that's managed by their employer. "Work" is an adjective.-->
- <string name="work_mode_off_summary">Apps and notifications are off</string>
+ <!-- This string is the title of a setting. If a user taps the setting, they can turn their work apps on or off. The work apps are a group of apps that are managed by the the user's employer. While this setting is off, the user cannot interact with those apps or get notifications from them. "Work" is an adjective. -->
+ <string name="work_mode_label">Work apps</string>
<!-- Button label to remove the work profile [CHAR LIMIT=35] -->
<string name="remove_managed_profile_label">Remove work profile</string>
<!-- Data synchronization settings screen, title of setting that controls whether background data should be used [CHAR LIMIT=30] -->
@@ -7175,7 +7173,7 @@
<string name="docking_sounds_title">Docking sounds</string>
<!-- Sound: Other sounds: Title for the option enabling touch sounds. [CHAR LIMIT=30] -->
- <string name="touch_sounds_title">Touch sounds</string>
+ <string name="touch_sounds_title">Tap & click sounds</string>
<!-- Sound: Other sounds: Title for the option enabling the vibrate icon. [CHAR LIMIT=50] -->
<string name="vibrate_icon_title">Always show icon when in vibrate mode</string>
@@ -9783,6 +9781,8 @@
<string name="cross_profile_calendar_title">Cross-profile calendar</string>
<!-- [CHAR LIMIT=NONE] Setting description. If the user turns on this setting, they can see their work events on their personal calendar. -->
<string name="cross_profile_calendar_summary">Show work events on your personal calendar</string>
+ <!-- [CHAR_LIMIT_NONE] Footer description. Explains to the user what will happen when work apps are turned off. -->
+ <string name="managed_profile_settings_footer">When work apps are off, they’re paused and can’t be accessed or send you notifications</string>
<!-- Used as title on the automatic storage manager settings. [CHAR LIMIT=60] -->
<string name="automatic_storage_manager_settings">Manage storage</string>
diff --git a/res/xml/bluetooth_audio_routing_fragment.xml b/res/xml/accessibility_audio_routing_fragment.xml
similarity index 85%
rename from res/xml/bluetooth_audio_routing_fragment.xml
rename to res/xml/accessibility_audio_routing_fragment.xml
index 5edf6cd..12e75f2 100644
--- a/res/xml/bluetooth_audio_routing_fragment.xml
+++ b/res/xml/accessibility_audio_routing_fragment.xml
@@ -31,7 +31,7 @@
android:key="audio_routing_ringtone"
android:persistent="false"
android:title="@string/bluetooth_ringtone_title"
- settings:controller="com.android.settings.bluetooth.HearingDeviceRingtoneRoutingPreferenceController" />
+ settings:controller="com.android.settings.accessibility.HearingDeviceRingtoneRoutingPreferenceController" />
<ListPreference
android:entries="@array/bluetooth_audio_routing_titles"
@@ -40,7 +40,7 @@
android:key="audio_routing_call"
android:persistent="false"
android:title="@string/bluetooth_call_title"
- settings:controller="com.android.settings.bluetooth.HearingDeviceCallRoutingPreferenceController" />
+ settings:controller="com.android.settings.accessibility.HearingDeviceCallRoutingPreferenceController" />
<ListPreference
android:entries="@array/bluetooth_audio_routing_titles"
@@ -49,7 +49,7 @@
android:key="audio_routing_media"
android:persistent="false"
android:title="@string/bluetooth_media_title"
- settings:controller="com.android.settings.bluetooth.HearingDeviceMediaRoutingPreferenceController" />
+ settings:controller="com.android.settings.accessibility.HearingDeviceMediaRoutingPreferenceController" />
<ListPreference
android:entries="@array/bluetooth_audio_routing_titles"
@@ -58,7 +58,7 @@
android:key="audio_routing_system_sounds"
android:persistent="false"
android:title="@string/bluetooth_system_sounds_title"
- settings:controller="com.android.settings.bluetooth.HearingDeviceSystemSoundsRoutingPreferenceController" />
+ settings:controller="com.android.settings.accessibility.HearingDeviceSystemSoundsRoutingPreferenceController" />
<com.android.settings.accessibility.AccessibilityFooterPreference
android:key="hearing_device_footer"
diff --git a/res/xml/accessibility_hearing_aids.xml b/res/xml/accessibility_hearing_aids.xml
index e813cf2..b13eb74 100644
--- a/res/xml/accessibility_hearing_aids.xml
+++ b/res/xml/accessibility_hearing_aids.xml
@@ -45,8 +45,17 @@
<PreferenceCategory
android:key="hearing_options_category"
android:title="@string/accessibility_screen_option">
+
+ <Preference
+ android:key="audio_routing"
+ android:title="@string/bluetooth_audio_routing_title"
+ android:summary="@string/bluetooth_audio_routing_summary"
+ android:fragment="com.android.settings.accessibility.AccessibilityAudioRoutingFragment"
+ settings:controller="com.android.settings.accessibility.HearingAidAudioRoutingPreferenceController"/>
+
<SwitchPreference
android:key="hearing_aid_compatibility"
+ android:order="30"
android:title="@string/accessibility_hac_mode_title"
android:summary="@string/accessibility_hac_mode_summary"
settings:searchable="true"
diff --git a/res/xml/bluetooth_device_details_fragment.xml b/res/xml/bluetooth_device_details_fragment.xml
index 8d74a39..35359f7 100644
--- a/res/xml/bluetooth_device_details_fragment.xml
+++ b/res/xml/bluetooth_device_details_fragment.xml
@@ -69,12 +69,7 @@
android:key="device_companion_apps"/>
<PreferenceCategory
- android:key="device_controls_general"
- android:title="@string/bluetooth_device_controls_general"/>
-
- <PreferenceCategory
- android:key="device_controls_specific"
- android:title="@string/bluetooth_device_controls_specific"/>
+ android:key="device_controls_general" />
<PreferenceCategory
android:key="spatial_audio_group"/>
diff --git a/res/xml/managed_profile_settings.xml b/res/xml/managed_profile_settings.xml
index 20f6d3d..ddfb869 100644
--- a/res/xml/managed_profile_settings.xml
+++ b/res/xml/managed_profile_settings.xml
@@ -19,10 +19,9 @@
android:key="managed_profile_settings_screen"
android:title="@string/managed_profile_settings_title">
- <SwitchPreference
+ <com.android.settingslib.widget.MainSwitchPreference
android:key="work_mode"
android:title="@string/work_mode_label"
- android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.accounts.WorkModePreferenceController"/>
<com.android.settingslib.RestrictedSwitchPreference
@@ -38,4 +37,9 @@
android:title="@string/cross_profile_calendar_title"
settings:controller="com.android.settings.accounts.CrossProfileCalendarPreferenceController"/>
+ <com.android.settingslib.widget.FooterPreference
+ android:title="@string/managed_profile_settings_footer"
+ android:key="managed_profile_footer"
+ settings:searchable="false"/>
+
</PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/SettingsApplication.java b/src/com/android/settings/SettingsApplication.java
index 7d8055d..8c050ea 100644
--- a/src/com/android/settings/SettingsApplication.java
+++ b/src/com/android/settings/SettingsApplication.java
@@ -51,8 +51,9 @@
// Set Spa environment.
setSpaEnvironment();
- if (FeatureFlagUtils.isEnabled(this, FeatureFlagUtils.SETTINGS_SUPPORT_LARGE_SCREEN)
- && ActivityEmbeddingUtils.isSettingsSplitEnabled(this)) {
+ if (ActivityEmbeddingUtils.isSettingsSplitEnabled(this)
+ && FeatureFlagUtils.isEnabled(this,
+ FeatureFlagUtils.SETTINGS_SUPPORT_LARGE_SCREEN)) {
if (WizardManagerHelper.isUserSetupComplete(this)) {
new ActivityEmbeddingRulesController(this).initRules();
} else {
diff --git a/src/com/android/settings/accessibility/AccessibilityAudioRoutingFragment.java b/src/com/android/settings/accessibility/AccessibilityAudioRoutingFragment.java
new file mode 100644
index 0000000..6eb2112
--- /dev/null
+++ b/src/com/android/settings/accessibility/AccessibilityAudioRoutingFragment.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 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.accessibility;
+
+import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
+
+import android.app.settings.SettingsEnums;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.RestrictedDashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+
+/** Settings fragment containing bluetooth audio routing. */
+public class AccessibilityAudioRoutingFragment extends RestrictedDashboardFragment {
+ private static final String TAG = "AccessibilityAudioRoutingFragment";
+
+ public AccessibilityAudioRoutingFragment() {
+ super(DISALLOW_CONFIG_BLUETOOTH);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.HEARING_AID_AUDIO_ROUTING;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.accessibility_audio_routing_fragment;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider(R.xml.accessibility_audio_routing_fragment);
+}
diff --git a/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java b/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java
index cd76b47..e4611fe 100644
--- a/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java
+++ b/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java
@@ -17,7 +17,6 @@
package com.android.settings.accessibility;
import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHapClient;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothLeAudio;
@@ -41,20 +40,14 @@
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
-import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
-import com.android.settingslib.bluetooth.HapClientProfile;
import com.android.settingslib.bluetooth.HearingAidInfo;
-import com.android.settingslib.bluetooth.HearingAidProfile;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Set;
-import java.util.stream.Collectors;
/**
* Controller that shows and updates the bluetooth device name
@@ -73,10 +66,8 @@
};
private final LocalBluetoothManager mLocalBluetoothManager;
- private final BluetoothAdapter mBluetoothAdapter;
private final LocalBluetoothProfileManager mProfileManager;
- private final CachedBluetoothDeviceManager mCachedDeviceManager;
-
+ private final HearingAidHelper mHelper;
private FragmentManager mFragmentManager;
public AccessibilityHearingAidPreferenceController(Context context, String preferenceKey) {
@@ -84,8 +75,7 @@
mLocalBluetoothManager = com.android.settings.bluetooth.Utils.getLocalBluetoothManager(
context);
mProfileManager = mLocalBluetoothManager.getProfileManager();
- mCachedDeviceManager = mLocalBluetoothManager.getCachedDeviceManager();
- mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ mHelper = new HearingAidHelper(context);
}
@Override
@@ -96,7 +86,7 @@
@Override
public int getAvailabilityStatus() {
- return isHearingAidSupported() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ return mHelper.isHearingAidSupported() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
@@ -111,7 +101,7 @@
// Can't get connected hearing aids when hearing aids related profiles are not ready. The
// profiles will be ready after the services are connected. Needs to add listener and
// updates the information when all hearing aids related services are connected.
- if (isAnyHearingAidRelatedProfilesNotReady()) {
+ if (!mHelper.isAllHearingAidRelatedProfilesReady()) {
mProfileManager.addServiceListener(this);
}
}
@@ -126,7 +116,7 @@
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
- final CachedBluetoothDevice device = getConnectedHearingAidDevice();
+ final CachedBluetoothDevice device = mHelper.getConnectedHearingAidDevice();
if (FeatureFlagUtils.isEnabled(mContext,
FeatureFlagUtils.SETTINGS_ACCESSIBILITY_HEARING_AID_PAGE)) {
launchHearingAidPage();
@@ -144,10 +134,7 @@
@Override
public CharSequence getSummary() {
- if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
- return mContext.getText(R.string.accessibility_hearingaid_not_connected_summary);
- }
- final CachedBluetoothDevice device = getConnectedHearingAidDevice();
+ final CachedBluetoothDevice device = mHelper.getConnectedHearingAidDevice();
if (device == null) {
return mContext.getText(R.string.accessibility_hearingaid_not_connected_summary);
}
@@ -203,7 +190,7 @@
@Override
public void onServiceConnected() {
- if (!isAnyHearingAidRelatedProfilesNotReady()) {
+ if (mHelper.isAllHearingAidRelatedProfilesReady()) {
updateState(mHearingAidPreference);
mProfileManager.removeServiceListener(this);
}
@@ -218,53 +205,8 @@
mFragmentManager = fragmentManager;
}
- @VisibleForTesting
- CachedBluetoothDevice getConnectedHearingAidDevice() {
- final List<BluetoothDevice> deviceList = getConnectedHearingAidDeviceList();
- return deviceList.isEmpty() ? null : mCachedDeviceManager.findDevice(deviceList.get(0));
- }
-
private int getConnectedHearingAidDeviceNum() {
- return getConnectedHearingAidDeviceList().size();
- }
-
- private List<BluetoothDevice> getConnectedHearingAidDeviceList() {
- if (!isHearingAidSupported()) {
- return new ArrayList<>();
- }
- final List<BluetoothDevice> deviceList = new ArrayList<>();
- final HapClientProfile hapClientProfile = mProfileManager.getHapClientProfile();
- if (hapClientProfile != null) {
- deviceList.addAll(hapClientProfile.getConnectedDevices());
- }
- final HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile();
- if (hearingAidProfile != null) {
- deviceList.addAll(hearingAidProfile.getConnectedDevices());
- }
- return deviceList.stream()
- .distinct()
- .filter(d -> !mCachedDeviceManager.isSubDevice(d)).collect(Collectors.toList());
- }
-
- private boolean isHearingAidSupported() {
- if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
- return false;
- }
- final List<Integer> supportedList = mBluetoothAdapter.getSupportedProfiles();
- return supportedList.contains(BluetoothProfile.HEARING_AID)
- || supportedList.contains(BluetoothProfile.HAP_CLIENT);
- }
-
- private boolean isAnyHearingAidRelatedProfilesNotReady() {
- HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile();
- if (hearingAidProfile != null && !hearingAidProfile.isProfileReady()) {
- return true;
- }
- HapClientProfile hapClientProfile = mProfileManager.getHapClientProfile();
- if (hapClientProfile != null && !hapClientProfile.isProfileReady()) {
- return true;
- }
- return false;
+ return mHelper.getConnectedHearingAidDeviceList().size();
}
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
diff --git a/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java b/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java
index 547c456..33fef62 100644
--- a/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java
@@ -39,7 +39,7 @@
private static final String TAG = "AccessibilityHearingAidsFragment";
private static final String KEY_HEARING_OPTIONS_CATEGORY = "hearing_options_category";
- private static final int FIRST_PREFERENCE_IN_CATEGORY_INDEX = -1;
+ private static final int SHORTCUT_PREFERENCE_IN_CATEGORY_INDEX = 20;
private String mFeatureName;
public AccessibilityHearingAidsFragment() {
@@ -65,7 +65,7 @@
final View view = super.onCreateView(inflater, container, savedInstanceState);
final PreferenceCategory controlCategory = findPreference(KEY_HEARING_OPTIONS_CATEGORY);
// To move the shortcut preference under controlCategory need to remove the original added.
- mShortcutPreference.setOrder(FIRST_PREFERENCE_IN_CATEGORY_INDEX);
+ mShortcutPreference.setOrder(SHORTCUT_PREFERENCE_IN_CATEGORY_INDEX);
getPreferenceScreen().removePreference(mShortcutPreference);
controlCategory.addPreference(mShortcutPreference);
return view;
diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
index 01158bf..b414add 100644
--- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
@@ -322,6 +322,18 @@
getComponentName());
};
+ private static CharSequence getSoftwareShortcutTypeSummary(Context context) {
+ int resId;
+ if (AccessibilityUtil.isFloatingMenuEnabled(context)) {
+ resId = R.string.accessibility_shortcut_edit_summary_software;
+ } else if (AccessibilityUtil.isGestureNavigateEnabled(context)) {
+ resId = R.string.accessibility_shortcut_edit_summary_software_gesture;
+ } else {
+ resId = R.string.accessibility_shortcut_edit_summary_software;
+ }
+ return context.getText(resId);
+ }
+
/**
* This method will be invoked when a button in the tutorial dialog is clicked.
*
@@ -429,11 +441,9 @@
getComponentName().flattenToString(), AccessibilityUtil.UserShortcutType.SOFTWARE);
final List<CharSequence> list = new ArrayList<>();
- final CharSequence softwareTitle = context.getText(
- R.string.accessibility_shortcut_edit_summary_software);
if (hasShortcutType(shortcutTypes, AccessibilityUtil.UserShortcutType.SOFTWARE)) {
- list.add(softwareTitle);
+ list.add(getSoftwareShortcutTypeSummary(context));
}
if (hasShortcutType(shortcutTypes, AccessibilityUtil.UserShortcutType.HARDWARE)) {
final CharSequence hardwareTitle = context.getText(
@@ -443,7 +453,7 @@
// Show software shortcut if first time to use.
if (list.isEmpty()) {
- list.add(softwareTitle);
+ list.add(getSoftwareShortcutTypeSummary(context));
}
return CaseMap.toTitle().wholeString().noLowercase().apply(Locale.getDefault(), /* iter= */
diff --git a/src/com/android/settings/accessibility/HearingAidAudioRoutingPreferenceController.java b/src/com/android/settings/accessibility/HearingAidAudioRoutingPreferenceController.java
new file mode 100644
index 0000000..54022ef
--- /dev/null
+++ b/src/com/android/settings/accessibility/HearingAidAudioRoutingPreferenceController.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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.accessibility;
+
+import android.content.Context;
+import android.util.FeatureFlagUtils;
+
+import com.android.settings.core.BasePreferenceController;
+
+/**
+ * The controller of the audio routing.
+ */
+public class HearingAidAudioRoutingPreferenceController extends BasePreferenceController {
+ public HearingAidAudioRoutingPreferenceController(Context context,
+ String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_AUDIO_ROUTING)
+ ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ }
+}
diff --git a/src/com/android/settings/accessibility/HearingAidHelper.java b/src/com/android/settings/accessibility/HearingAidHelper.java
new file mode 100644
index 0000000..66a37f8
--- /dev/null
+++ b/src/com/android/settings/accessibility/HearingAidHelper.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2023 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.accessibility;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.HapClientProfile;
+import com.android.settingslib.bluetooth.HearingAidProfile;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * A helper class to get and check hearing aids and its status.
+ */
+public class HearingAidHelper {
+
+ private final BluetoothAdapter mBluetoothAdapter;
+ private final LocalBluetoothProfileManager mProfileManager;
+ private final CachedBluetoothDeviceManager mCachedDeviceManager;
+
+ public HearingAidHelper(Context context) {
+ final LocalBluetoothManager localBluetoothManager =
+ com.android.settings.bluetooth.Utils.getLocalBluetoothManager(context);
+ mProfileManager = localBluetoothManager.getProfileManager();
+ mCachedDeviceManager = localBluetoothManager.getCachedDeviceManager();
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ }
+
+ /**
+ * Gets the connected hearing aids device whose profiles are
+ * {@link BluetoothProfile#HEARING_AID} or {@link BluetoothProfile#HAP_CLIENT}.
+ *
+ * @return a list of hearing aids {@link BluetoothDevice} objects
+ */
+ public List<BluetoothDevice> getConnectedHearingAidDeviceList() {
+ if (!isHearingAidSupported()) {
+ return new ArrayList<>();
+ }
+ final List<BluetoothDevice> deviceList = new ArrayList<>();
+ final HapClientProfile hapClientProfile = mProfileManager.getHapClientProfile();
+ if (hapClientProfile != null) {
+ deviceList.addAll(hapClientProfile.getConnectedDevices());
+ }
+ final HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile();
+ if (hearingAidProfile != null) {
+ deviceList.addAll(hearingAidProfile.getConnectedDevices());
+ }
+ return deviceList.stream()
+ .distinct()
+ .filter(d -> !mCachedDeviceManager.isSubDevice(d)).collect(Collectors.toList());
+ }
+
+ /**
+ * Gets the first connected hearing aids device.
+ *
+ * @return a {@link CachedBluetoothDevice} that is hearing aids device
+ */
+ public CachedBluetoothDevice getConnectedHearingAidDevice() {
+ final List<BluetoothDevice> deviceList = getConnectedHearingAidDeviceList();
+ return deviceList.isEmpty() ? null : mCachedDeviceManager.findDevice(deviceList.get(0));
+ }
+
+ /**
+ * Checks if {@link BluetoothProfile#HEARING_AID} or {@link BluetoothProfile#HAP_CLIENT}
+ * supported.
+ */
+ public boolean isHearingAidSupported() {
+ if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
+ return false;
+ }
+ final List<Integer> supportedList = mBluetoothAdapter.getSupportedProfiles();
+ return supportedList.contains(BluetoothProfile.HEARING_AID)
+ || supportedList.contains(BluetoothProfile.HAP_CLIENT);
+ }
+
+ /**
+ * Checks if {@link BluetoothProfile#HEARING_AID} or {@link BluetoothProfile#HAP_CLIENT}
+ * profiles all ready.
+ */
+ public boolean isAllHearingAidRelatedProfilesReady() {
+ HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile();
+ if (hearingAidProfile != null && !hearingAidProfile.isProfileReady()) {
+ return false;
+ }
+ HapClientProfile hapClientProfile = mProfileManager.getHapClientProfile();
+ if (hapClientProfile != null && !hapClientProfile.isProfileReady()) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/src/com/android/settings/bluetooth/HearingDeviceAudioRoutingBasePreferenceController.java b/src/com/android/settings/accessibility/HearingDeviceAudioRoutingBasePreferenceController.java
similarity index 79%
rename from src/com/android/settings/bluetooth/HearingDeviceAudioRoutingBasePreferenceController.java
rename to src/com/android/settings/accessibility/HearingDeviceAudioRoutingBasePreferenceController.java
index e93863a..3599f48 100644
--- a/src/com/android/settings/bluetooth/HearingDeviceAudioRoutingBasePreferenceController.java
+++ b/src/com/android/settings/accessibility/HearingDeviceAudioRoutingBasePreferenceController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.bluetooth;
+package com.android.settings.accessibility;
import android.content.ContentResolver;
import android.content.Context;
@@ -47,19 +47,24 @@
private static final String TAG = "HARoutingBasePreferenceController";
private static final boolean DEBUG = false;
- private final HearingAidAudioRoutingHelper mHelper;
+ private final HearingAidAudioRoutingHelper mAudioRoutingHelper;
+ private final HearingAidHelper mHearingAidHelper;
public HearingDeviceAudioRoutingBasePreferenceController(Context context,
String preferenceKey) {
- super(context, preferenceKey);
- mHelper = new HearingAidAudioRoutingHelper(context);
+ this(context, preferenceKey,
+ new HearingAidAudioRoutingHelper(context),
+ new HearingAidHelper(context));
}
@VisibleForTesting
public HearingDeviceAudioRoutingBasePreferenceController(Context context,
- String preferenceKey, HearingAidAudioRoutingHelper helper) {
+ String preferenceKey, HearingAidAudioRoutingHelper audioRoutingHelper,
+ HearingAidHelper hearingAidHelper) {
super(context, preferenceKey);
- mHelper = helper;
+
+ mAudioRoutingHelper = audioRoutingHelper;
+ mHearingAidHelper = hearingAidHelper;
}
@Override
@@ -81,7 +86,11 @@
final Integer routingValue = Ints.tryParse((String) newValue);
saveRoutingValue(mContext, routingValue);
- trySetAudioRoutingConfig(getSupportedAttributeList(), getHearingDevice(), routingValue);
+ final CachedBluetoothDevice device = mHearingAidHelper.getConnectedHearingAidDevice();
+ if (device != null) {
+ trySetAudioRoutingConfig(getSupportedAttributeList(),
+ mHearingAidHelper.getConnectedHearingAidDevice(), routingValue);
+ }
return true;
}
@@ -89,10 +98,10 @@
private void trySetAudioRoutingConfig(int[] audioAttributes,
CachedBluetoothDevice hearingDevice,
@HearingAidAudioRoutingConstants.RoutingValue int routingValue) {
- final List<AudioProductStrategy> supportedStrategies = mHelper.getSupportedStrategies(
- audioAttributes);
+ final List<AudioProductStrategy> supportedStrategies =
+ mAudioRoutingHelper.getSupportedStrategies(audioAttributes);
final AudioDeviceAttributes hearingDeviceAttributes =
- mHelper.getMatchedHearingDeviceAttributes(hearingDevice);
+ mAudioRoutingHelper.getMatchedHearingDeviceAttributes(hearingDevice);
if (hearingDeviceAttributes == null) {
if (DEBUG) {
Log.d(TAG,
@@ -103,8 +112,8 @@
return;
}
- final boolean status = mHelper.setPreferredDeviceRoutingStrategies(supportedStrategies,
- hearingDeviceAttributes, routingValue);
+ final boolean status = mAudioRoutingHelper.setPreferredDeviceRoutingStrategies(
+ supportedStrategies, hearingDeviceAttributes, routingValue);
if (!status) {
final List<String> strategiesName = supportedStrategies.stream()
@@ -122,12 +131,6 @@
protected abstract int[] getSupportedAttributeList();
/**
- * Gets the {@link CachedBluetoothDevice} hearing device that is used to configure audio
- * routing.
- */
- protected abstract CachedBluetoothDevice getHearingDevice();
-
- /**
* Saves the routing value.
*
* @param context the valid context used to get the {@link ContentResolver}
diff --git a/src/com/android/settings/bluetooth/HearingDeviceCallRoutingPreferenceController.java b/src/com/android/settings/accessibility/HearingDeviceCallRoutingPreferenceController.java
similarity index 81%
rename from src/com/android/settings/bluetooth/HearingDeviceCallRoutingPreferenceController.java
rename to src/com/android/settings/accessibility/HearingDeviceCallRoutingPreferenceController.java
index 4e5e193..8ca2663 100644
--- a/src/com/android/settings/bluetooth/HearingDeviceCallRoutingPreferenceController.java
+++ b/src/com/android/settings/accessibility/HearingDeviceCallRoutingPreferenceController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.bluetooth;
+package com.android.settings.accessibility;
import android.content.Context;
import android.provider.Settings;
@@ -35,15 +35,6 @@
super(context, preferenceKey);
}
- /**
- * Initializes objects in this controller. Need to call this before using the controller.
- *
- * @param cachedBluetoothDevice the hearing device to configure audio routing
- */
- public void init(CachedBluetoothDevice cachedBluetoothDevice) {
- mHearingDevice = cachedBluetoothDevice;
- }
-
@Override
public int getAvailabilityStatus() {
return Utils.isVoiceCapable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
@@ -55,11 +46,6 @@
}
@Override
- protected CachedBluetoothDevice getHearingDevice() {
- return mHearingDevice;
- }
-
- @Override
protected void saveRoutingValue(Context context, int routingValue) {
Settings.Secure.putInt(context.getContentResolver(),
Settings.Secure.HEARING_AID_CALL_ROUTING, routingValue);
diff --git a/src/com/android/settings/bluetooth/HearingDeviceMediaRoutingPreferenceController.java b/src/com/android/settings/accessibility/HearingDeviceMediaRoutingPreferenceController.java
similarity index 79%
rename from src/com/android/settings/bluetooth/HearingDeviceMediaRoutingPreferenceController.java
rename to src/com/android/settings/accessibility/HearingDeviceMediaRoutingPreferenceController.java
index 1ea36c7..cd99ce0 100644
--- a/src/com/android/settings/bluetooth/HearingDeviceMediaRoutingPreferenceController.java
+++ b/src/com/android/settings/accessibility/HearingDeviceMediaRoutingPreferenceController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.bluetooth;
+package com.android.settings.accessibility;
import android.content.Context;
import android.provider.Settings;
@@ -34,15 +34,6 @@
super(context, preferenceKey);
}
- /**
- * Initializes objects in this controller. Need to call this before using the controller.
- *
- * @param cachedBluetoothDevice the hearing device to configure audio routing
- */
- public void init(CachedBluetoothDevice cachedBluetoothDevice) {
- mHearingDevice = cachedBluetoothDevice;
- }
-
@Override
protected int[] getSupportedAttributeList() {
return HearingAidAudioRoutingConstants.MEDIA_ROUTING_ATTRIBUTES;
@@ -50,11 +41,6 @@
}
@Override
- protected CachedBluetoothDevice getHearingDevice() {
- return mHearingDevice;
- }
-
- @Override
protected void saveRoutingValue(Context context, int routingValue) {
Settings.Secure.putInt(context.getContentResolver(),
Settings.Secure.HEARING_AID_MEDIA_ROUTING, routingValue);
diff --git a/src/com/android/settings/bluetooth/HearingDeviceRingtoneRoutingPreferenceController.java b/src/com/android/settings/accessibility/HearingDeviceRingtoneRoutingPreferenceController.java
similarity index 79%
rename from src/com/android/settings/bluetooth/HearingDeviceRingtoneRoutingPreferenceController.java
rename to src/com/android/settings/accessibility/HearingDeviceRingtoneRoutingPreferenceController.java
index 006cb6b..3e8f79c 100644
--- a/src/com/android/settings/bluetooth/HearingDeviceRingtoneRoutingPreferenceController.java
+++ b/src/com/android/settings/accessibility/HearingDeviceRingtoneRoutingPreferenceController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.bluetooth;
+package com.android.settings.accessibility;
import android.content.Context;
import android.provider.Settings;
@@ -34,15 +34,6 @@
super(context, preferenceKey);
}
- /**
- * Initializes objects in this controller. Need to call this before using the controller.
- *
- * @param cachedBluetoothDevice the hearing device to configure audio routing
- */
- public void init(CachedBluetoothDevice cachedBluetoothDevice) {
- mHearingDevice = cachedBluetoothDevice;
- }
-
@Override
protected int[] getSupportedAttributeList() {
return HearingAidAudioRoutingConstants.RINGTONE_ROUTING_ATTRIBUTE;
@@ -50,11 +41,6 @@
}
@Override
- protected CachedBluetoothDevice getHearingDevice() {
- return mHearingDevice;
- }
-
- @Override
protected void saveRoutingValue(Context context, int routingValue) {
Settings.Secure.putInt(context.getContentResolver(),
Settings.Secure.HEARING_AID_RINGTONE_ROUTING, routingValue);
diff --git a/src/com/android/settings/bluetooth/HearingDeviceSystemSoundsRoutingPreferenceController.java b/src/com/android/settings/accessibility/HearingDeviceSystemSoundsRoutingPreferenceController.java
similarity index 80%
rename from src/com/android/settings/bluetooth/HearingDeviceSystemSoundsRoutingPreferenceController.java
rename to src/com/android/settings/accessibility/HearingDeviceSystemSoundsRoutingPreferenceController.java
index a66cfab..1bc0090 100644
--- a/src/com/android/settings/bluetooth/HearingDeviceSystemSoundsRoutingPreferenceController.java
+++ b/src/com/android/settings/accessibility/HearingDeviceSystemSoundsRoutingPreferenceController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.bluetooth;
+package com.android.settings.accessibility;
import android.content.Context;
import android.provider.Settings;
@@ -35,15 +35,6 @@
super(context, preferenceKey);
}
- /**
- * Initializes objects in this controller. Need to call this before using the controller.
- *
- * @param cachedBluetoothDevice the hearing device to configure audio routing
- */
- public void init(CachedBluetoothDevice cachedBluetoothDevice) {
- mHearingDevice = cachedBluetoothDevice;
- }
-
@Override
protected int[] getSupportedAttributeList() {
return HearingAidAudioRoutingConstants.SYSTEM_SOUNDS_ROUTING_ATTRIBUTES;
@@ -51,11 +42,6 @@
}
@Override
- protected CachedBluetoothDevice getHearingDevice() {
- return mHearingDevice;
- }
-
- @Override
protected void saveRoutingValue(Context context, int routingValue) {
Settings.Secure.putInt(context.getContentResolver(),
Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING, routingValue);
diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
index 2011725..1270671 100644
--- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
@@ -249,12 +249,18 @@
super.onProcessArguments(arguments);
}
- private void addAlwaysOnSetting(PreferenceCategory generalCategory) {
- if (!DeviceConfig.getBoolean(
+ private boolean isAlwaysOnSettingEnabled() {
+ final boolean defaultValue = getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_magnification_always_on_enabled);
+
+ return DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_WINDOW_MANAGER,
"AlwaysOnMagnifier__enable_always_on_magnifier",
- false
- )) {
+ defaultValue
+ );
+ }
+ private void addAlwaysOnSetting(PreferenceCategory generalCategory) {
+ if (!isAlwaysOnSettingEnabled()) {
return;
}
diff --git a/src/com/android/settings/accounts/ContactSearchPreferenceController.java b/src/com/android/settings/accounts/ContactSearchPreferenceController.java
index 5e4ef48..87dabd8 100644
--- a/src/com/android/settings/accounts/ContactSearchPreferenceController.java
+++ b/src/com/android/settings/accounts/ContactSearchPreferenceController.java
@@ -20,37 +20,38 @@
import android.os.UserManager;
import android.provider.Settings;
-import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.DefaultLifecycleObserver;
+import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import com.android.settings.R;
import com.android.settings.Utils;
-import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.TogglePreferenceController;
import com.android.settings.slices.SliceData;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedSwitchPreference;
-public class ContactSearchPreferenceController extends BasePreferenceController implements
- Preference.OnPreferenceChangeListener {
+import org.jetbrains.annotations.NotNull;
- private UserHandle mManagedUser;
+public class ContactSearchPreferenceController extends TogglePreferenceController implements
+ Preference.OnPreferenceChangeListener, DefaultLifecycleObserver,
+ ManagedProfileQuietModeEnabler.QuietModeChangeListener {
+
+ private final ManagedProfileQuietModeEnabler mQuietModeEnabler;
+ private final UserHandle mManagedUser;
+ private Preference mPreference;
public ContactSearchPreferenceController(Context context, String key) {
super(context, key);
- // Set default managed profile for the current user, otherwise isAvailable will be false and
- // the setting won't be searchable.
- UserManager userManager = context.getSystemService(UserManager.class);
- mManagedUser = Utils.getManagedProfile(userManager);
- }
-
- @VisibleForTesting
- void setManagedUser(UserHandle managedUser) {
- mManagedUser = managedUser;
+ mManagedUser = Utils.getManagedProfile(context.getSystemService(UserManager.class));
+ mQuietModeEnabler = new ManagedProfileQuietModeEnabler(context, this);
}
@Override
public int getAvailabilityStatus() {
- return (mManagedUser != null) ? AVAILABLE : DISABLED_FOR_USER;
+ return mQuietModeEnabler.isAvailable() ? AVAILABLE : DISABLED_FOR_USER;
}
@Override
@@ -59,6 +60,7 @@
if (preference instanceof RestrictedSwitchPreference) {
final RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
pref.setChecked(isChecked());
+ pref.setEnabled(!mQuietModeEnabler.isQuietModeEnabled());
if (mManagedUser != null) {
final RestrictedLockUtils.EnforcedAdmin enforcedAdmin =
RestrictedLockUtilsInternal.checkIfRemoteContactSearchDisallowed(
@@ -68,26 +70,48 @@
}
}
- private boolean isChecked() {
- if (mManagedUser == null) {
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(getPreferenceKey());
+ updateState(mPreference);
+ }
+
+ @Override
+ public void onStart(@NotNull LifecycleOwner lifecycleOwner) {
+ lifecycleOwner.getLifecycle().addObserver(mQuietModeEnabler);
+ }
+
+ @Override
+ public void onStop(@NotNull LifecycleOwner lifecycleOwner) {
+ lifecycleOwner.getLifecycle().removeObserver(mQuietModeEnabler);
+ }
+
+ @Override
+ public boolean isChecked() {
+ if (mManagedUser == null || mQuietModeEnabler.isQuietModeEnabled()) {
return false;
}
return 0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, mManagedUser.getIdentifier());
}
- private boolean setChecked(boolean isChecked) {
- if (mManagedUser != null) {
- final int value = isChecked ? 1 : 0;
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, value, mManagedUser.getIdentifier());
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ if (mManagedUser == null || mQuietModeEnabler.isQuietModeEnabled()) {
+ return false;
}
+ final int value = isChecked ? 1 : 0;
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, value, mManagedUser.getIdentifier());
return true;
}
@Override
- public final boolean onPreferenceChange(Preference preference, Object newValue) {
- return setChecked((boolean) newValue);
+ public void onQuietModeChanged() {
+ if (mPreference != null) {
+ updateState(mPreference);
+ }
}
@Override
@@ -95,4 +119,9 @@
public int getSliceType() {
return SliceData.SliceType.SWITCH;
}
-}
\ No newline at end of file
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_accounts;
+ }
+}
diff --git a/src/com/android/settings/accounts/ManagedProfileQuietModeEnabler.java b/src/com/android/settings/accounts/ManagedProfileQuietModeEnabler.java
new file mode 100644
index 0000000..989be09
--- /dev/null
+++ b/src/com/android/settings/accounts/ManagedProfileQuietModeEnabler.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2023 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.accounts;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.DefaultLifecycleObserver;
+import androidx.lifecycle.LifecycleOwner;
+
+import com.android.settings.Utils;
+
+import javax.annotation.Nullable;
+
+/**
+ * A class that controls the managed profile's quiet mode, listens to quiet mode changes and
+ * modifies managed profile settings. The user facing term for quiet mode is "work apps".
+ */
+final class ManagedProfileQuietModeEnabler implements DefaultLifecycleObserver {
+
+ private static final String TAG = "QuietModeEnabler";
+ private final Context mContext;
+ private final QuietModeChangeListener mListener;
+ @Nullable private final UserHandle mManagedProfile;
+ private final UserManager mUserManager;
+
+ public interface QuietModeChangeListener {
+ /** Called when quiet mode has changed. */
+ void onQuietModeChanged();
+ }
+
+ ManagedProfileQuietModeEnabler(Context context, QuietModeChangeListener listener) {
+ mContext = context;
+ mListener = listener;
+ mUserManager = context.getSystemService(UserManager.class);
+ mManagedProfile = Utils.getManagedProfile(mUserManager);
+ }
+
+ public void setQuietModeEnabled(boolean enabled) {
+ if (mManagedProfile != null) {
+ mUserManager.requestQuietModeEnabled(enabled, mManagedProfile);
+ }
+ }
+
+ public boolean isQuietModeEnabled() {
+ return mManagedProfile != null && mUserManager.isQuietModeEnabled(mManagedProfile);
+ }
+
+ @Override
+ public void onStart(@NonNull LifecycleOwner owner) {
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
+ intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
+ mContext.registerReceiver(mReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED);
+ }
+
+ @Override
+ public void onStop(@NonNull LifecycleOwner owner) {
+ mContext.unregisterReceiver(mReceiver);
+ }
+
+ public boolean isAvailable() {
+ return (mManagedProfile != null);
+ }
+
+ private void refreshQuietMode() {
+ if (mListener != null) {
+ mListener.onQuietModeChanged();
+ }
+ }
+
+ /**
+ * Receiver that listens to {@link Intent#ACTION_MANAGED_PROFILE_AVAILABLE} and
+ * {@link Intent#ACTION_MANAGED_PROFILE_UNAVAILABLE}, and updates the work mode
+ */
+ @VisibleForTesting
+ final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent == null) {
+ return;
+ }
+ String action = intent.getAction();
+ Log.v(TAG, "Received broadcast: " + action);
+
+ if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action)
+ || Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action)) {
+ int intentUserIdentifier = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+ UserHandle.USER_NULL);
+ if (intentUserIdentifier == mManagedProfile.getIdentifier()) {
+ refreshQuietMode();
+ } else {
+ Log.w(TAG, "Managed profile broadcast ID: " + intentUserIdentifier
+ + " does not match managed user: " + mManagedProfile);
+ }
+ } else {
+ Log.w(TAG, "Cannot handle received broadcast: " + intent.getAction());
+ }
+ }
+ };
+}
diff --git a/src/com/android/settings/accounts/WorkModePreferenceController.java b/src/com/android/settings/accounts/WorkModePreferenceController.java
index 1941de4..a261afc 100644
--- a/src/com/android/settings/accounts/WorkModePreferenceController.java
+++ b/src/com/android/settings/accounts/WorkModePreferenceController.java
@@ -1,165 +1,90 @@
/*
* Copyright (C) 2018 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
+ * 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.
+ * 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.accounts;
-import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SETTING_OFF_SUMMARY;
-import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SETTING_ON_SUMMARY;
-
-import android.app.admin.DevicePolicyManager;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
-import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.DefaultLifecycleObserver;
+import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.TwoStatePreference;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
-import com.android.settings.Utils;
-import com.android.settings.core.BasePreferenceController;
import com.android.settings.slices.SliceData;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnStart;
-import com.android.settingslib.core.lifecycle.events.OnStop;
+import com.android.settings.widget.SettingsMainSwitchPreferenceController;
+import com.android.settingslib.widget.MainSwitchPreference;
-public class WorkModePreferenceController extends BasePreferenceController implements
- Preference.OnPreferenceChangeListener, LifecycleObserver, OnStart, OnStop {
+import org.jetbrains.annotations.NotNull;
- private static final String TAG = "WorkModeController";
- private UserManager mUserManager;
- private UserHandle mManagedUser;
- private DevicePolicyManager mDevicePolicyManager;
+public class WorkModePreferenceController extends SettingsMainSwitchPreferenceController
+ implements Preference.OnPreferenceChangeListener, DefaultLifecycleObserver,
+ ManagedProfileQuietModeEnabler.QuietModeChangeListener {
- private Preference mPreference;
- private IntentFilter mIntentFilter;
+ private final ManagedProfileQuietModeEnabler mQuietModeEnabler;
public WorkModePreferenceController(Context context, String key) {
super(context, key);
- mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
- mIntentFilter = new IntentFilter();
- mIntentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
- mIntentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
- // Set default managed profile for the current user, otherwise isAvailable will be false and
- // the setting won't be searchable.
- mManagedUser = Utils.getManagedProfile(mUserManager);
- }
-
- @VisibleForTesting
- void setManagedUser(UserHandle managedUser) {
- mManagedUser = managedUser;
- }
-
- @Override
- public void onStart() {
- mContext.registerReceiver(mReceiver, mIntentFilter,
- Context.RECEIVER_EXPORTED_UNAUDITED);
- }
-
- @Override
- public void onStop() {
- mContext.unregisterReceiver(mReceiver);
+ mQuietModeEnabler = new ManagedProfileQuietModeEnabler(context, this);
}
@Override
public int getAvailabilityStatus() {
- return (mManagedUser != null) ? AVAILABLE : DISABLED_FOR_USER;
+ return (mQuietModeEnabler.isAvailable()) ? AVAILABLE : DISABLED_FOR_USER;
}
@Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- mPreference = screen.findPreference(getPreferenceKey());
+ public void onStart(@NotNull LifecycleOwner lifecycleOwner) {
+ lifecycleOwner.getLifecycle().addObserver(mQuietModeEnabler);
}
@Override
- public CharSequence getSummary() {
- if (isChecked()) {
- return mDevicePolicyManager.getResources().getString(
- WORK_PROFILE_SETTING_ON_SUMMARY,
- () -> mContext.getString(R.string.work_mode_on_summary));
- }
-
- return mDevicePolicyManager.getResources().getString(
- WORK_PROFILE_SETTING_OFF_SUMMARY,
- () -> mContext.getString(R.string.work_mode_off_summary));
+ public void onStop(@NotNull LifecycleOwner lifecycleOwner) {
+ lifecycleOwner.getLifecycle().removeObserver(mQuietModeEnabler);
}
- private boolean isChecked() {
- boolean isWorkModeOn = false;
- if (mUserManager != null && mManagedUser != null) {
- isWorkModeOn = !mUserManager.isQuietModeEnabled(mManagedUser);
- }
- return isWorkModeOn;
+ @Override
+ public boolean isChecked() {
+ return !mQuietModeEnabler.isQuietModeEnabled();
}
- private boolean setChecked(boolean isChecked) {
- if (mUserManager != null && mManagedUser != null) {
- final boolean quietModeEnabled = !isChecked;
- mUserManager.requestQuietModeEnabled(quietModeEnabled, mManagedUser);
- }
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ mQuietModeEnabler.setQuietModeEnabled(!isChecked);
return true;
}
@Override
- public void updateState(Preference preference) {
- super.updateState(preference);
- if (preference instanceof TwoStatePreference) {
- ((TwoStatePreference) preference).setChecked(isChecked());
- }
+ public void onQuietModeChanged() {
+ updateState(mSwitchPreference);
}
@Override
- public final boolean onPreferenceChange(Preference preference, Object newValue) {
- return setChecked((boolean) newValue);
- }
-
- /**
- * Receiver that listens to {@link Intent#ACTION_MANAGED_PROFILE_AVAILABLE} and
- * {@link Intent#ACTION_MANAGED_PROFILE_UNAVAILABLE}, and updates the work mode
- */
- @VisibleForTesting
- final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent == null) {
- return;
- }
- final String action = intent.getAction();
- Log.v(TAG, "Received broadcast: " + action);
-
- if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action)
- || Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action)) {
- if (intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
- UserHandle.USER_NULL) == mManagedUser.getIdentifier()) {
- updateState(mPreference);
- }
- return;
- }
- Log.w(TAG, "Cannot handle received broadcast: " + intent.getAction());
- }
- };
-
- @Override
@SliceData.SliceType
public int getSliceType() {
return SliceData.SliceType.SWITCH;
}
-}
\ No newline at end of file
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_accounts;
+ }
+
+ @VisibleForTesting
+ void setPreference(MainSwitchPreference preference) {
+ mSwitchPreference = preference;
+ }
+}
diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java b/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
index ae890f8..67d56e0 100644
--- a/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
+++ b/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
@@ -97,16 +97,24 @@
* </ul>
*/
public static boolean isEmbeddingActivityEnabled(Context context) {
- boolean isFlagEnabled = FeatureFlagUtils.isEnabled(context,
- FeatureFlagUtils.SETTINGS_SUPPORT_LARGE_SCREEN);
- boolean isSettingsSplitSupported = isSettingsSplitEnabled(context);
- boolean isUserSetupComplete = WizardManagerHelper.isUserSetupComplete(context);
-
- Log.d(TAG, "isFlagEnabled = " + isFlagEnabled);
- Log.d(TAG, "isSettingsSplitSupported = " + isSettingsSplitSupported);
- Log.d(TAG, "isUserSetupComplete = " + isUserSetupComplete);
-
- return isFlagEnabled && isSettingsSplitSupported && isUserSetupComplete;
+ // Activity Embedding feature is not enabled if Settings doesn't enable large screen
+ // optimization or the device is not supported.
+ if (!isSettingsSplitEnabled(context)) {
+ Log.d(TAG, "isSettingsSplitSupported = false");
+ return false;
+ }
+ // Activity Embedding feature is not enabled if a user chooses to disable the feature.
+ if (!FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_SUPPORT_LARGE_SCREEN)) {
+ Log.d(TAG, "isFlagEnabled = false");
+ return false;
+ }
+ // Don't enable Activity embedding for setup wizard.
+ if (!WizardManagerHelper.isUserSetupComplete(context)) {
+ Log.d(TAG, "isUserSetupComplete = false");
+ return false;
+ }
+ Log.d(TAG, "isEmbeddingActivityEnabled = true");
+ return true;
}
/** Whether to show the regular or simplified homepage layout. */
@@ -120,8 +128,7 @@
* Check if activity is already embedded
*/
public static boolean isAlreadyEmbedded(Activity activity) {
- return ActivityEmbeddingController
- .getInstance(activity)
- .isActivityEmbedded(activity);
+ return isEmbeddingActivityEnabled(activity) && ActivityEmbeddingController.getInstance(
+ activity).isActivityEmbedded(activity);
}
}
diff --git a/src/com/android/settings/applications/ClonedAppsPreferenceController.java b/src/com/android/settings/applications/ClonedAppsPreferenceController.java
index a8a79f4..332df18 100644
--- a/src/com/android/settings/applications/ClonedAppsPreferenceController.java
+++ b/src/com/android/settings/applications/ClonedAppsPreferenceController.java
@@ -75,6 +75,9 @@
}
private void updatePreferenceSummary() {
+ if (!isAvailable()) {
+ return;
+ }
new AsyncTask<Void, Void, Integer[]>() {
@Override
diff --git a/src/com/android/settings/applications/credentials/CombinedProviderInfo.java b/src/com/android/settings/applications/credentials/CombinedProviderInfo.java
index 1fd3075..074fb7b 100644
--- a/src/com/android/settings/applications/credentials/CombinedProviderInfo.java
+++ b/src/com/android/settings/applications/credentials/CombinedProviderInfo.java
@@ -51,7 +51,7 @@
@Nullable List<CredentialProviderInfo> cpis,
@Nullable AutofillServiceInfo asi,
boolean isDefaultAutofillProvider,
- boolean IsPrimaryCredmanProvider) {
+ boolean isPrimaryCredmanProvider) {
if (cpis == null) {
mCredentialProviderInfos = new ArrayList<>();
} else {
@@ -59,11 +59,11 @@
}
mAutofillServiceInfo = asi;
mIsDefaultAutofillProvider = isDefaultAutofillProvider;
- mIsPrimaryCredmanProvider = IsPrimaryCredmanProvider;
+ mIsPrimaryCredmanProvider = isPrimaryCredmanProvider;
}
/** Returns the credential provider info. */
- @Nullable
+ @NonNull
public List<CredentialProviderInfo> getCredentialProviderInfos() {
return mCredentialProviderInfos;
}
@@ -85,11 +85,13 @@
/** Returns the app icon. */
@Nullable
public Drawable getAppIcon(@NonNull Context context, int userId) {
- IconDrawableFactory factory = IconDrawableFactory.newInstance(context);
+ final IconDrawableFactory factory = IconDrawableFactory.newInstance(context);
+ final ServiceInfo brandingService = getBrandingService();
+ final ApplicationInfo appInfo = getApplicationInfo();
+
Drawable icon = null;
- ServiceInfo brandingService = getBrandingService();
- if (brandingService != null) {
- icon = factory.getBadgedIcon(brandingService, getApplicationInfo(), userId);
+ if (brandingService != null && appInfo != null) {
+ icon = factory.getBadgedIcon(brandingService, appInfo, userId);
}
// If the branding service gave us a icon then use that.
@@ -98,7 +100,10 @@
}
// Otherwise fallback to the app icon and then the package name.
- return factory.getBadgedIcon(getApplicationInfo(), userId);
+ if (appInfo != null) {
+ return factory.getBadgedIcon(appInfo, userId);
+ }
+ return null;
}
/** Returns the app name. */
@@ -116,11 +121,14 @@
}
// Otherwise fallback to the app label and then the package name.
- name = getApplicationInfo().loadLabel(context.getPackageManager());
- if (TextUtils.isEmpty(name)) {
- name = getApplicationInfo().packageName;
+ final ApplicationInfo appInfo = getApplicationInfo();
+ if (appInfo != null) {
+ name = appInfo.loadLabel(context.getPackageManager());
+ if (TextUtils.isEmpty(name)) {
+ return appInfo.packageName;
+ }
}
- return name;
+ return "";
}
/** Gets the service to use for branding (name, icons). */
@@ -245,8 +253,10 @@
// Now go through and build the joint datasets.
List<CombinedProviderInfo> cmpi = new ArrayList<>();
for (String packageName : packageNames) {
- List<AutofillServiceInfo> asi = autofillServices.get(packageName);
- List<CredentialProviderInfo> cpi = credmanServices.get(packageName);
+ List<AutofillServiceInfo> asi =
+ autofillServices.getOrDefault(packageName, new ArrayList<>());
+ List<CredentialProviderInfo> cpi =
+ credmanServices.getOrDefault(packageName, new ArrayList<>());
// If there are multiple autofill services then pick the first one.
AutofillServiceInfo selectedAsi = null;
diff --git a/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceController.java b/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceController.java
index 742faf1..59c33b2 100644
--- a/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceController.java
+++ b/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceController.java
@@ -35,6 +35,7 @@
import com.android.settings.applications.defaultapps.DefaultAppPreferenceController;
import com.android.settingslib.applications.DefaultAppInfo;
+import java.util.ArrayList;
import java.util.List;
public class DefaultCombinedPreferenceController extends DefaultAppPreferenceController {
@@ -110,15 +111,19 @@
private List<CombinedProviderInfo> getAllProviders(int userId) {
final List<AutofillServiceInfo> autofillProviders =
AutofillServiceInfo.getAvailableServices(mContext, userId);
- final List<CredentialProviderInfo> credManProviders =
- mCredentialManager.getCredentialProviderServices(
- userId, CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY);
final String selectedAutofillProvider =
Settings.Secure.getStringForUser(
mContext.getContentResolver(),
DefaultCombinedPicker.AUTOFILL_SETTING,
userId);
+ final List<CredentialProviderInfo> credManProviders = new ArrayList<>();
+ if (mCredentialManager != null) {
+ credManProviders.addAll(
+ mCredentialManager.getCredentialProviderServices(
+ userId, CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY));
+ }
+
return CombinedProviderInfo.buildMergedList(
autofillProviders, credManProviders, selectedAutofillProvider);
}
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index a6e6ac4..e0f1b5f 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -16,8 +16,6 @@
package com.android.settings.applications.manageapplications;
-import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_SPA;
-
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING;
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
@@ -67,7 +65,6 @@
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArraySet;
-import android.util.FeatureFlagUtils;
import android.util.IconDrawableFactory;
import android.util.Log;
import android.view.LayoutInflater;
@@ -728,9 +725,6 @@
R.string.long_background_tasks_label);
break;
case LIST_TYPE_CLONED_APPS:
- if (!FeatureFlagUtils.isEnabled(getContext(), SETTINGS_ENABLE_SPA)) {
- return;
- }
int userId = UserHandle.getUserId(mCurrentUid);
UserInfo userInfo = mUserManager.getUserInfo(userId);
if (userInfo != null && !userInfo.isCloneProfile()) {
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingController.java b/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingController.java
deleted file mode 100644
index 91221a3..0000000
--- a/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingController.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2022 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.bluetooth;
-
-import static com.android.settings.bluetooth.BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.util.FeatureFlagUtils;
-
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceFragmentCompat;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settingslib.bluetooth.CachedBluetoothDevice;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-/**
- * The controller of the audio routing in the bluetooth detail settings.
- */
-public class BluetoothDetailsAudioRoutingController extends BluetoothDetailsController {
-
- private static final String KEY_DEVICE_CONTROLS_SPECIFIC_GROUP = "device_controls_specific";
- @VisibleForTesting
- static final String KEY_AUDIO_ROUTING = "audio_routing";
-
- public BluetoothDetailsAudioRoutingController(Context context,
- PreferenceFragmentCompat fragment, CachedBluetoothDevice device, Lifecycle lifecycle) {
- super(context, fragment, device, lifecycle);
- }
-
- @Override
- public boolean isAvailable() {
- return mCachedDevice.isHearingAidDevice() && FeatureFlagUtils.isEnabled(mContext,
- FeatureFlagUtils.SETTINGS_AUDIO_ROUTING);
- }
-
- @Override
- protected void init(PreferenceScreen screen) {
- if (!mCachedDevice.isHearingAidDevice()) {
- return;
- }
-
- final PreferenceCategory prefCategory = screen.findPreference(getPreferenceKey());
- final Preference pref = createAudioRoutingPreference(prefCategory.getContext());
- prefCategory.addPreference(pref);
- }
-
- @Override
- protected void refresh() {}
-
- @Override
- public String getPreferenceKey() {
- return KEY_DEVICE_CONTROLS_SPECIFIC_GROUP;
- }
-
- private Preference createAudioRoutingPreference(Context context) {
- final Preference preference = new Preference(context);
-
- preference.setKey(KEY_AUDIO_ROUTING);
- preference.setTitle(context.getString(R.string.bluetooth_audio_routing_title));
- preference.setSummary(context.getString(R.string.bluetooth_audio_routing_summary));
- final Bundle extras = preference.getExtras();
- extras.putString(KEY_DEVICE_ADDRESS, mCachedDevice.getAddress());
- preference.setFragment(BluetoothDetailsAudioRoutingFragment.class.getName());
-
- return preference;
- }
-}
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragment.java b/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragment.java
deleted file mode 100644
index 6c435a2..0000000
--- a/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragment.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2023 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.bluetooth;
-
-import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
-
-import static com.android.settings.bluetooth.BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS;
-
-import android.app.settings.SettingsEnums;
-import android.bluetooth.BluetoothDevice;
-import android.content.Context;
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.settings.R;
-import com.android.settings.dashboard.RestrictedDashboardFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.bluetooth.CachedBluetoothDevice;
-import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
-
-/** Settings fragment containing bluetooth audio routing. */
-public class BluetoothDetailsAudioRoutingFragment extends RestrictedDashboardFragment {
-
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.bluetooth_audio_routing_fragment);
- private static final String TAG = "BluetoothDetailsAudioRoutingFragment";
- @VisibleForTesting
- CachedBluetoothDevice mCachedDevice;
-
- public BluetoothDetailsAudioRoutingFragment() {
- super(DISALLOW_CONFIG_BLUETOOTH);
- }
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- final LocalBluetoothManager localBtMgr = Utils.getLocalBtManager(context);
- final CachedBluetoothDeviceManager cachedDeviceMgr = localBtMgr.getCachedDeviceManager();
- final BluetoothDevice bluetoothDevice = localBtMgr.getBluetoothAdapter().getRemoteDevice(
- getArguments().getString(KEY_DEVICE_ADDRESS));
-
- mCachedDevice = cachedDeviceMgr.findDevice(bluetoothDevice);
- if (mCachedDevice == null) {
- // Close this page if device is null with invalid device mac address
- Log.w(TAG, "onAttach() CachedDevice is null! Can not find address: "
- + bluetoothDevice.getAnonymizedAddress());
- finish();
- return;
- }
-
- use(HearingDeviceRingtoneRoutingPreferenceController.class).init(mCachedDevice);
- use(HearingDeviceCallRoutingPreferenceController.class).init(mCachedDevice);
- use(HearingDeviceMediaRoutingPreferenceController.class).init(mCachedDevice);
- use(HearingDeviceSystemSoundsRoutingPreferenceController.class).init(mCachedDevice);
- }
-
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.BLUETOOTH_AUDIO_ROUTING;
- }
-
- @Override
- protected int getPreferenceScreenResId() {
- return R.xml.bluetooth_audio_routing_fragment;
- }
-
- @Override
- protected String getLogTag() {
- return TAG;
- }
-}
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsController.java b/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsController.java
index a3b1105..c4a4221 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsController.java
@@ -34,7 +34,7 @@
import com.google.common.annotations.VisibleForTesting;
/**
- * The controller of the hearing device controls in the bluetooth detail settings.
+ * The controller of the hearing device settings to launch Hearing device page.
*/
public class BluetoothDetailsHearingDeviceControlsController extends BluetoothDetailsController
implements Preference.OnPreferenceClickListener {
@@ -87,6 +87,7 @@
final Preference preference = new Preference(context);
preference.setKey(KEY_HEARING_DEVICE_CONTROLS);
preference.setTitle(context.getString(R.string.bluetooth_device_controls_title));
+ preference.setSummary(context.getString(R.string.bluetooth_device_controls_summary));
preference.setOnPreferenceClickListener(this);
return preference;
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java b/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java
index 2a94b1e..99f3e31 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java
@@ -314,8 +314,6 @@
lifecycle));
controllers.add(new BluetoothDetailsHearingDeviceControlsController(context, this,
mCachedDevice, lifecycle));
- controllers.add(new BluetoothDetailsAudioRoutingController(context, this, mCachedDevice,
- lifecycle));
}
return controllers;
}
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
index 17c5f36..2935c67 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
@@ -35,8 +35,10 @@
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -125,7 +127,7 @@
update(cachedBluetoothDevice);
}
} else {
- removeAllDevicesFromPreference();
+ removeAllDevicesFromPreference();
}
}
@@ -252,7 +254,7 @@
btPreference.setOnGearClickListener(mDeviceProfilesListener);
if (this instanceof Preference.OnPreferenceClickListener) {
btPreference.setOnPreferenceClickListener(
- (Preference.OnPreferenceClickListener)this);
+ (Preference.OnPreferenceClickListener) this);
}
mPreferenceMap.put(device, btPreference);
mDevicePreferenceCallback.onDeviceAdded(btPreference);
@@ -266,17 +268,20 @@
final BluetoothDevice device = cachedDevice.getDevice();
final CachedBluetoothDevice subCachedDevice = cachedDevice.getSubDevice();
if (mPreferenceMap.containsKey(device)) {
- mDevicePreferenceCallback.onDeviceRemoved(mPreferenceMap.get(device));
- mPreferenceMap.remove(device);
+ removePreference(device);
} else if (subCachedDevice != null) {
// When doing remove, to check if preference maps to sub device.
// This would happen when connection state is changed in detail page that there is no
// callback from SettingsLib.
final BluetoothDevice subDevice = subCachedDevice.getDevice();
- if (mPreferenceMap.containsKey(subDevice)) {
- mDevicePreferenceCallback.onDeviceRemoved(mPreferenceMap.get(subDevice));
- mPreferenceMap.remove(subDevice);
- }
+ removePreference(subDevice);
+ }
+ }
+
+ private void removePreference(BluetoothDevice device) {
+ if (mPreferenceMap.containsKey(device)) {
+ mDevicePreferenceCallback.onDeviceRemoved(mPreferenceMap.get(device));
+ mPreferenceMap.remove(device);
}
}
@@ -324,14 +329,38 @@
* Update the attributes of {@link Preference}.
*/
public void refreshPreference() {
- for (Preference preference : mPreferenceMap.values()) {
- ((BluetoothDevicePreference) preference).onPreferenceAttributesChanged();
+ List<BluetoothDevice> removeList = new ArrayList<>();
+ mPreferenceMap.forEach((key, preference) -> {
+ if (isDeviceOfMapInCachedDevicesList(key)) {
+ ((BluetoothDevicePreference) preference).onPreferenceAttributesChanged();
+ } else {
+ // If the BluetoothDevice of preference is not in the CachedDevices List, then
+ // remove this preference.
+ removeList.add(key);
+ }
+ });
+
+ for (BluetoothDevice bluetoothDevice : removeList) {
+ Log.d(getLogTag(), "removePreference key: " + bluetoothDevice.getAnonymizedAddress());
+ removePreference(bluetoothDevice);
}
}
- protected boolean isDeviceInCachedDevicesList(CachedBluetoothDevice cachedDevice){
+ protected boolean isDeviceInCachedDevicesList(CachedBluetoothDevice cachedDevice) {
return mLocalManager.getCachedDeviceManager().getCachedDevicesCopy().contains(cachedDevice);
}
+
+ private boolean isDeviceOfMapInCachedDevicesList(BluetoothDevice inputBluetoothDevice) {
+ Collection<CachedBluetoothDevice> cachedDevices =
+ mLocalManager.getCachedDeviceManager().getCachedDevicesCopy();
+ if (cachedDevices == null || cachedDevices.isEmpty()) {
+ return false;
+ }
+ return cachedDevices.stream()
+ .anyMatch(cachedBluetoothDevice -> cachedBluetoothDevice.getDevice() != null
+ && cachedBluetoothDevice.getDevice().equals(inputBluetoothDevice));
+ }
+
protected String getLogTag() {
return TAG;
}
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
index 777e428..79e0194 100644
--- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -343,7 +343,7 @@
final String stateString;
final String footerString;
- if (!mBatteryOptimizeUtils.isValidPackageName()) {
+ if (mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()) {
// Present optimized only string when the package name is invalid.
stateString = context.getString(R.string.manager_battery_usage_optimized_only);
footerString = context.getString(
diff --git a/src/com/android/settings/fuelgauge/BatteryBackupHelper.java b/src/com/android/settings/fuelgauge/BatteryBackupHelper.java
index 79df57a..eb4bbf6 100644
--- a/src/com/android/settings/fuelgauge/BatteryBackupHelper.java
+++ b/src/com/android/settings/fuelgauge/BatteryBackupHelper.java
@@ -55,7 +55,6 @@
static final String DELIMITER = ",";
static final String DELIMITER_MODE = ":";
- static final String KEY_FULL_POWER_LIST = "full_power_list";
static final String KEY_OPTIMIZATION_LIST = "optimization_mode_list";
@VisibleForTesting
@@ -83,7 +82,7 @@
Log.w(TAG, "ignore performBackup() for non-owner or empty data");
return;
}
- final List<String> allowlistedApps = backupFullPowerList(data);
+ final List<String> allowlistedApps = getFullPowerList();
if (allowlistedApps != null) {
backupOptimizationMode(data, allowlistedApps);
}
@@ -91,11 +90,12 @@
@Override
public void restoreEntity(BackupDataInputStream data) {
- BatterySettingsMigrateChecker.verifyConfiguration(mContext);
+ BatterySettingsMigrateChecker.verifySaverConfiguration(mContext);
if (!isOwner() || data == null || data.size() == 0) {
Log.w(TAG, "ignore restoreEntity() for non-owner or empty data");
return;
}
+
if (KEY_OPTIMIZATION_LIST.equals(data.getKey())) {
final int dataSize = data.size();
final byte[] dataBytes = new byte[dataSize];
@@ -105,7 +105,10 @@
Log.e(TAG, "failed to load BackupDataInputStream", e);
return;
}
- restoreOptimizationMode(dataBytes);
+ final int restoreCount = restoreOptimizationMode(dataBytes);
+ if (restoreCount > 0) {
+ BatterySettingsMigrateChecker.verifyOptimizationModes(mContext);
+ }
}
}
@@ -113,7 +116,7 @@
public void writeNewStateDescription(ParcelFileDescriptor newState) {
}
- private List<String> backupFullPowerList(BackupDataOutput data) {
+ private List<String> getFullPowerList() {
final long timestamp = System.currentTimeMillis();
String[] allowlistedApps;
try {
@@ -127,10 +130,7 @@
Log.w(TAG, "no data found in the getFullPowerList()");
return new ArrayList<>();
}
-
- final String allowedApps = String.join(DELIMITER, allowlistedApps);
- writeBackupData(data, KEY_FULL_POWER_LIST, allowedApps);
- Log.d(TAG, String.format("backup getFullPowerList() size=%d in %d/ms",
+ Log.d(TAG, String.format("getFullPowerList() size=%d in %d/ms",
allowlistedApps.length, (System.currentTimeMillis() - timestamp)));
return Arrays.asList(allowlistedApps);
}
@@ -175,17 +175,17 @@
}
@VisibleForTesting
- void restoreOptimizationMode(byte[] dataBytes) {
+ int restoreOptimizationMode(byte[] dataBytes) {
final long timestamp = System.currentTimeMillis();
final String dataContent = new String(dataBytes, StandardCharsets.UTF_8);
if (dataContent == null || dataContent.isEmpty()) {
Log.w(TAG, "no data found in the restoreOptimizationMode()");
- return;
+ return 0;
}
final String[] appConfigurations = dataContent.split(BatteryBackupHelper.DELIMITER);
if (appConfigurations == null || appConfigurations.length == 0) {
Log.w(TAG, "no data found from the split() processing");
- return;
+ return 0;
}
int restoreCount = 0;
for (int index = 0; index < appConfigurations.length; index++) {
@@ -217,6 +217,7 @@
}
Log.d(TAG, String.format("restoreOptimizationMode() count=%d in %d/ms",
restoreCount, (System.currentTimeMillis() - timestamp)));
+ return restoreCount;
}
/** Dump the app optimization mode backup history data. */
@@ -225,6 +226,23 @@
getSharedPreferences(context), writer);
}
+ static boolean isOwner() {
+ return UserHandle.myUserId() == UserHandle.USER_SYSTEM;
+ }
+
+ static BatteryOptimizeUtils newBatteryOptimizeUtils(
+ Context context, String packageName, BatteryOptimizeUtils testOptimizeUtils) {
+ final int uid = BatteryUtils.getInstance(context).getPackageUid(packageName);
+ if (uid == BatteryUtils.UID_NULL) {
+ return null;
+ }
+ final BatteryOptimizeUtils batteryOptimizeUtils =
+ testOptimizeUtils != null
+ ? testOptimizeUtils /*testing only*/
+ : new BatteryOptimizeUtils(context, uid, packageName);
+ return batteryOptimizeUtils;
+ }
+
@VisibleForTesting
static SharedPreferences getSharedPreferences(Context context) {
return context.getSharedPreferences(
@@ -233,14 +251,11 @@
private void restoreOptimizationMode(
String packageName, @BatteryOptimizeUtils.OptimizationMode int mode) {
- final int uid = BatteryUtils.getInstance(mContext).getPackageUid(packageName);
- if (uid == BatteryUtils.UID_NULL) {
+ final BatteryOptimizeUtils batteryOptimizeUtils =
+ newBatteryOptimizeUtils(mContext, packageName, mBatteryOptimizeUtils);
+ if (batteryOptimizeUtils == null) {
return;
}
- final BatteryOptimizeUtils batteryOptimizeUtils =
- mBatteryOptimizeUtils != null
- ? mBatteryOptimizeUtils /*testing only*/
- : new BatteryOptimizeUtils(mContext, uid, packageName);
batteryOptimizeUtils.setAppUsageState(
mode, BatteryOptimizeHistoricalLogEntry.Action.RESTORE);
Log.d(TAG, String.format("restore:%s mode=%d", packageName, mode));
@@ -294,8 +309,4 @@
Log.e(TAG, "writeBackupData() is failed for " + dataKey, e);
}
}
-
- private static boolean isOwner() {
- return UserHandle.myUserId() == UserHandle.USER_SYSTEM;
- }
}
diff --git a/src/com/android/settings/fuelgauge/BatteryBroadcastReceiver.java b/src/com/android/settings/fuelgauge/BatteryBroadcastReceiver.java
index 81a15ca..79ecd40 100644
--- a/src/com/android/settings/fuelgauge/BatteryBroadcastReceiver.java
+++ b/src/com/android/settings/fuelgauge/BatteryBroadcastReceiver.java
@@ -34,24 +34,20 @@
import java.lang.annotation.RetentionPolicy;
/**
- * Use this broadcastReceiver to listen to the battery change, and it will invoke
- * {@link OnBatteryChangedListener} if any of the following has been changed:
- *
- * 1. Battery level(e.g. 100%->99%)
- * 2. Battery status(e.g. plugged->unplugged)
- * 3. Battery saver(e.g. off->on)
- * 4. Battery health(e.g. good->overheat)
+ * Use this broadcastReceiver to listen to the battery change and it will invoke
+ * {@link OnBatteryChangedListener}
*/
public class BatteryBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "BatteryBroadcastRcvr";
/**
- * Callback when the following has been changed:
+ * Callback if any of the monitored fields has been changed:
*
* Battery level(e.g. 100%->99%)
* Battery status(e.g. plugged->unplugged)
* Battery saver(e.g. off->on)
* Battery health(e.g. good->overheat)
+ * Battery charging status(e.g. default->long life)
*/
public interface OnBatteryChangedListener {
void onBatteryChanged(@BatteryUpdateType int type);
@@ -63,6 +59,7 @@
BatteryUpdateType.BATTERY_SAVER,
BatteryUpdateType.BATTERY_STATUS,
BatteryUpdateType.BATTERY_HEALTH,
+ BatteryUpdateType.CHARGING_STATUS,
BatteryUpdateType.BATTERY_NOT_PRESENT})
public @interface BatteryUpdateType {
int MANUAL = 0;
@@ -70,7 +67,8 @@
int BATTERY_SAVER = 2;
int BATTERY_STATUS = 3;
int BATTERY_HEALTH = 4;
- int BATTERY_NOT_PRESENT = 5;
+ int CHARGING_STATUS = 5;
+ int BATTERY_NOT_PRESENT = 6;
}
@VisibleForTesting
@@ -78,6 +76,8 @@
@VisibleForTesting
String mBatteryStatus;
@VisibleForTesting
+ int mChargingStatus;
+ @VisibleForTesting
int mBatteryHealth;
private OnBatteryChangedListener mBatteryListener;
private Context mContext;
@@ -121,21 +121,27 @@
final String batteryLevel = Utils.getBatteryPercentage(intent);
final String batteryStatus =
Utils.getBatteryStatus(mContext, intent, /* compactStatus= */ false);
+ final int chargingStatus = intent.getIntExtra(
+ BatteryManager.EXTRA_CHARGING_STATUS, BatteryManager.CHARGING_POLICY_DEFAULT);
final int batteryHealth = intent.getIntExtra(
BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_UNKNOWN);
Log.d(
TAG,
- "Battery changed: level="
+ "Battery changed: level: "
+ batteryLevel
- + ", status="
+ + "| status: "
+ batteryStatus
- + ", health="
+ + "| chargingStatus: "
+ + chargingStatus
+ + "| health: "
+ batteryHealth);
if (!Utils.isBatteryPresent(intent)) {
Log.w(TAG, "Problem reading the battery meter.");
mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_NOT_PRESENT);
} else if (forceUpdate) {
mBatteryListener.onBatteryChanged(BatteryUpdateType.MANUAL);
+ } else if (chargingStatus != mChargingStatus) {
+ mBatteryListener.onBatteryChanged(BatteryUpdateType.CHARGING_STATUS);
} else if (batteryHealth != mBatteryHealth) {
mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_HEALTH);
} else if(!batteryLevel.equals(mBatteryLevel)) {
@@ -145,6 +151,7 @@
}
mBatteryLevel = batteryLevel;
mBatteryStatus = batteryStatus;
+ mChargingStatus = chargingStatus;
mBatteryHealth = batteryHealth;
} else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)) {
mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_SAVER);
diff --git a/src/com/android/settings/fuelgauge/BatteryInfo.java b/src/com/android/settings/fuelgauge/BatteryInfo.java
index 9824044..27d7154 100644
--- a/src/com/android/settings/fuelgauge/BatteryInfo.java
+++ b/src/com/android/settings/fuelgauge/BatteryInfo.java
@@ -51,7 +51,7 @@
public int batteryStatus;
public int pluggedStatus;
public boolean discharging = true;
- public boolean isOverheated;
+ public boolean isBatteryDefender;
public long remainingTimeUs = 0;
public long averageTimeToDischarge = EstimateKt.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN;
public String batteryPercentString;
@@ -257,9 +257,9 @@
info.pluggedStatus = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
info.mCharging = info.pluggedStatus != 0;
info.averageTimeToDischarge = estimate.getAverageDischargeTime();
- info.isOverheated = batteryBroadcast.getIntExtra(
- BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_UNKNOWN)
- == BatteryManager.BATTERY_HEALTH_OVERHEAT;
+ info.isBatteryDefender = batteryBroadcast.getIntExtra(
+ BatteryManager.EXTRA_CHARGING_STATUS, BatteryManager.CHARGING_POLICY_DEFAULT)
+ == BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE;
info.statusLabel = Utils.getBatteryStatus(context, batteryBroadcast, isCompactStatus);
info.batteryStatus = batteryBroadcast.getIntExtra(
@@ -283,7 +283,7 @@
info.discharging = false;
info.suggestionLabel = null;
int dockDefenderMode = BatteryUtils.getCurrentDockDefenderMode(context, info);
- if ((info.isOverheated && status != BatteryManager.BATTERY_STATUS_FULL
+ if ((info.isBatteryDefender && status != BatteryManager.BATTERY_STATUS_FULL
&& dockDefenderMode == BatteryUtils.DockDefenderMode.DISABLED)
|| dockDefenderMode == BatteryUtils.DockDefenderMode.ACTIVE) {
// Battery defender active, battery charging paused
@@ -322,18 +322,11 @@
final long drainTimeUs = PowerUtil.convertMsToUs(estimate.getEstimateMillis());
if (drainTimeUs > 0) {
info.remainingTimeUs = drainTimeUs;
- info.remainingLabel = PowerUtil.getBatteryRemainingStringFormatted(
+ info.remainingLabel = PowerUtil.getBatteryRemainingShortStringFormatted(
context,
- PowerUtil.convertUsToMs(drainTimeUs),
- null /* percentageString */,
- false /* basedOnUsage */
+ PowerUtil.convertUsToMs(drainTimeUs)
);
- info.chargeLabel = PowerUtil.getBatteryRemainingStringFormatted(
- context,
- PowerUtil.convertUsToMs(drainTimeUs),
- info.batteryPercentString,
- estimate.isBasedOnUsage() && !shortString
- );
+ info.chargeLabel = info.remainingLabel;
info.suggestionLabel = PowerUtil.getBatteryTipStringFormatted(
context, PowerUtil.convertUsToMs(drainTimeUs));
} else {
diff --git a/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java b/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java
index b9ac64d..589e1fd 100644
--- a/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java
@@ -31,11 +31,14 @@
import androidx.annotation.VisibleForTesting;
+import com.android.settings.R;
import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action;
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.List;
/** A utility class for application usage operation. */
public class BatteryOptimizeUtils {
@@ -125,11 +128,10 @@
mContext, mode, mUid, mPackageName, mBatteryUtils, mPowerAllowListBackend, action);
}
- /**
- * Return {@code true} if package name is valid (can get an uid).
- */
- public boolean isValidPackageName() {
- return mBatteryUtils.getPackageUid(mPackageName) != BatteryUtils.UID_NULL;
+ /** Return {@code true} if it is disabled for default optimized mode only. */
+ public boolean isDisabledForOptimizeModeOnly() {
+ return getAllowList(mContext).contains(mPackageName)
+ || mBatteryUtils.getPackageUid(mPackageName) == BatteryUtils.UID_NULL;
}
/**
@@ -214,6 +216,11 @@
|| powerAllowlistBackend.isDefaultActiveApp(packageName, uid);
}
+ static List<String> getAllowList(Context context) {
+ return Arrays.asList(context.getResources().getStringArray(
+ R.array.config_disable_optimization_mode_apps));
+ }
+
private static void setAppUsageStateInternal(
Context context, @OptimizationMode int mode, int uid, String packageName,
BatteryUtils batteryUtils, PowerAllowlistBackend powerAllowlistBackend,
diff --git a/src/com/android/settings/fuelgauge/BatterySettingsMigrateChecker.java b/src/com/android/settings/fuelgauge/BatterySettingsMigrateChecker.java
index c54e6d8..4b9e6ef 100644
--- a/src/com/android/settings/fuelgauge/BatterySettingsMigrateChecker.java
+++ b/src/com/android/settings/fuelgauge/BatterySettingsMigrateChecker.java
@@ -23,16 +23,27 @@
import android.provider.Settings;
import android.util.Log;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settings.R;
+import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry;
import com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleRadioButtonsController;
import com.android.settingslib.fuelgauge.BatterySaverUtils;
+import java.util.List;
+
/** Execute battery settings migration tasks in the device booting stage. */
public final class BatterySettingsMigrateChecker extends BroadcastReceiver {
private static final String TAG = "BatterySettingsMigrateChecker";
+ @VisibleForTesting
+ static BatteryOptimizeUtils sBatteryOptimizeUtils = null;
+
@Override
public void onReceive(Context context, Intent intent) {
- if (intent != null && Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
+ if (intent != null
+ && Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())
+ && BatteryBackupHelper.isOwner()) {
verifyConfiguration(context);
}
}
@@ -40,9 +51,35 @@
static void verifyConfiguration(Context context) {
context = context.getApplicationContext();
verifySaverConfiguration(context);
+ verifyOptimizationModes(context);
}
- private static void verifySaverConfiguration(Context context) {
+ /** Avoid users set important apps into the unexpected battery optimize modes */
+ static void verifyOptimizationModes(Context context) {
+ Log.d(TAG, "invoke verifyOptimizationModes()");
+ verifyOptimizationModes(context, BatteryOptimizeUtils.getAllowList(context));
+ }
+
+ @VisibleForTesting
+ static void verifyOptimizationModes(Context context, List<String> allowList) {
+ allowList.forEach(packageName -> {
+ final BatteryOptimizeUtils batteryOptimizeUtils =
+ BatteryBackupHelper.newBatteryOptimizeUtils(context, packageName,
+ /* testOptimizeUtils */ sBatteryOptimizeUtils);
+ if (batteryOptimizeUtils == null) {
+ return;
+ }
+ if (batteryOptimizeUtils.getAppOptimizationMode() !=
+ BatteryOptimizeUtils.MODE_OPTIMIZED) {
+ Log.w(TAG, "Reset optimization mode for: " + packageName);
+ batteryOptimizeUtils.setAppUsageState(BatteryOptimizeUtils.MODE_OPTIMIZED,
+ BatteryOptimizeHistoricalLogEntry.Action.FORCE_RESET);
+ }
+ });
+ }
+
+ static void verifySaverConfiguration(Context context) {
+ Log.d(TAG, "invoke verifySaverConfiguration()");
final ContentResolver resolver = context.getContentResolver();
final int threshold = Settings.Global.getInt(resolver,
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
index 72d84ef..12760b1 100644
--- a/src/com/android/settings/fuelgauge/BatteryUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -18,7 +18,6 @@
import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.InstallSourceInfo;
import android.content.pm.PackageInfo;
@@ -322,10 +321,10 @@
}
/**
- * Return {@code true} if battery is overheated and charging.
+ * Return {@code true} if battery defender is on and charging.
*/
public static boolean isBatteryDefenderOn(BatteryInfo batteryInfo) {
- return batteryInfo.isOverheated && !batteryInfo.discharging;
+ return batteryInfo.isBatteryDefender && !batteryInfo.discharging;
}
/**
@@ -627,11 +626,11 @@
if (Settings.Global.getInt(context.getContentResolver(),
SETTINGS_GLOBAL_DOCK_DEFENDER_BYPASS, 0) == 1) {
return DockDefenderMode.TEMPORARILY_BYPASSED;
- } else if (batteryInfo.isOverheated && FeatureFactory.getFactory(context)
+ } else if (batteryInfo.isBatteryDefender && FeatureFactory.getFactory(context)
.getPowerUsageFeatureProvider(context)
.isExtraDefend()) {
return DockDefenderMode.ACTIVE;
- } else if (!batteryInfo.isOverheated) {
+ } else if (!batteryInfo.isBatteryDefender) {
return DockDefenderMode.FUTURE_BYPASS;
}
}
diff --git a/src/com/android/settings/fuelgauge/OptimizedPreferenceController.java b/src/com/android/settings/fuelgauge/OptimizedPreferenceController.java
index 88241b6..ca75b0e 100644
--- a/src/com/android/settings/fuelgauge/OptimizedPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/OptimizedPreferenceController.java
@@ -46,8 +46,8 @@
@Override
public void updateState(Preference preference) {
- if (!mBatteryOptimizeUtils.isValidPackageName()) {
- Log.d(TAG, "invalid package name, optimized states only");
+ if (mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()) {
+ Log.d(TAG, "disable preference for " + mBatteryOptimizeUtils.getPackageName());
preference.setEnabled(true);
((SelectorWithWidgetPreference) preference).setChecked(true);
return;
diff --git a/src/com/android/settings/fuelgauge/RestrictedPreferenceController.java b/src/com/android/settings/fuelgauge/RestrictedPreferenceController.java
index fe896a6..7db77f1 100644
--- a/src/com/android/settings/fuelgauge/RestrictedPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/RestrictedPreferenceController.java
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-
package com.android.settings.fuelgauge;
import android.content.Context;
@@ -43,8 +42,8 @@
@Override
public void updateState(Preference preference) {
- if (!mBatteryOptimizeUtils.isValidPackageName()) {
- Log.d(TAG, "invalid package name, disable pref");
+ if (mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()) {
+ Log.d(TAG, "disable preference for " + mBatteryOptimizeUtils.getPackageName());
preference.setEnabled(false);
return;
} else {
diff --git a/src/com/android/settings/fuelgauge/UnrestrictedPreferenceController.java b/src/com/android/settings/fuelgauge/UnrestrictedPreferenceController.java
index be4091c..4578723 100644
--- a/src/com/android/settings/fuelgauge/UnrestrictedPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/UnrestrictedPreferenceController.java
@@ -42,8 +42,8 @@
@Override
public void updateState(Preference preference) {
- if (!mBatteryOptimizeUtils.isValidPackageName()) {
- Log.d(TAG, "invalid package name, disable pref");
+ if (mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()) {
+ Log.d(TAG, "disable preference for " + mBatteryOptimizeUtils.getPackageName());
preference.setEnabled(false);
return;
} else {
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/BatteryDefenderDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/BatteryDefenderDetector.java
index 2dc057e..8b7d4c1 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/BatteryDefenderDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/BatteryDefenderDetector.java
@@ -37,13 +37,12 @@
@Override
public BatteryTip detect() {
- final boolean isBasicBatteryDefend = mBatteryInfo.isOverheated
- && !FeatureFactory.getFactory(mContext)
- .getPowerUsageFeatureProvider(mContext)
- .isExtraDefend();
- final int state = isBasicBatteryDefend
- ? BatteryTip.StateType.NEW : BatteryTip.StateType.INVISIBLE;
- final boolean isPluggedIn = mBatteryInfo.pluggedStatus != 0;
- return new BatteryDefenderTip(state, isPluggedIn);
+ final boolean isBasicBatteryDefend = mBatteryInfo.isBatteryDefender
+ && !FeatureFactory.getFactory(mContext).getPowerUsageFeatureProvider(mContext)
+ .isExtraDefend();
+ final int state = isBasicBatteryDefend
+ ? BatteryTip.StateType.NEW : BatteryTip.StateType.INVISIBLE;
+ final boolean isPluggedIn = mBatteryInfo.pluggedStatus != 0;
+ return new BatteryDefenderTip(state, isPluggedIn);
}
}
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index 03bc1b3..829a89c 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -57,7 +57,6 @@
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
-import androidx.window.embedding.ActivityEmbeddingController;
import androidx.window.embedding.SplitRule;
import com.android.settings.R;
@@ -108,7 +107,6 @@
private View mTwoPaneSuggestionView;
private CategoryMixin mCategoryMixin;
private Set<HomepageLoadedListener> mLoadedListeners;
- private ActivityEmbeddingController mActivityEmbeddingController;
private boolean mIsEmbeddingActivityEnabled;
private boolean mIsTwoPane;
// A regular layout shows icons on homepage, whereas a simplified layout doesn't.
@@ -200,8 +198,7 @@
setupEdgeToEdge();
setContentView(R.layout.settings_homepage_container);
- mActivityEmbeddingController = ActivityEmbeddingController.getInstance(this);
- mIsTwoPane = mActivityEmbeddingController.isActivityEmbedded(this);
+ mIsTwoPane = ActivityEmbeddingUtils.isAlreadyEmbedded(this);
updateAppBarMinHeight();
initHomepageContainer();
@@ -242,7 +239,7 @@
// Settings app may be launched on an existing task. Reset SplitPairRule of SubSettings here
// to prevent SplitPairRule of an existing task applied on a new started Settings app.
- if (ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this)
+ if (mIsEmbeddingActivityEnabled
&& (getIntent().getFlags() & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
initSplitPairRules();
}
@@ -284,7 +281,7 @@
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- final boolean newTwoPaneState = mActivityEmbeddingController.isActivityEmbedded(this);
+ final boolean newTwoPaneState = ActivityEmbeddingUtils.isAlreadyEmbedded(this);
if (mIsTwoPane != newTwoPaneState) {
mIsTwoPane = newTwoPaneState;
updateHomepageAppBar();
@@ -427,8 +424,9 @@
}
private boolean shouldLaunchDeepLinkIntentToRight() {
- if (!FeatureFlagUtils.isEnabled(this, FeatureFlagUtils.SETTINGS_SUPPORT_LARGE_SCREEN)
- || !ActivityEmbeddingUtils.isSettingsSplitEnabled(this)) {
+ if (!ActivityEmbeddingUtils.isSettingsSplitEnabled(this)
+ || !FeatureFlagUtils.isEnabled(this,
+ FeatureFlagUtils.SETTINGS_SUPPORT_LARGE_SCREEN)) {
return false;
}
diff --git a/src/com/android/settings/network/tether/TetherSettings.java b/src/com/android/settings/network/tether/TetherSettings.java
index ba19d1c..9fa8730 100644
--- a/src/com/android/settings/network/tether/TetherSettings.java
+++ b/src/com/android/settings/network/tether/TetherSettings.java
@@ -171,6 +171,8 @@
return;
}
+ setupTetherPreference();
+
final Activity activity = getActivity();
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
@@ -184,7 +186,6 @@
new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
}
- setupTetherPreference();
setTopIntroPreferenceTitle();
mDataSaverBackend.addListener(this);
@@ -605,6 +606,7 @@
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (mBluetoothPan.get() == null) {
mBluetoothPan.set((BluetoothPan) proxy);
+ updateBluetoothState();
}
}
diff --git a/src/com/android/settings/password/BiometricFragment.java b/src/com/android/settings/password/BiometricFragment.java
index d364c71..4ad04a1 100644
--- a/src/com/android/settings/password/BiometricFragment.java
+++ b/src/com/android/settings/password/BiometricFragment.java
@@ -141,6 +141,7 @@
.setDisallowBiometricsIfPolicyExists(
promptInfo.isDisallowBiometricsIfPolicyExists())
.setReceiveSystemEvents(true)
+ .setAllowBackgroundAuthentication(true)
.build();
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java
index 5ee7ab3..c68e90b 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java
@@ -24,25 +24,22 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHapClient;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
+import android.content.Context;
import android.content.Intent;
-import androidx.appcompat.app.AlertDialog;
-import androidx.fragment.app.FragmentActivity;
import androidx.preference.Preference;
+import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.bluetooth.Utils;
-import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
-import com.android.settings.utils.ActivityControllerWrapper;
import com.android.settingslib.bluetooth.BluetoothEventManager;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
@@ -55,11 +52,12 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
@@ -74,6 +72,9 @@
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowBluetoothAdapter.class, ShadowBluetoothUtils.class})
public class AccessibilityHearingAidPreferenceControllerTest {
+ @Rule
+ public final MockitoRule mockito = MockitoJUnit.rule();
+
private static final String TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1";
private static final String TEST_DEVICE_ADDRESS_2 = "00:A2:A2:A2:A2:A2";
private static final String TEST_DEVICE_NAME = "TEST_HEARING_AID_BT_DEVICE_NAME";
@@ -82,7 +83,8 @@
private BluetoothAdapter mBluetoothAdapter;
private ShadowBluetoothAdapter mShadowBluetoothAdapter;
private BluetoothDevice mBluetoothDevice;
- private Activity mContext;
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+
private Preference mHearingAidPreference;
private AccessibilityHearingAidPreferenceController mPreferenceController;
private ShadowApplication mShadowApplication;
@@ -106,11 +108,7 @@
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
mShadowApplication = ShadowApplication.getInstance();
-
- mContext = spy((Activity) ActivityControllerWrapper.setup(
- Robolectric.buildActivity(Activity.class)).get());
setupEnvironment();
mHearingAidPreference = new Preference(mContext);
@@ -275,65 +273,6 @@
}
@Test
- public void onSupportHearingAidProfile_isAvailable() {
- mShadowBluetoothAdapter.clearSupportedProfiles();
- mShadowBluetoothAdapter.addSupportedProfiles(BluetoothProfile.HEARING_AID);
- mPreferenceController = new AccessibilityHearingAidPreferenceController(mContext,
- HEARING_AID_PREFERENCE);
- mPreferenceController.setPreference(mHearingAidPreference);
-
- assertThat(mPreferenceController.isAvailable()).isTrue();
- }
-
- @Test
- public void onSupportHapClientProfile_isAvailable() {
- mShadowBluetoothAdapter.clearSupportedProfiles();
- mShadowBluetoothAdapter.addSupportedProfiles(BluetoothProfile.HAP_CLIENT);
- mPreferenceController = new AccessibilityHearingAidPreferenceController(mContext,
- HEARING_AID_PREFERENCE);
- mPreferenceController.setPreference(mHearingAidPreference);
-
- assertThat(mPreferenceController.isAvailable()).isTrue();
- }
-
- @Test
- public void onNotSupportAnyHearingAidRelatedProfile_isNotAvailable() {
- mShadowBluetoothAdapter.clearSupportedProfiles();
- mPreferenceController = new AccessibilityHearingAidPreferenceController(mContext,
- HEARING_AID_PREFERENCE);
- mPreferenceController.setPreference(mHearingAidPreference);
-
- assertThat(mPreferenceController.isAvailable()).isFalse();
- }
-
- @Test
- public void getConnectedHearingAidDevice_doNotReturnSubDevice() {
- when(mHearingAidProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
- when(mLocalBluetoothManager.getCachedDeviceManager().isSubDevice(mBluetoothDevice))
- .thenReturn(true);
-
- assertThat(mPreferenceController.getConnectedHearingAidDevice()).isNull();
- }
-
- @Test
- @Config(shadows = ShadowAlertDialogCompat.class)
- public void onActiveDeviceChanged_hearingAidProfile_launchHearingAidPairingDialog() {
- final FragmentActivity mActivity = Robolectric.setupActivity(FragmentActivity.class);
- when(mCachedBluetoothDevice.isConnectedAshaHearingAidDevice()).thenReturn(true);
- when(mCachedBluetoothDevice.getDeviceMode()).thenReturn(
- HearingAidInfo.DeviceMode.MODE_BINAURAL);
- when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
- HearingAidInfo.DeviceSide.SIDE_LEFT);
- mPreferenceController.setFragmentManager(mActivity.getSupportFragmentManager());
-
- mPreferenceController.onActiveDeviceChanged(mCachedBluetoothDevice,
- BluetoothProfile.HEARING_AID);
-
- final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
- assertThat(dialog.isShowing()).isTrue();
- }
-
- @Test
public void onServiceConnected_onHearingAidProfileConnected_updateSummary() {
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
HearingAidInfo.DeviceSide.SIDE_LEFT);
diff --git a/tests/robotests/src/com/android/settings/accessibility/HearingAidAudioRoutingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/HearingAidAudioRoutingPreferenceControllerTest.java
new file mode 100644
index 0000000..d16bc43
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/HearingAidAudioRoutingPreferenceControllerTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 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.accessibility;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.util.FeatureFlagUtils;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link HearingAidAudioRoutingPreferenceController}. */
+@RunWith(RobolectricTestRunner.class)
+public class HearingAidAudioRoutingPreferenceControllerTest {
+ @Rule
+ public final MockitoRule mockito = MockitoJUnit.rule();
+
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+
+ private HearingAidAudioRoutingPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ mController = new HearingAidAudioRoutingPreferenceController(mContext, "test_key");
+ }
+
+ @Test
+ public void getAvailabilityStatus_audioRoutingNotSupported_returnUnsupported() {
+ FeatureFlagUtils.setEnabled(mContext,
+ FeatureFlagUtils.SETTINGS_AUDIO_ROUTING, false);
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_audioRoutingNotSupported_available() {
+ FeatureFlagUtils.setEnabled(mContext,
+ FeatureFlagUtils.SETTINGS_AUDIO_ROUTING, true);
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/HearingAidHelperTest.java b/tests/robotests/src/com/android/settings/accessibility/HearingAidHelperTest.java
new file mode 100644
index 0000000..194b766
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/HearingAidHelperTest.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2023 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.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.bluetooth.Utils;
+import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
+import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.HapClientProfile;
+import com.android.settingslib.bluetooth.HearingAidProfile;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+/** Tests for {@link HearingAidHelper}. */
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class, ShadowBluetoothUtils.class})
+public class HearingAidHelperTest {
+ @Rule
+ public final MockitoRule mockito = MockitoJUnit.rule();
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ private static final String TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1";
+
+ @Mock
+ private LocalBluetoothManager mLocalBluetoothManager;
+ @Mock
+ private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
+ @Mock
+ private CachedBluetoothDeviceManager mCachedDeviceManager;
+ @Mock
+ private CachedBluetoothDevice mCachedBluetoothDevice;
+ @Mock
+ private HearingAidProfile mHearingAidProfile;
+ @Mock
+ private HapClientProfile mHapClientProfile;
+ private ShadowBluetoothAdapter mShadowBluetoothAdapter;
+ private BluetoothAdapter mBluetoothAdapter;
+ private BluetoothDevice mBluetoothDevice;
+ private HearingAidHelper mHelper;
+
+ @Before
+ public void setUp() {
+ ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
+ mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ mShadowBluetoothAdapter = Shadow.extract(mBluetoothAdapter);
+ mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS);
+ when(mCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
+ when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
+ when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
+ when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
+ when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
+ when(mLocalBluetoothProfileManager.getHapClientProfile()).thenReturn(mHapClientProfile);
+
+ mHelper = new HearingAidHelper(mContext);
+ }
+
+ @Test
+ public void isHearingAidSupported_supported_returnTrue() {
+ mBluetoothAdapter.enable();
+ mShadowBluetoothAdapter.clearSupportedProfiles();
+ mShadowBluetoothAdapter.addSupportedProfiles(BluetoothProfile.HEARING_AID);
+
+ assertThat(mHelper.isHearingAidSupported()).isTrue();
+ }
+
+ @Test
+ public void isHearingAidSupported_bluetoothOff_returnFalse() {
+ mShadowBluetoothAdapter.clearSupportedProfiles();
+ mShadowBluetoothAdapter.addSupportedProfiles(BluetoothProfile.HEARING_AID);
+ mBluetoothAdapter.disable();
+
+ assertThat(mHelper.isHearingAidSupported()).isFalse();
+ }
+
+
+ @Test
+ public void isAllHearingAidRelatedProfilesReady_allReady_returnTrue() {
+ when(mHearingAidProfile.isProfileReady()).thenReturn(true);
+ when(mHapClientProfile.isProfileReady()).thenReturn(true);
+
+ assertThat(mHelper.isAllHearingAidRelatedProfilesReady()).isTrue();
+ }
+
+ @Test
+ public void isAllHearingAidRelatedProfilesReady_notFullReady_returnFalse() {
+ when(mHearingAidProfile.isProfileReady()).thenReturn(false);
+ when(mHapClientProfile.isProfileReady()).thenReturn(true);
+
+ assertThat(mHelper.isAllHearingAidRelatedProfilesReady()).isFalse();
+ }
+
+ @Test
+ public void getConnectedHearingAidDeviceList_oneDeviceAdded_getOneDevice() {
+ mBluetoothAdapter.enable();
+ mShadowBluetoothAdapter.clearSupportedProfiles();
+ mShadowBluetoothAdapter.addSupportedProfiles(BluetoothProfile.HEARING_AID);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(new ArrayList<>(
+ Collections.singletonList(mBluetoothDevice)));
+
+ assertThat(mHelper.getConnectedHearingAidDeviceList().size()).isEqualTo(1);
+ }
+
+ @Test
+ public void getConnectedHearingAidDeviceList_oneSubDeviceAdded_getZeroDevice() {
+ mBluetoothAdapter.enable();
+ mShadowBluetoothAdapter.clearSupportedProfiles();
+ mShadowBluetoothAdapter.addSupportedProfiles(BluetoothProfile.HEARING_AID);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(new ArrayList<>(
+ Collections.singletonList(mBluetoothDevice)));
+ when(mLocalBluetoothManager.getCachedDeviceManager().isSubDevice(
+ mBluetoothDevice)).thenReturn(true);
+
+ assertThat(mHelper.getConnectedHearingAidDeviceList().size()).isEqualTo(0);
+ }
+
+ @Test
+ public void getConnectedHearingAidDevice_getExpectedCachedBluetoothDevice() {
+ mBluetoothAdapter.enable();
+ mShadowBluetoothAdapter.clearSupportedProfiles();
+ mShadowBluetoothAdapter.addSupportedProfiles(BluetoothProfile.HEARING_AID);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(new ArrayList<>(
+ Collections.singletonList(mBluetoothDevice)));
+
+ assertThat(mHelper.getConnectedHearingAidDevice()).isEqualTo(mCachedBluetoothDevice);
+ assertThat(mCachedBluetoothDevice.getAddress()).isEqualTo(mBluetoothDevice.getAddress());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/HearingDeviceAudioRoutingBasePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/HearingDeviceAudioRoutingBasePreferenceControllerTest.java
similarity index 70%
rename from tests/robotests/src/com/android/settings/bluetooth/HearingDeviceAudioRoutingBasePreferenceControllerTest.java
rename to tests/robotests/src/com/android/settings/accessibility/HearingDeviceAudioRoutingBasePreferenceControllerTest.java
index 105da65..4decf68 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/HearingDeviceAudioRoutingBasePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/HearingDeviceAudioRoutingBasePreferenceControllerTest.java
@@ -14,13 +14,14 @@
* limitations under the License.
*/
-package com.android.settings.bluetooth;
+package com.android.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -37,9 +38,15 @@
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
+import com.android.settings.bluetooth.Utils;
+import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
+import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants;
import com.android.settingslib.bluetooth.HearingAidAudioRoutingHelper;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import org.junit.Before;
import org.junit.Rule;
@@ -50,11 +57,13 @@
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
import java.util.List;
/** Tests for {@link HearingDeviceAudioRoutingBasePreferenceController}. */
@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class, ShadowBluetoothUtils.class})
public class HearingDeviceAudioRoutingBasePreferenceControllerTest {
@Rule
@@ -63,17 +72,25 @@
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
private static final String TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1";
- private static final String FAKE_KEY = "fake_key";
+ private final ListPreference mListPreference = new ListPreference(mContext);
@Mock
+ private LocalBluetoothManager mLocalBluetoothManager;
+ @Mock
+ private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
+ @Mock
+ private CachedBluetoothDeviceManager mCachedDeviceManager;
+ @Mock
private AudioProductStrategy mAudioProductStrategyMedia;
@Mock
private CachedBluetoothDevice mCachedBluetoothDevice;
@Mock
private BluetoothDevice mBluetoothDevice;
@Spy
- private HearingAidAudioRoutingHelper mHelper = new HearingAidAudioRoutingHelper(mContext);
- private final ListPreference mListPreference = new ListPreference(mContext);
+ private HearingAidAudioRoutingHelper mAudioRoutingHelper =
+ new HearingAidAudioRoutingHelper(mContext);
+ @Mock
+ private HearingAidHelper mHearingAidHelper;
private TestHearingDeviceAudioRoutingBasePreferenceController mController;
@Before
@@ -83,19 +100,23 @@
AudioDeviceInfo.TYPE_HEARING_AID,
TEST_DEVICE_ADDRESS);
+ ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
+ mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
+ when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
+ when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
when(mBluetoothDevice.getAnonymizedAddress()).thenReturn(TEST_DEVICE_ADDRESS);
when(mCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
- when(mHelper.getMatchedHearingDeviceAttributes(any())).thenReturn(hearingDeviceAttribute);
+ doReturn(hearingDeviceAttribute).when(
+ mAudioRoutingHelper).getMatchedHearingDeviceAttributes(any());
when(mAudioProductStrategyMedia.getAudioAttributesForLegacyStreamType(
- AudioManager.STREAM_MUSIC))
- .thenReturn((new AudioAttributes.Builder()).build());
- when(mHelper.getAudioProductStrategies()).thenReturn(List.of(mAudioProductStrategyMedia));
+ AudioManager.STREAM_MUSIC)).thenReturn((new AudioAttributes.Builder()).build());
+ when(mAudioRoutingHelper.getAudioProductStrategies()).thenReturn(
+ List.of(mAudioProductStrategyMedia));
- mController = new TestHearingDeviceAudioRoutingBasePreferenceController(mContext, FAKE_KEY,
- mHelper);
- TestHearingDeviceAudioRoutingBasePreferenceController.setupForTesting(
- mCachedBluetoothDevice);
+ mController = new TestHearingDeviceAudioRoutingBasePreferenceController(mContext,
+ "test_key",
+ mAudioRoutingHelper, mHearingAidHelper);
mListPreference.setEntries(R.array.bluetooth_audio_routing_titles);
mListPreference.setEntryValues(R.array.bluetooth_audio_routing_values);
mListPreference.setSummary("%s");
@@ -122,20 +143,21 @@
@Test
public void onPreferenceChange_noMatchedDeviceAttributes_notCallSetStrategies() {
- when(mHelper.getMatchedHearingDeviceAttributes(any())).thenReturn(null);
+ when(mAudioRoutingHelper.getMatchedHearingDeviceAttributes(any())).thenReturn(null);
- verify(mHelper, never()).setPreferredDeviceRoutingStrategies(any(), isNull(), anyInt());
+ verify(mAudioRoutingHelper, never()).setPreferredDeviceRoutingStrategies(any(), isNull(),
+ anyInt());
}
private static class TestHearingDeviceAudioRoutingBasePreferenceController extends
HearingDeviceAudioRoutingBasePreferenceController {
- private static CachedBluetoothDevice sCachedBluetoothDevice;
private static int sSavedRoutingValue;
TestHearingDeviceAudioRoutingBasePreferenceController(Context context,
- String preferenceKey, HearingAidAudioRoutingHelper helper) {
- super(context, preferenceKey, helper);
+ String preferenceKey, HearingAidAudioRoutingHelper audioRoutingHelper,
+ HearingAidHelper hearingAidHelper) {
+ super(context, preferenceKey, audioRoutingHelper, hearingAidHelper);
}
@Override
@@ -144,11 +166,6 @@
}
@Override
- protected CachedBluetoothDevice getHearingDevice() {
- return sCachedBluetoothDevice;
- }
-
- @Override
protected void saveRoutingValue(Context context, int routingValue) {
sSavedRoutingValue = routingValue;
}
@@ -157,9 +174,5 @@
protected int restoreRoutingValue(Context context) {
return sSavedRoutingValue;
}
-
- public static void setupForTesting(CachedBluetoothDevice cachedBluetoothDevice) {
- sCachedBluetoothDevice = cachedBluetoothDevice;
- }
}
}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/HearingDeviceCallRoutingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/HearingDeviceCallRoutingPreferenceControllerTest.java
similarity index 97%
rename from tests/robotests/src/com/android/settings/bluetooth/HearingDeviceCallRoutingPreferenceControllerTest.java
rename to tests/robotests/src/com/android/settings/accessibility/HearingDeviceCallRoutingPreferenceControllerTest.java
index dec4cc4..8eed294 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/HearingDeviceCallRoutingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/HearingDeviceCallRoutingPreferenceControllerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.bluetooth;
+package com.android.settings.accessibility;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
diff --git a/tests/robotests/src/com/android/settings/accounts/ContactSearchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/ContactSearchPreferenceControllerTest.java
index c8606e1..bc65563 100644
--- a/tests/robotests/src/com/android/settings/accounts/ContactSearchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/ContactSearchPreferenceControllerTest.java
@@ -20,13 +20,19 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.pm.UserInfo;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings;
+import androidx.test.core.app.ApplicationProvider;
+
import com.android.settingslib.RestrictedSwitchPreference;
import org.junit.Before;
@@ -35,39 +41,51 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
+
+import java.util.Collections;
@RunWith(RobolectricTestRunner.class)
public class ContactSearchPreferenceControllerTest {
private static final String PREF_KEY = "contacts_search";
-
- @Mock
- private UserHandle mManagedUser;
+ private static final int MANAGED_USER_ID = 10;
private Context mContext;
private ContactSearchPreferenceController mController;
private RestrictedSwitchPreference mPreference;
+ @Mock
+ private UserHandle mManagedUser;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private UserInfo mUserInfo;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
- mController = new ContactSearchPreferenceController(mContext, PREF_KEY);
- mController.setManagedUser(mManagedUser);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
mPreference = spy(new RestrictedSwitchPreference(mContext));
+ when(mUserInfo.isManagedProfile()).thenReturn(true);
+ when(mUserManager.getUserInfo(anyInt())).thenReturn(mUserInfo);
+ when(mUserManager.getProcessUserId()).thenReturn(0);
+ when(mUserManager.getUserProfiles()).thenReturn(Collections.singletonList(mManagedUser));
+ when(mManagedUser.getIdentifier()).thenReturn(MANAGED_USER_ID);
+ mController = new ContactSearchPreferenceController(mContext, PREF_KEY);
}
@Test
public void getAvailabilityStatus_noManagedUser_DISABLED() {
- mController.setManagedUser(null);
+ when(mUserManager.getProcessUserId()).thenReturn(MANAGED_USER_ID);
+ mController = new ContactSearchPreferenceController(mContext, PREF_KEY);
+
assertThat(mController.getAvailabilityStatus())
.isNotEqualTo(ContactSearchPreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_hasManagedUser_AVAILABLE() {
- mController.setManagedUser(mManagedUser);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(ContactSearchPreferenceController.AVAILABLE);
}
@@ -75,32 +93,96 @@
@Test
public void updateState_shouldRefreshContent() {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
- MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, mManagedUser.getIdentifier());
+ MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, MANAGED_USER_ID);
+
mController.updateState(mPreference);
+
assertThat(mPreference.isChecked()).isFalse();
Settings.Secure.putIntForUser(mContext.getContentResolver(),
- MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 1, mManagedUser.getIdentifier());
+ MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 1, MANAGED_USER_ID);
+
mController.updateState(mPreference);
+
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void updateState_preferenceShouldBeDisabled() {
mController.updateState(mPreference);
+
verify(mPreference).setDisabledByAdmin(any());
}
@Test
public void onPreferenceChange_shouldUpdateProviderValue() {
mController.onPreferenceChange(mPreference, false);
+
assertThat(Settings.Secure.getIntForUser(mContext.getContentResolver(),
- MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 1, mManagedUser.getIdentifier()))
+ MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 1, MANAGED_USER_ID))
.isEqualTo(0);
mController.onPreferenceChange(mPreference, true);
+
assertThat(Settings.Secure.getIntForUser(mContext.getContentResolver(),
- MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, mManagedUser.getIdentifier()))
+ MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, MANAGED_USER_ID))
.isEqualTo(1);
}
-}
\ No newline at end of file
+
+ @Test
+ public void onQuietModeDisabled_preferenceEnabled() {
+ when(mUserManager.isQuietModeEnabled(any(UserHandle.class))).thenReturn(false);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isEnabled()).isTrue();
+ }
+
+ @Test
+ public void onQuietModeEnabled_preferenceDisabledAndUnchecked() {
+ when(mUserManager.isQuietModeEnabled(any(UserHandle.class))).thenReturn(true);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isEnabled()).isFalse();
+ assertThat(mPreference.isChecked()).isFalse();
+ }
+
+ @Test
+ public void afterQuietModeTurnedOnAndOffWhenPreferenceChecked_toggleCheckedAndEnabled() {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 1, MANAGED_USER_ID);
+ when(mUserManager.isQuietModeEnabled(any(UserHandle.class))).thenReturn(true);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isEnabled()).isFalse();
+ assertThat(mPreference.isChecked()).isFalse();
+
+ when(mUserManager.isQuietModeEnabled(any(UserHandle.class))).thenReturn(false);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isEnabled()).isTrue();
+ assertThat(mPreference.isChecked()).isTrue();
+ }
+
+ @Test
+ public void afterQuietModeTurnedOnAndOffWhenPreferenceUnchecked_toggleUncheckedAndEnabled() {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, MANAGED_USER_ID);
+ when(mUserManager.isQuietModeEnabled(any(UserHandle.class))).thenReturn(true);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isEnabled()).isFalse();
+ assertThat(mPreference.isChecked()).isFalse();
+
+ when(mUserManager.isQuietModeEnabled(any(UserHandle.class))).thenReturn(false);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isEnabled()).isTrue();
+ assertThat(mPreference.isChecked()).isFalse();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accounts/ManagedProfileQuietModeEnablerTest.java b/tests/robotests/src/com/android/settings/accounts/ManagedProfileQuietModeEnablerTest.java
new file mode 100644
index 0000000..2698efa
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accounts/ManagedProfileQuietModeEnablerTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2023 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.accounts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LifecycleRegistry;
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.Collections;
+
+
+@RunWith(RobolectricTestRunner.class)
+public class ManagedProfileQuietModeEnablerTest {
+ private static final int MANAGED_USER_ID = 10;
+ private Context mContext;
+ private ManagedProfileQuietModeEnabler mQuietModeEnabler;
+ private LifecycleOwner mLifecycleOwner = new LifecycleOwner() {
+ public LifecycleRegistry registry = new LifecycleRegistry(this);
+
+ @Override
+ public Lifecycle getLifecycle() {
+ return registry;
+ }
+ };
+
+ @Mock
+ private ManagedProfileQuietModeEnabler.QuietModeChangeListener mOnQuietModeChangeListener;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private UserHandle mManagedUser;
+ @Mock
+ private UserInfo mUserInfo;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ when(mUserInfo.isManagedProfile()).thenReturn(true);
+ when(mUserManager.getUserInfo(anyInt())).thenReturn(mUserInfo);
+ when(mUserManager.getProcessUserId()).thenReturn(0);
+ when(mManagedUser.getIdentifier()).thenReturn(MANAGED_USER_ID);
+ when(mUserManager.getUserProfiles()).thenReturn(Collections.singletonList(mManagedUser));
+ mQuietModeEnabler = new ManagedProfileQuietModeEnabler(mContext,
+ mOnQuietModeChangeListener);
+ }
+
+ @Test
+ public void onSetQuietMode_shouldRequestQuietModeEnabled() {
+ mQuietModeEnabler.setQuietModeEnabled(false);
+ verify(mUserManager).requestQuietModeEnabled(false, mManagedUser);
+ mQuietModeEnabler.setQuietModeEnabled(true);
+ verify(mUserManager).requestQuietModeEnabled(true, mManagedUser);
+ }
+
+ @Test
+ public void onIsQuietModeEnabled_shouldCallIsQuietModeEnabled() {
+ assertThat(mQuietModeEnabler.isQuietModeEnabled()).isEqualTo(
+ verify(mUserManager).isQuietModeEnabled(any()));
+ }
+
+ @Test
+ public void onQuietModeChanged_listenerNotified() {
+ mQuietModeEnabler.onStart(mLifecycleOwner);
+ mContext.sendBroadcast(new Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABLE).putExtra(
+ Intent.EXTRA_USER_HANDLE, MANAGED_USER_ID));
+ mContext.sendBroadcast(new Intent(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE).putExtra(
+ Intent.EXTRA_USER_HANDLE, MANAGED_USER_ID));
+ verify(mOnQuietModeChangeListener, times(2)).onQuietModeChanged();
+ }
+
+ @Test
+ public void onStart_shouldRegisterReceiver() {
+ mQuietModeEnabler.onStart(mLifecycleOwner);
+ verify(mContext).registerReceiver(eq(mQuietModeEnabler.mReceiver), any(), anyInt());
+ }
+
+ @Test
+ public void onStop_shouldUnregisterReceiver() {
+ // register it first
+ mContext.registerReceiver(mQuietModeEnabler.mReceiver, null,
+ Context.RECEIVER_EXPORTED/*UNAUDITED*/);
+
+ mQuietModeEnabler.onStop(mLifecycleOwner);
+ verify(mContext).unregisterReceiver(mQuietModeEnabler.mReceiver);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accounts/WorkModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/WorkModePreferenceControllerTest.java
index 2a28318..e862d10 100644
--- a/tests/robotests/src/com/android/settings/accounts/WorkModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/WorkModePreferenceControllerTest.java
@@ -19,18 +19,18 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
-import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
-import com.android.settings.R;
+import com.android.settingslib.widget.MainSwitchPreference;
import org.junit.Before;
import org.junit.Test;
@@ -38,43 +38,51 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
+
+import java.util.Collections;
@RunWith(RobolectricTestRunner.class)
public class WorkModePreferenceControllerTest {
private static final String PREF_KEY = "work_mode";
+ private static final int MANAGED_USER_ID = 10;
+
+ private Context mContext;
+ private WorkModePreferenceController mController;
+ private MainSwitchPreference mPreference;
@Mock
private UserManager mUserManager;
@Mock
private UserHandle mManagedUser;
-
- private Context mContext;
- private WorkModePreferenceController mController;
- private SwitchPreference mPreference;
+ @Mock
+ private UserInfo mUserInfo;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = spy(RuntimeEnvironment.application);
- when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
-
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+ mPreference = new MainSwitchPreference(mContext);
+ when(mUserInfo.isManagedProfile()).thenReturn(true);
+ when(mUserManager.getUserInfo(anyInt())).thenReturn(mUserInfo);
+ when(mUserManager.getProcessUserId()).thenReturn(0);
+ when(mUserManager.getUserProfiles()).thenReturn(Collections.singletonList(mManagedUser));
+ when(mManagedUser.getIdentifier()).thenReturn(MANAGED_USER_ID);
mController = new WorkModePreferenceController(mContext, PREF_KEY);
- mController.setManagedUser(mManagedUser);
- mPreference = new SwitchPreference(mContext);
}
@Test
public void getAvailabilityStatus_noManagedUser_DISABLED() {
- mController.setManagedUser(null);
+ when(mUserManager.getProcessUserId()).thenReturn(MANAGED_USER_ID);
+ mController = new WorkModePreferenceController(mContext, PREF_KEY);
+
assertThat(mController.getAvailabilityStatus())
.isNotEqualTo(WorkModePreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_hasManagedUser_AVAILABLE() {
- mController.setManagedUser(mManagedUser);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(WorkModePreferenceController.AVAILABLE);
}
@@ -83,41 +91,29 @@
public void updateState_shouldRefreshContent() {
when(mUserManager.isQuietModeEnabled(any(UserHandle.class)))
.thenReturn(false);
+
mController.updateState(mPreference);
+
assertThat(mPreference.isChecked()).isTrue();
- assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getText(R.string.work_mode_on_summary));
when(mUserManager.isQuietModeEnabled(any(UserHandle.class)))
.thenReturn(true);
+
mController.updateState(mPreference);
+
assertThat(mPreference.isChecked()).isFalse();
- assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getText(R.string.work_mode_off_summary));
}
@Test
public void onPreferenceChange_shouldRequestQuietModeEnabled() {
+ mController.setPreference(mPreference);
+
mController.onPreferenceChange(mPreference, true);
+
verify(mUserManager).requestQuietModeEnabled(false, mManagedUser);
mController.onPreferenceChange(mPreference, false);
+
verify(mUserManager).requestQuietModeEnabled(true, mManagedUser);
}
-
- @Test
- public void onStart_shouldRegisterReceiver() {
- mController.onStart();
- verify(mContext).registerReceiver(eq(mController.mReceiver), any(), anyInt());
- }
-
- @Test
- public void onStop_shouldUnregisterReceiver() {
- // register it first
- mContext.registerReceiver(mController.mReceiver, null,
- Context.RECEIVER_EXPORTED/*UNAUDITED*/);
-
- mController.onStop();
- verify(mContext).unregisterReceiver(mController.mReceiver);
- }
}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingControllerTest.java
deleted file mode 100644
index ea65856..0000000
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingControllerTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2022 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.bluetooth;
-
-import static com.android.settings.bluetooth.BluetoothDetailsAudioRoutingController.KEY_AUDIO_ROUTING;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.util.FeatureFlagUtils;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-import org.robolectric.RobolectricTestRunner;
-
-/** Tests for {@link BluetoothDetailsAudioRoutingController}. */
-@RunWith(RobolectricTestRunner.class)
-public class BluetoothDetailsAudioRoutingControllerTest extends
- BluetoothDetailsControllerTestBase {
- @Rule
- public final MockitoRule mockito = MockitoJUnit.rule();
-
- private static final String TEST_ADDRESS = "55:66:77:88:99:AA";
-
- private BluetoothDetailsAudioRoutingController mController;
-
- @Override
- public void setUp() {
- super.setUp();
-
- mController = new BluetoothDetailsAudioRoutingController(mContext, mFragment, mCachedDevice,
- mLifecycle);
- final PreferenceCategory preferenceCategory = new PreferenceCategory(mContext);
- preferenceCategory.setKey(mController.getPreferenceKey());
- mScreen.addPreference(preferenceCategory);
- }
-
- @Test
- public void isAvailable_isHearingAidDevice_available() {
- FeatureFlagUtils.setEnabled(mContext,
- FeatureFlagUtils.SETTINGS_AUDIO_ROUTING, true);
- when(mCachedDevice.isHearingAidDevice()).thenReturn(true);
-
- assertThat(mController.isAvailable()).isTrue();
- }
-
- @Test
- public void isAvailable_isNotHearingAidDevice_notAvailable() {
- FeatureFlagUtils.setEnabled(mContext,
- FeatureFlagUtils.SETTINGS_AUDIO_ROUTING, true);
- when(mCachedDevice.isHearingAidDevice()).thenReturn(false);
-
- assertThat(mController.isAvailable()).isFalse();
- }
-
- @Test
- public void init_isHearingAidDevice_expectedAudioRoutingPreference() {
- when(mCachedDevice.isHearingAidDevice()).thenReturn(true);
- when(mCachedDevice.getAddress()).thenReturn(TEST_ADDRESS);
-
- mController.init(mScreen);
- final Preference preference = mScreen.findPreference(KEY_AUDIO_ROUTING);
- final String address = preference.getExtras().getString(
- BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS);
- final String fragment = preference.getFragment();
-
- assertThat(address).isEqualTo(TEST_ADDRESS);
- assertThat(fragment).isEqualTo(BluetoothDetailsAudioRoutingFragment.class.getName());
-
- }
-}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragmentTest.java
deleted file mode 100644
index 9bd4f1b..0000000
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragmentTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2023 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.bluetooth;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.Context;
-import android.os.Bundle;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
-import com.android.settingslib.bluetooth.CachedBluetoothDevice;
-import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link BluetoothDetailsAudioRoutingFragment}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowBluetoothUtils.class})
-public class BluetoothDetailsAudioRoutingFragmentTest {
-
- @Rule
- public MockitoRule mMockitoRule = MockitoJUnit.rule();
-
- private static final String TEST_ADDRESS = "55:66:77:88:99:AA";
-
- private final Context mContext = ApplicationProvider.getApplicationContext();
-
- private BluetoothDetailsAudioRoutingFragment mFragment;
- @Mock
- private LocalBluetoothManager mLocalBluetoothManager;
- @Mock
- private CachedBluetoothDeviceManager mCachedDeviceManager;
- @Mock
- private LocalBluetoothAdapter mLocalBluetoothAdapter;
- @Mock
- private BluetoothDevice mBluetoothDevice;
- @Mock
- private CachedBluetoothDevice mCachedDevice;
-
- @Before
- public void setUp() {
- setupEnvironment();
-
- when(mLocalBluetoothAdapter.getRemoteDevice(TEST_ADDRESS)).thenReturn(mBluetoothDevice);
- when(mCachedDevice.getAddress()).thenReturn(TEST_ADDRESS);
- when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedDevice);
-
- mFragment = new BluetoothDetailsAudioRoutingFragment();
- }
-
- @Test
- public void onAttach_setArgumentsWithAddress_expectedCachedDeviceWithAddress() {
- final Bundle args = new Bundle();
- args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS, TEST_ADDRESS);
- mFragment.setArguments(args);
-
- mFragment.onAttach(mContext);
-
- assertThat(mFragment.mCachedDevice.getAddress()).isEqualTo(TEST_ADDRESS);
- }
-
- private void setupEnvironment() {
- ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
- when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
- when(mLocalBluetoothManager.getBluetoothAdapter()).thenReturn(mLocalBluetoothAdapter);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
index 0278553..5e9fb73 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
@@ -710,7 +710,7 @@
@Test
public void initPreferenceForTriState_isValidPackageName_hasCorrectString() {
- when(mBatteryOptimizeUtils.isValidPackageName()).thenReturn(false);
+ when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true);
mFragment.initPreferenceForTriState(mContext);
@@ -720,7 +720,7 @@
@Test
public void initPreferenceForTriState_isSystemOrDefaultApp_hasCorrectString() {
- when(mBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
mFragment.initPreferenceForTriState(mContext);
@@ -731,7 +731,7 @@
@Test
public void initPreferenceForTriState_hasCorrectString() {
- when(mBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(false);
mFragment.initPreferenceForTriState(mContext);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java
index 8970730..a800fdb 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java
@@ -160,34 +160,6 @@
}
@Test
- public void performBackup_oneFullPowerListElement_backupFullPowerListData()
- throws Exception {
- final String[] fullPowerList = {"com.android.package"};
- doReturn(fullPowerList).when(mDeviceController).getFullPowerWhitelist();
-
- mBatteryBackupHelper.performBackup(null, mBackupDataOutput, null);
-
- final byte[] expectedBytes = fullPowerList[0].getBytes();
- verify(mBackupDataOutput).writeEntityHeader(
- BatteryBackupHelper.KEY_FULL_POWER_LIST, expectedBytes.length);
- verify(mBackupDataOutput).writeEntityData(expectedBytes, expectedBytes.length);
- }
-
- @Test
- public void performBackup_backupFullPowerListData() throws Exception {
- final String[] fullPowerList = {"com.android.package1", "com.android.package2"};
- doReturn(fullPowerList).when(mDeviceController).getFullPowerWhitelist();
-
- mBatteryBackupHelper.performBackup(null, mBackupDataOutput, null);
-
- final String expectedResult = fullPowerList[0] + DELIMITER + fullPowerList[1];
- final byte[] expectedBytes = expectedResult.getBytes();
- verify(mBackupDataOutput).writeEntityHeader(
- BatteryBackupHelper.KEY_FULL_POWER_LIST, expectedBytes.length);
- verify(mBackupDataOutput).writeEntityData(expectedBytes, expectedBytes.length);
- }
-
- @Test
public void performBackup_nonOwner_ignoreAllBackupAction() throws Exception {
ShadowUserHandle.setUid(1);
final String[] fullPowerList = {"com.android.package"};
@@ -283,7 +255,7 @@
@Test
public void restoreEntity_incorrectDataKey_notReadBackupData() throws Exception {
- final String incorrectDataKey = BatteryBackupHelper.KEY_FULL_POWER_LIST;
+ final String incorrectDataKey = "incorrect_data_key";
mockBackupData(30 /*dataSize*/, incorrectDataKey);
mBatteryBackupHelper.restoreEntity(mBackupDataInputStream);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBroadcastReceiverTest.java
index a829c40..62f812d 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryBroadcastReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBroadcastReceiverTest.java
@@ -69,6 +69,7 @@
mBatteryBroadcastReceiver.mBatteryLevel = BATTERY_INIT_LEVEL;
mBatteryBroadcastReceiver.mBatteryStatus = BATTERY_INIT_STATUS;
mBatteryBroadcastReceiver.mBatteryHealth = BatteryManager.BATTERY_HEALTH_UNKNOWN;
+ mBatteryBroadcastReceiver.mChargingStatus = BatteryManager.CHARGING_POLICY_DEFAULT;
mBatteryBroadcastReceiver.setBatteryChangedListener(mBatteryListener);
mChargingIntent = new Intent(Intent.ACTION_BATTERY_CHANGED);
@@ -91,8 +92,8 @@
@Test
public void onReceive_batteryHealthChanged_dataUpdated() {
- mChargingIntent
- .putExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_OVERHEAT);
+ mChargingIntent.putExtra(
+ BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_OVERHEAT);
mBatteryBroadcastReceiver.onReceive(mContext, mChargingIntent);
assertThat(mBatteryBroadcastReceiver.mBatteryHealth)
@@ -101,6 +102,17 @@
}
@Test
+ public void onReceive_chargingStatusChanged_dataUpdated() {
+ mChargingIntent.putExtra(BatteryManager.EXTRA_CHARGING_STATUS,
+ BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE);
+ mBatteryBroadcastReceiver.onReceive(mContext, mChargingIntent);
+
+ assertThat(mBatteryBroadcastReceiver.mChargingStatus)
+ .isEqualTo(BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE);
+ verify(mBatteryListener).onBatteryChanged(BatteryUpdateType.CHARGING_STATUS);
+ }
+
+ @Test
public void onReceive_batteryNotPresent_shouldShowHelpMessage() {
mChargingIntent.putExtra(BatteryManager.EXTRA_PRESENT, false);
@@ -131,6 +143,8 @@
assertThat(mBatteryBroadcastReceiver.mBatteryStatus).isEqualTo(batteryStatus);
assertThat(mBatteryBroadcastReceiver.mBatteryHealth)
.isEqualTo(BatteryManager.BATTERY_HEALTH_UNKNOWN);
+ assertThat(mBatteryBroadcastReceiver.mChargingStatus)
+ .isEqualTo(BatteryManager.CHARGING_POLICY_DEFAULT);
verify(mBatteryListener, never()).onBatteryChanged(anyInt());
}
@@ -163,6 +177,8 @@
Utils.getBatteryStatus(mContext, mChargingIntent, /* compactStatus= */ false));
assertThat(mBatteryBroadcastReceiver.mBatteryHealth)
.isEqualTo(BatteryManager.BATTERY_HEALTH_UNKNOWN);
+ assertThat(mBatteryBroadcastReceiver.mChargingStatus)
+ .isEqualTo(BatteryManager.CHARGING_POLICY_DEFAULT);
// 2 times because register will force update the battery
verify(mBatteryListener, times(2)).onBatteryChanged(BatteryUpdateType.MANUAL);
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
index f94e5bf..2779e0a 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
@@ -290,8 +290,8 @@
}
@Test
- public void updatePreference_isOverheat_showEmptyText() {
- mBatteryInfo.isOverheated = true;
+ public void updatePreference_isBatteryDefender_showEmptyText() {
+ mBatteryInfo.isBatteryDefender = true;
mController.updateHeaderPreference(mBatteryInfo);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java
index eb4b598..b0d6da6 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java
@@ -43,7 +43,6 @@
import com.android.settings.testutils.BatteryTestUtils;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.widget.UsageView;
-import com.android.settingslib.R;
import com.android.settingslib.fuelgauge.Estimate;
import org.junit.Before;
@@ -164,26 +163,6 @@
}
@Test
- public void testGetBatteryInfo_basedOnUsageTrueLessThanSevenMinutes_usesCorrectString() {
- Estimate estimate = new Estimate(Duration.ofMinutes(7).toMillis(),
- true /* isBasedOnUsage */,
- 1000 /* averageDischargeTime */);
- BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
- mBatteryUsageStats, estimate, SystemClock.elapsedRealtime() * 1000,
- false /* shortString */);
- BatteryInfo info2 = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
- mBatteryUsageStats, estimate, SystemClock.elapsedRealtime() * 1000,
- true /* shortString */);
-
- // These should be identical in either case
- assertThat(info.remainingLabel.toString()).isEqualTo(
- mContext.getString(R.string.power_remaining_duration_only_shutdown_imminent));
- assertThat(info2.remainingLabel.toString()).isEqualTo(
- mContext.getString(R.string.power_remaining_duration_only_shutdown_imminent));
- assertThat(info2.suggestionLabel).contains(BATTERY_RUN_OUT_PREFIX);
- }
-
- @Test
@Ignore
public void getBatteryInfo_MoreThanOneDay_suggestionLabelIsCorrectString() {
Estimate estimate = new Estimate(Duration.ofDays(3).toMillis(),
@@ -197,25 +176,6 @@
}
@Test
- public void
- testGetBatteryInfo_basedOnUsageTrueBetweenSevenAndFifteenMinutes_usesCorrectString() {
- Estimate estimate = new Estimate(Duration.ofMinutes(10).toMillis(),
- true /* isBasedOnUsage */,
- 1000 /* averageDischargeTime */);
- BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
- mBatteryUsageStats, estimate, SystemClock.elapsedRealtime() * 1000,
- false /* shortString */);
-
- // Check that strings are showing less than 15 minutes remaining regardless of exact time.
- assertThat(info.chargeLabel.toString()).isEqualTo(
- mContext.getString(R.string.power_remaining_less_than_duration,
- FIFTEEN_MIN_FORMATTED, TEST_BATTERY_LEVEL_10));
- assertThat(info.remainingLabel.toString()).isEqualTo(
- mContext.getString(R.string.power_remaining_less_than_duration_only,
- FIFTEEN_MIN_FORMATTED));
- }
-
- @Test
public void testGetBatteryInfo_basedOnUsageFalse_usesDefaultString() {
BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
mBatteryUsageStats, MOCK_ESTIMATE, SystemClock.elapsedRealtime() * 1000,
@@ -254,18 +214,18 @@
}
@Test
- public void testGetBatteryInfo_chargingWithOverheated_updateChargeLabel() {
+ public void testGetBatteryInfo_chargingWithDefender_updateChargeLabel() {
doReturn(TEST_CHARGE_TIME_REMAINING)
.when(mBatteryUsageStats)
.getChargeTimeRemainingMs();
- mChargingBatteryBroadcast
- .putExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_OVERHEAT);
+ mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_CHARGING_STATUS,
+ BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE);
BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
mBatteryUsageStats, MOCK_ESTIMATE, SystemClock.elapsedRealtime() * 1000,
false /* shortString */);
- assertThat(info.isOverheated).isTrue();
+ assertThat(info.isBatteryDefender).isTrue();
assertThat(info.chargeLabel.toString()).contains(STATUS_CHARGING_PAUSED);
}
@@ -278,7 +238,8 @@
50 /* level */,
100 /* scale */,
BatteryManager.BATTERY_STATUS_CHARGING)
- .putExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_OVERHEAT);
+ .putExtra(BatteryManager.EXTRA_CHARGING_STATUS,
+ BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE);
BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, intent,
mBatteryUsageStats, MOCK_ESTIMATE, SystemClock.elapsedRealtime() * 1000,
@@ -290,8 +251,8 @@
@Test
public void testGetBatteryInfo_dockDefenderTemporarilyBypassed_updateChargeLabel() {
doReturn(REMAINING_TIME).when(mBatteryUsageStats).getChargeTimeRemainingMs();
- mChargingBatteryBroadcast
- .putExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_GOOD);
+ mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_CHARGING_STATUS,
+ BatteryManager.CHARGING_POLICY_DEFAULT);
Settings.Global.putInt(mContext.getContentResolver(),
BatteryUtils.SETTINGS_GLOBAL_DOCK_DEFENDER_BYPASS, 1);
@@ -309,8 +270,8 @@
@Test
public void testGetBatteryInfo_dockDefenderFutureBypass_updateChargeLabel() {
doReturn(false).when(mFeatureFactory.powerUsageFeatureProvider).isExtraDefend();
- mChargingBatteryBroadcast
- .putExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_GOOD);
+ mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_CHARGING_STATUS,
+ BatteryManager.CHARGING_POLICY_DEFAULT);
BatteryInfo info = BatteryInfo.getBatteryInfo(mContext,
BatteryTestUtils.getCustomBatteryIntent(BatteryManager.BATTERY_PLUGGED_DOCK,
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizeUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizeUtilsTest.java
index 83a75f6..f9d3108 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizeUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizeUtilsTest.java
@@ -136,16 +136,16 @@
}
@Test
- public void testIsValidPackageName_InvalidPackageName_returnFalse() {
+ public void isDisabledForOptimizeModeOnly_invalidPackageName_returnTrue() {
final BatteryOptimizeUtils testBatteryOptimizeUtils =
new BatteryOptimizeUtils(mContext, UID, null);
- assertThat(testBatteryOptimizeUtils.isValidPackageName()).isFalse();
+ assertThat(testBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).isTrue();
}
@Test
- public void testIsValidPackageName_validPackageName_returnTrue() {
- assertThat(mBatteryOptimizeUtils.isValidPackageName()).isTrue();
+ public void isDisabledForOptimizeModeOnly_validPackageName_returnFalse() {
+ assertThat(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).isFalse();
}
@Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java
index dfee3e7..c34dcec 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java
@@ -18,35 +18,76 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.UserHandle;
+import android.os.UserManager;
import com.android.settings.TestUtils;
+import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry;
import com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleRadioButtonsController;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {BatterySettingsMigrateCheckerTest.ShadowUserHandle.class})
public final class BatterySettingsMigrateCheckerTest {
private static final Intent BOOT_COMPLETED_INTENT =
new Intent(Intent.ACTION_BOOT_COMPLETED);
+ private static final int UID = 2003;
+ private static final String PACKAGE_NAME = "com.android.test.app";
private Context mContext;
private BatterySettingsMigrateChecker mBatterySettingsMigrateChecker;
+ @Mock
+ private PackageManager mPackageManager;
+ @Mock
+ private BatteryOptimizeUtils mBatteryOptimizeUtils;
+
@Before
- public void setUp() {
+ public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
+ mContext = spy(RuntimeEnvironment.application);
+ doReturn(mContext).when(mContext).getApplicationContext();
+ doReturn(mPackageManager).when(mContext).getPackageManager();
+ doReturn(UID).when(mPackageManager)
+ .getPackageUid(PACKAGE_NAME, PackageManager.GET_META_DATA);
+ BatterySettingsMigrateChecker.sBatteryOptimizeUtils = mBatteryOptimizeUtils;
mBatterySettingsMigrateChecker = new BatterySettingsMigrateChecker();
}
+ @After
+ public void resetShadows() {
+ ShadowUserHandle.reset();
+ }
+
@Test
public void onReceive_invalidScheduledLevel_resetScheduledValue() {
final int invalidScheduledLevel = 5;
@@ -98,6 +139,54 @@
assertThat(getScheduledLevel()).isEqualTo(invalidScheduledLevel);
}
+ @Test
+ public void onReceive_nonOwner_noAction() {
+ ShadowUserHandle.setUid(1);
+ final int invalidScheduledLevel = 5;
+ setScheduledLevel(invalidScheduledLevel);
+
+ mBatterySettingsMigrateChecker.onReceive(mContext, BOOT_COMPLETED_INTENT);
+
+ assertThat(getScheduledLevel()).isEqualTo(invalidScheduledLevel);
+ }
+
+ @Test
+ public void verifyOptimizationModes_inAllowList_resetOptimizationMode() throws Exception {
+ doReturn(BatteryOptimizeUtils.MODE_RESTRICTED).when(mBatteryOptimizeUtils)
+ .getAppOptimizationMode();
+
+ mBatterySettingsMigrateChecker.verifyOptimizationModes(
+ mContext, Arrays.asList(PACKAGE_NAME));
+
+ final InOrder inOrder = inOrder(mBatteryOptimizeUtils);
+ inOrder.verify(mBatteryOptimizeUtils).getAppOptimizationMode();
+ inOrder.verify(mBatteryOptimizeUtils).setAppUsageState(
+ BatteryOptimizeUtils.MODE_OPTIMIZED,
+ BatteryOptimizeHistoricalLogEntry.Action.FORCE_RESET);
+ }
+
+ @Test
+ public void verifyOptimizationModes_optimizedMode_noAction() throws Exception {
+ doReturn(BatteryOptimizeUtils.MODE_OPTIMIZED).when(mBatteryOptimizeUtils)
+ .getAppOptimizationMode();
+
+ mBatterySettingsMigrateChecker.verifyOptimizationModes(
+ mContext, Arrays.asList(PACKAGE_NAME));
+
+ verify(mBatteryOptimizeUtils, never()).setAppUsageState(anyInt(), any());
+ }
+
+ @Test
+ public void verifyOptimizationModes_notInAllowList_noAction() throws Exception {
+ doReturn(BatteryOptimizeUtils.MODE_RESTRICTED).when(mBatteryOptimizeUtils)
+ .getAppOptimizationMode();
+
+ mBatterySettingsMigrateChecker.verifyOptimizationModes(
+ mContext, new ArrayList<String>());
+
+ verifyNoInteractions(mBatteryOptimizeUtils);
+ }
+
private void setScheduledLevel(int scheduledLevel) {
TestUtils.setScheduledLevel(mContext, scheduledLevel);
}
@@ -105,4 +194,24 @@
private int getScheduledLevel() {
return TestUtils.getScheduledLevel(mContext);
}
+
+ @Implements(UserHandle.class)
+ public static class ShadowUserHandle {
+ // Sets the default as thte OWNER role.
+ private static int sUid = 0;
+
+ public static void setUid(int uid) {
+ sUid = uid;
+ }
+
+ @Implementation
+ public static int myUserId() {
+ return sUid;
+ }
+
+ @Resetter
+ public static void reset() {
+ sUid = 0;
+ }
+ }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
index b5f8149..2fe0cec 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
@@ -487,32 +487,32 @@
}
@Test
- public void testIsBatteryDefenderOn_isOverheatedAndIsCharging_returnTrue() {
- mBatteryInfo.isOverheated = true;
+ public void testIsBatteryDefenderOn_isDefenderAndIsCharging_returnTrue() {
+ mBatteryInfo.isBatteryDefender = true;
mBatteryInfo.discharging = false;
assertThat(mBatteryUtils.isBatteryDefenderOn(mBatteryInfo)).isTrue();
}
@Test
- public void testIsBatteryDefenderOn_isOverheatedAndDischarging_returnFalse() {
- mBatteryInfo.isOverheated = true;
+ public void testIsBatteryDefenderOn_isDefenderAndDischarging_returnFalse() {
+ mBatteryInfo.isBatteryDefender = true;
mBatteryInfo.discharging = true;
assertThat(mBatteryUtils.isBatteryDefenderOn(mBatteryInfo)).isFalse();
}
@Test
- public void testIsBatteryDefenderOn_notOverheatedAndDischarging_returnFalse() {
- mBatteryInfo.isOverheated = false;
+ public void testIsBatteryDefenderOn_notDefenderAndDischarging_returnFalse() {
+ mBatteryInfo.isBatteryDefender = false;
mBatteryInfo.discharging = true;
assertThat(mBatteryUtils.isBatteryDefenderOn(mBatteryInfo)).isFalse();
}
@Test
- public void testIsBatteryDefenderOn_notOverheatedAndIsCharging_returnFalse() {
- mBatteryInfo.isOverheated = false;
+ public void testIsBatteryDefenderOn_notDefenderAndIsCharging_returnFalse() {
+ mBatteryInfo.isBatteryDefender = false;
mBatteryInfo.discharging = false;
assertThat(mBatteryUtils.isBatteryDefenderOn(mBatteryInfo)).isFalse();
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/OptimizedPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/OptimizedPreferenceControllerTest.java
index 1fec92a..71bb998 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/OptimizedPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/OptimizedPreferenceControllerTest.java
@@ -52,7 +52,7 @@
@Test
public void testUpdateState_invalidPackage_prefEnabled() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(false);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true);
mController.updateState(mPreference);
@@ -62,7 +62,7 @@
@Test
public void testUpdateState_isSystemOrDefaultAppAndOptimizeStates_prefChecked() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
when(mockBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
BatteryOptimizeUtils.MODE_OPTIMIZED);
@@ -74,7 +74,7 @@
@Test
public void testUpdateState_isSystemOrDefaultApp_prefUnchecked() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
mController.updateState(mPreference);
@@ -85,7 +85,7 @@
@Test
public void testUpdateState_isOptimizedStates_prefChecked() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
when(mockBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
BatteryOptimizeUtils.MODE_OPTIMIZED);
@@ -96,7 +96,7 @@
@Test
public void testUpdateState_prefUnchecked() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
mController.updateState(mPreference);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/RestrictedPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/RestrictedPreferenceControllerTest.java
index 944376c..bcddbc2 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/RestrictedPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/RestrictedPreferenceControllerTest.java
@@ -52,7 +52,7 @@
@Test
public void testUpdateState_isValidPackage_prefEnabled() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
mController.updateState(mPreference);
@@ -61,7 +61,7 @@
@Test
public void testUpdateState_invalidPackage_prefDisabled() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(false);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true);
mController.updateState(mPreference);
@@ -70,7 +70,7 @@
@Test
public void testUpdateState_isSystemOrDefaultAppAndRestrictedStates_prefChecked() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
when(mockBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
BatteryOptimizeUtils.MODE_RESTRICTED);
@@ -82,7 +82,7 @@
@Test
public void testUpdateState_isSystemOrDefaultApp_prefUnchecked() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
mController.updateState(mPreference);
@@ -93,7 +93,7 @@
@Test
public void testUpdateState_isRestrictedStates_prefChecked() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
when(mockBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
BatteryOptimizeUtils.MODE_RESTRICTED);
@@ -104,7 +104,7 @@
@Test
public void testUpdateState_prefUnchecked() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
mController.updateState(mPreference);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/UnrestrictedPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/UnrestrictedPreferenceControllerTest.java
index c5642df..9bed9ba 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/UnrestrictedPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/UnrestrictedPreferenceControllerTest.java
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-
package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
@@ -53,7 +52,7 @@
@Test
public void testUpdateState_isValidPackage_prefEnabled() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
mController.updateState(mPreference);
@@ -62,7 +61,7 @@
@Test
public void testUpdateState_invalidPackage_prefDisabled() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(false);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true);
mController.updateState(mPreference);
@@ -71,7 +70,7 @@
@Test
public void testUpdateState_isSystemOrDefaultAppAndUnrestrictedStates_prefChecked() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
when(mockBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
BatteryOptimizeUtils.MODE_UNRESTRICTED);
@@ -83,7 +82,7 @@
@Test
public void testUpdateState_isSystemOrDefaultApp_prefUnchecked() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
mController.updateState(mPreference);
@@ -94,7 +93,7 @@
@Test
public void testUpdateState_isUnrestrictedStates_prefChecked() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
when(mockBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
BatteryOptimizeUtils.MODE_UNRESTRICTED);
@@ -105,7 +104,7 @@
@Test
public void testUpdateState_prefUnchecked() {
- when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
+ when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
mController.updateState(mPreference);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/BatteryDefenderDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/BatteryDefenderDetectorTest.java
index f81a4be..64d5d04 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/BatteryDefenderDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/BatteryDefenderDetectorTest.java
@@ -60,32 +60,32 @@
}
@Test
- public void testDetect_notOverheatedNotExtraDefend_tipInvisible() {
- mBatteryInfo.isOverheated = false;
+ public void testDetect_notDefenderNotExtraDefend_tipInvisible() {
+ mBatteryInfo.isBatteryDefender = false;
when(mFakeFeatureFactory.powerUsageFeatureProvider.isExtraDefend()).thenReturn(false);
assertThat(mBatteryDefenderDetector.detect().isVisible()).isFalse();
}
@Test
- public void testDetect_notOverheatedIsExtraDefend_tipInvisible() {
- mBatteryInfo.isOverheated = false;
+ public void testDetect_notDefenderIsExtraDefend_tipInvisible() {
+ mBatteryInfo.isBatteryDefender = false;
when(mFakeFeatureFactory.powerUsageFeatureProvider.isExtraDefend()).thenReturn(true);
assertThat(mBatteryDefenderDetector.detect().isVisible()).isFalse();
}
@Test
- public void testDetect_isOverheatedIsExtraDefend_tipInvisible() {
- mBatteryInfo.isOverheated = false;
+ public void testDetect_isDefenderIsExtraDefend_tipInvisible() {
+ mBatteryInfo.isBatteryDefender = false;
when(mFakeFeatureFactory.powerUsageFeatureProvider.isExtraDefend()).thenReturn(true);
assertThat(mBatteryDefenderDetector.detect().isVisible()).isFalse();
}
@Test
- public void testDetect_isOverheatedNotExtraDefend_tipNew() {
- mBatteryInfo.isOverheated = true;
+ public void testDetect_isDefenderNotExtraDefend_tipNew() {
+ mBatteryInfo.isBatteryDefender = true;
when(mFakeFeatureFactory.powerUsageFeatureProvider.isExtraDefend()).thenReturn(false);
assertThat(mBatteryDefenderDetector.detect().getState())
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/DockDefenderDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/DockDefenderDetectorTest.java
index 9652a00..bd2c5d1 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/DockDefenderDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/DockDefenderDetectorTest.java
@@ -83,7 +83,7 @@
@Test
public void testDetect_dockDefenderActive() {
- mBatteryInfo.isOverheated = true;
+ mBatteryInfo.isBatteryDefender = true;
doReturn(true).when(mFakeFeatureFactory.powerUsageFeatureProvider).isExtraDefend();
BatteryTip batteryTip = mDockDefenderDetector.detect();
@@ -95,7 +95,7 @@
@Test
public void testDetect_dockDefenderFutureBypass() {
- mBatteryInfo.isOverheated = false;
+ mBatteryInfo.isBatteryDefender = false;
doReturn(false).when(mFakeFeatureFactory.powerUsageFeatureProvider).isExtraDefend();
BatteryTip batteryTip = mDockDefenderDetector.detect();
@@ -107,7 +107,7 @@
@Test
public void testDetect_overheatedTrue_dockDefenderDisabled() {
- mBatteryInfo.isOverheated = true;
+ mBatteryInfo.isBatteryDefender = true;
doReturn(false).when(mFakeFeatureFactory.powerUsageFeatureProvider).isExtraDefend();
BatteryTip batteryTip = mDockDefenderDetector.detect();
@@ -131,7 +131,7 @@
@Test
public void testDetect_overheatedTrueAndDockDefenderNotTriggered_dockDefenderDisabled() {
doReturn(false).when(mFakeFeatureFactory.powerUsageFeatureProvider).isExtraDefend();
- mBatteryInfo.isOverheated = true;
+ mBatteryInfo.isBatteryDefender = true;
BatteryTip batteryTip = mDockDefenderDetector.detect();
diff --git a/tests/unit/src/com/android/settings/biometrics/face/FaceUpdaterTest.java b/tests/unit/src/com/android/settings/biometrics/face/FaceUpdaterTest.java
index a49b4a6..66514ac 100644
--- a/tests/unit/src/com/android/settings/biometrics/face/FaceUpdaterTest.java
+++ b/tests/unit/src/com/android/settings/biometrics/face/FaceUpdaterTest.java
@@ -39,6 +39,7 @@
import com.android.settings.safetycenter.SafetyCenterManagerWrapper;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -152,6 +153,7 @@
verify(mSafetyCenterManagerWrapper, never()).isEnabled(any());
}
+ @Ignore("b/282413778")
@Test
public void enroll_secondVersion_onEnrollmentCallbacks_triggerGivenCallback() {
ArgumentCaptor<FaceManager.EnrollmentCallback> callbackCaptor =
@@ -180,6 +182,7 @@
.onEnrollmentFrame(HELP_CODE, HELP_MESSAGE, CELL, STAGE, PAN, TILT, DISTANCE);
}
+ @Ignore("b/282413778")
@Test
public void enroll_secondVersion_onEnrollmentSuccess_invokedInteractionWithSafetyCenter() {
ArgumentCaptor<FaceManager.EnrollmentCallback> callbackCaptor =
@@ -201,6 +204,7 @@
verify(mSafetyCenterManagerWrapper).isEnabled(mContext);
}
+ @Ignore("b/282413778")
@Test
public void enroll_secondVersion_onEnrollmentNotYetFinished_didntInvokeInteractionWithSafetyCenter() {
ArgumentCaptor<FaceManager.EnrollmentCallback> callbackCaptor =