Merge "Set higher priority for ADD_DEVICE_ADMIN intent" into tm-dev
diff --git a/res/layout/apps_filter_spinner.xml b/res/layout/apps_filter_spinner.xml
index fcdcb5e..dfd41d4 100644
--- a/res/layout/apps_filter_spinner.xml
+++ b/res/layout/apps_filter_spinner.xml
@@ -33,8 +33,8 @@
style="?android:attr/borderlessButtonStyle"
android:layout_width="56dp"
android:layout_height="56dp"
- android:layout_marginTop="12dp"
- android:layout_toEndOf="@id/filter_spinner"
+ android:layout_centerHorizontal="true"
+ android:layout_toRightOf="@+id/filter_spinner"
android:contentDescription="@string/configure"
android:scaleType="center"
android:src="@drawable/ic_apps_filter_settings_24dp"
diff --git a/res/layout/confirm_convert_fbe.xml b/res/layout/confirm_convert_fbe.xml
deleted file mode 100644
index 537c368..0000000
--- a/res/layout/confirm_convert_fbe.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:layout_marginBottom="12dp" >
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="12dp"
- android:layout_marginEnd="12dp"
- android:layout_marginTop="12dp"
- android:textSize="18sp"
- android:text="@string/confirm_convert_to_fbe_warning" />
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_gravity="center"
- android:orientation="horizontal">
- <Button
- android:id="@+id/button_confirm_convert_fbe"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- android:layout_marginBottom="12dp"
- android:text="@string/button_confirm_convert_fbe" />
- </LinearLayout>
-
-</LinearLayout>
diff --git a/res/layout/convert_fbe.xml b/res/layout/convert_fbe.xml
deleted file mode 100644
index d1e0cea..0000000
--- a/res/layout/convert_fbe.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:layout_marginBottom="12dp" >
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/preference_no_icon_padding_start"
- android:layout_marginEnd="12dp"
- android:layout_marginTop="12dp"
- android:textSize="18sp"
- android:text="@string/convert_to_fbe_warning" />
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_gravity="center"
- android:orientation="horizontal">
- <Button
- android:id="@+id/button_convert_fbe"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- android:layout_marginBottom="12dp"
- android:text="@string/button_convert_fbe" />
- </LinearLayout>
-
-</LinearLayout>
diff --git a/res/layout/le_audio_bt_entity_header.xml b/res/layout/le_audio_bt_entity_header.xml
new file mode 100644
index 0000000..6e2a1e8
--- /dev/null
+++ b/res/layout/le_audio_bt_entity_header.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/entity_header"
+ style="@style/EntityHeader"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:gravity="center_horizontal"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/entity_header_title"
+ style="@style/TextAppearance.EntityHeaderTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:singleLine="false"
+ android:ellipsize="marquee"
+ android:textDirection="locale"/>
+
+ <TextView
+ android:id="@+id/entity_header_summary"
+ style="@style/TextAppearance.EntityHeaderSummary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginTop="4dp"
+ android:singleLine="false"
+ android:ellipsize="marquee"
+ android:textDirection="locale"/>
+
+ <ImageView
+ android:id="@+id/entity_header_icon"
+ android:layout_width="72dp"
+ android:layout_height="72dp"
+ android:layout_marginTop="24dp"
+ android:scaleType="fitCenter"
+ android:antialias="true"/>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/le_bluetooth_battery_start_margin"
+ android:orientation="vertical">
+ <TextView
+ android:id="@+id/bt_battery_case_title"
+ style="@style/TextAppearance.EntityHeaderTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/le_bluetooth_battery_top_margin"
+ android:gravity="start|center_vertical"
+ android:ellipsize="end"
+ android:textDirection="locale"
+ android:text="@string/bluetooth_middle_name"
+ android:textSize="@dimen/advanced_bluetooth_header_title_text_size"
+ android:visibility="gone"/>
+ <TextView
+ android:id="@+id/bt_battery_left_title"
+ style="@style/TextAppearance.EntityHeaderTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/le_bluetooth_battery_top_margin"
+ android:gravity="start|center_vertical"
+ android:ellipsize="end"
+ android:textDirection="locale"
+ android:text="@string/bluetooth_left_name"
+ android:textSize="@dimen/advanced_bluetooth_header_title_text_size"/>
+ <TextView
+ android:id="@+id/bt_battery_right_title"
+ style="@style/TextAppearance.EntityHeaderTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/le_bluetooth_battery_top_margin"
+ android:gravity="start|center_vertical"
+ android:ellipsize="end"
+ android:textDirection="locale"
+ android:text="@string/bluetooth_right_name"
+ android:textSize="@dimen/advanced_bluetooth_header_title_text_size"/>
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/le_bluetooth_summary_start_margin"
+ android:orientation="vertical">
+ <TextView
+ android:id="@+id/bt_battery_case_summary"
+ style="@style/TextAppearance.EntityHeaderSummary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/le_bluetooth_battery_top_margin"
+ android:padding="@dimen/le_bluetooth_summary_padding"
+ android:drawablePadding="@dimen/le_bluetooth_summary_drawable_padding"
+ android:visibility="gone"/>
+ <TextView
+ android:id="@+id/bt_battery_left_summary"
+ style="@style/TextAppearance.EntityHeaderSummary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/le_bluetooth_battery_top_margin"
+ android:padding="@dimen/le_bluetooth_summary_padding"
+ android:drawablePadding="@dimen/le_bluetooth_summary_drawable_padding"/>
+ <TextView
+ android:id="@+id/bt_battery_right_summary"
+ style="@style/TextAppearance.EntityHeaderSummary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/le_bluetooth_battery_top_margin"
+ android:padding="@dimen/le_bluetooth_summary_padding"
+ android:drawablePadding="@dimen/le_bluetooth_summary_drawable_padding"/>
+ </LinearLayout>
+ </LinearLayout>
+</LinearLayout>
diff --git a/res/raw/udfps_edge_hint_lottie.json b/res/raw/udfps_left_edge_hint_lottie.json
similarity index 100%
rename from res/raw/udfps_edge_hint_lottie.json
rename to res/raw/udfps_left_edge_hint_lottie.json
diff --git a/res/raw/udfps_edge_hint_lottie.json b/res/raw/udfps_right_edge_hint_lottie.json
similarity index 100%
copy from res/raw/udfps_edge_hint_lottie.json
copy to res/raw/udfps_right_edge_hint_lottie.json
diff --git a/res/values/config.xml b/res/values/config.xml
index 8933305..0d67de7 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -618,4 +618,6 @@
<!-- Whether the dream setup activity should be enabled as part of setupwizard -->
<bool name="dream_setup_supported">false</bool>
+ <!-- Whether to put the apps with system UID into system component bucket or not -->
+ <bool name="config_battery_combine_system_components">false</bool>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index c44a1cb..8a59da2 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -399,6 +399,13 @@
<dimen name="advanced_bluetooth_battery_height">27.5dp</dimen>
<dimen name="advanced_bluetooth_battery_right_margin">-4dp</dimen>
+ <!-- Header layout of LE audio bluetooth device at bluretooth device detalis -->
+ <dimen name="le_bluetooth_battery_top_margin">5dp</dimen>
+ <dimen name="le_bluetooth_battery_start_margin">10dp</dimen>
+ <dimen name="le_bluetooth_summary_drawable_padding">6dp</dimen>
+ <dimen name="le_bluetooth_summary_start_margin">20dp</dimen>
+ <dimen name="le_bluetooth_summary_padding">1.5dp</dimen>
+
<!-- Developer option bluetooth settings dialog -->
<dimen name="developer_option_dialog_margin_start">8dp</dimen>
<dimen name="developer_option_dialog_margin_top">8dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2c0780f..27f57a7 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5405,7 +5405,7 @@
<!-- Description for the accessibility button in gesture navigation. Explain how this page works. [CHAR LIMIT=NONE] -->
<string name="accessibility_button_gesture_description"><b>To get started</b>\n1. Go to accessibility settings\n2. Select a feature and tap the shortcut\n3. Choose whether you want to use a button or gesture to access the feature</string>
<!-- Description for the accessibility button page. Explain how this page works. [CHAR LIMIT=NONE] -->
- <string name="accessibility_button_description"><b>To get started</b>\n1. Go to accessibility settings\n2. Select a feature and tap the shortcut\n3. Choose the button to use to access the feature</string>
+ <string name="accessibility_button_description"><b>To get started</b>\n1. Go to accessibility settings\n2. Select a feature and tap the shortcut\n3. Choose the button to access the feature</string>
<!-- Title for the button or gesture of the accessibility button. [CHAR LIMIT=35] -->
<string name="accessibility_button_or_gesture_title">Use button or gesture</string>
<!-- Title for the location of the accessibility button. [CHAR LIMIT=35] -->
@@ -7774,6 +7774,8 @@
<string name="nfc_payment_btn_text_set_deault">Set default</string>
<!-- Label of the Update button of the Update default payment app dialog [CHAR LIMIT=40] -->
<string name="nfc_payment_btn_text_update">Update</string>
+ <!-- Summary text of the work apps in the default payment selection list [CHAR LIMIT=20]-->
+ <string name="nfc_work_text">Work</string>
<!-- Restrictions settings --><skip/>
<!-- Restriction settings title [CHAR LIMIT=35] -->
@@ -8294,7 +8296,7 @@
<string name="keywords_sounds_and_notifications_interruptions">dont don\u2019t disturb, interrupt, interruption, break</string>
<string name="keywords_app">RAM</string>
<string name="keywords_location">nearby, location, history, reporting, GPS</string>
- <string name="keywords_accounts">account, add an account, work profile, add account</string>
+ <string name="keywords_accounts">account, add an account, work profile, add account, remove, delete</string>
<string name="keywords_users">restriction, restrict, restricted</string>
<string name="keywords_keyboard_and_ime">text correction, correct, sound, vibrate, auto, language, gesture, suggest, suggestion, theme, offensive, word, type, emoji, international</string>
<string name="keywords_reset_apps">reset, preferences, default</string>
@@ -9850,7 +9852,7 @@
<string name="zen_mode_people_calls_messages_section_title">Who can interrupt</string>
<!-- [CHAR LIMIT=NONE] Zen mode settings: people screen footer -->
- <string name="zen_mode_people_footer" translatable="false">Even if messaging or calling apps can\u0027t notify you, people you choose here can still reach you through those apps</string>
+ <string name="zen_mode_people_footer">Even if messaging or calling apps can\u0027t notify you, people you choose here can still reach you through those apps</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Allow calls toggle title -->
<string name="zen_mode_calls_title">Calls</string>
@@ -11594,11 +11596,6 @@
<!-- Title for the See more preference item in Special app access settings [CHAR LIMIT=30] -->
<string name="special_access_more">See more</string>
- <!-- Developer option to convert to file encryption - final warning -->
- <string name="confirm_convert_to_fbe_warning">Really wipe user data and convert to file encryption?</string>
- <!-- Developer option to convert to file encryption - final button -->
- <string name="button_confirm_convert_fbe">Wipe and convert</string>
-
<!-- Reset rate-limiting in the system service ShortcutManager. "ShortcutManager" is the name of a system service and not translatable.
If the word "rate-limit" is hard to translate, use "Reset ShortcutManager API call limit" as the source text, which means
the same thing in this context.
diff --git a/res/values/styles.xml b/res/values/styles.xml
index c3ed5b2..bd0aea1 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -432,12 +432,12 @@
</style>
<style name="LockPatternContainerStyle">
- <item name="android:maxHeight">400dp</item>
- <item name="android:maxWidth">420dp</item>
+ <item name="android:maxHeight">620dp</item>
+ <item name="android:maxWidth">620dp</item>
<item name="android:minHeight">0dp</item>
<item name="android:minWidth">0dp</item>
<item name="android:paddingBottom">0dp</item>
- <item name="android:paddingHorizontal">44dp</item>
+ <item name="android:paddingHorizontal">0dp</item>
<item name="android:paddingTop">0dp</item>
</style>
diff --git a/res/xml/bluetooth_device_details_fragment.xml b/res/xml/bluetooth_device_details_fragment.xml
index ef5a990..f6c0af6 100644
--- a/res/xml/bluetooth_device_details_fragment.xml
+++ b/res/xml/bluetooth_device_details_fragment.xml
@@ -34,6 +34,14 @@
settings:searchable="false"
settings:controller="com.android.settings.bluetooth.AdvancedBluetoothDetailsHeaderController"/>
+ <com.android.settingslib.widget.LayoutPreference
+ android:key="le_audio_bluetooth_device_header"
+ android:layout="@layout/le_audio_bt_entity_header"
+ android:selectable="false"
+ settings:allowDividerBelow="true"
+ settings:searchable="false"
+ settings:controller="com.android.settings.bluetooth.LeAudioBluetoothDetailsHeaderController"/>
+
<com.android.settingslib.widget.ActionButtonsPreference
android:key="action_buttons"
settings:allowDividerBelow="true"/>
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 75395c0..9867419 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -92,12 +92,6 @@
android:summary="@string/runningservices_settings_summary"
android:fragment="com.android.settings.applications.RunningServices" />
- <Preference
- android:key="convert_to_file_encryption"
- android:title="@string/convert_to_file_encryption"
- android:summary="@string/convert_to_file_encryption_enabled"
- android:fragment="com.android.settings.applications.ConvertToFbe" />
-
<com.android.settings.development.ColorModePreference
android:key="picture_color_mode"
android:title="@string/picture_color_mode"
diff --git a/src/com/android/settings/accessibility/AccessibilityFooterPreference.java b/src/com/android/settings/accessibility/AccessibilityFooterPreference.java
index 67b7827..fd9b6f8 100644
--- a/src/com/android/settings/accessibility/AccessibilityFooterPreference.java
+++ b/src/com/android/settings/accessibility/AccessibilityFooterPreference.java
@@ -25,9 +25,7 @@
import com.android.settingslib.widget.FooterPreference;
-/**
- * A custom preference acting as footer of a page. Disables the movement method by default.
- */
+/** A custom preference acting as footer of a page. Disables the movement method by default. */
public final class AccessibilityFooterPreference extends FooterPreference {
private boolean mLinkEnabled;
@@ -46,12 +44,16 @@
final TextView title = holder.itemView.findViewById(android.R.id.title);
if (mLinkEnabled) {
- // When a TextView has a movement method, it will set the view to clickable. This makes
- // View.onTouchEvent always return true and consumes the touch event, essentially
- // nullifying any return values of MovementMethod.onTouchEvent.
+ // When a TextView has a movement method, it will set the view to focusable and
+ // clickable. This makes View.onTouchEvent always return true and consumes the touch
+ // event, essentially nullifying any return values of MovementMethod.onTouchEvent.
// To still allow propagating touch events to the parent when this view doesn't have
// links, we only set the movement method here if the text contains links.
title.setMovementMethod(LinkMovementMethod.getInstance());
+
+ // Groups of related title and link content by making the container focusable,
+ // then make all the children inside not focusable.
+ title.setFocusable(false);
} else {
title.setMovementMethod(/* movement= */ null);
}
diff --git a/src/com/android/settings/accessibility/AccessibilityFooterPreferenceController.java b/src/com/android/settings/accessibility/AccessibilityFooterPreferenceController.java
index c22b11e..a422eb8 100644
--- a/src/com/android/settings/accessibility/AccessibilityFooterPreferenceController.java
+++ b/src/com/android/settings/accessibility/AccessibilityFooterPreferenceController.java
@@ -122,5 +122,8 @@
} else {
footerPreference.setLinkEnabled(false);
}
+
+ // Grouping subcomponents to make more accessible.
+ footerPreference.setSelectable(false);
}
}
diff --git a/src/com/android/settings/accessibility/HighTextContrastPreferenceController.java b/src/com/android/settings/accessibility/HighTextContrastPreferenceController.java
index aad69b9..8c9d234 100644
--- a/src/com/android/settings/accessibility/HighTextContrastPreferenceController.java
+++ b/src/com/android/settings/accessibility/HighTextContrastPreferenceController.java
@@ -19,6 +19,9 @@
import android.content.Context;
import android.provider.Settings;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
@@ -27,6 +30,7 @@
*/
public class HighTextContrastPreferenceController extends TogglePreferenceController implements
TextReadingResetController.ResetStateListener {
+ private SwitchPreference mSwitchPreference;
public HighTextContrastPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
@@ -55,7 +59,14 @@
}
@Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mSwitchPreference = screen.findPreference(getPreferenceKey());
+ }
+
+ @Override
public void resetState() {
setChecked(false);
+ updateState(mSwitchPreference);
}
}
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index ccdc78b..fd19376 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -564,13 +564,6 @@
createFooterPreference(getPreferenceScreen(), mDescription,
getString(R.string.accessibility_introduction_title, mPackageName));
}
-
- if (TextUtils.isEmpty(mHtmlDescription) && TextUtils.isEmpty(mDescription)) {
- final CharSequence defaultDescription =
- getText(R.string.accessibility_service_default_description);
- createFooterPreference(getPreferenceScreen(), defaultDescription,
- getString(R.string.accessibility_introduction_title, mPackageName));
- }
}
diff --git a/src/com/android/settings/applications/ConfirmConvertToFbe.java b/src/com/android/settings/applications/ConfirmConvertToFbe.java
deleted file mode 100644
index 35ddc6b..0000000
--- a/src/com/android/settings/applications/ConfirmConvertToFbe.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2016 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.applications;
-
-import android.app.settings.SettingsEnums;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-public class ConfirmConvertToFbe extends SettingsPreferenceFragment {
- static final String TAG = "ConfirmConvertToFBE";
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View rootView = inflater.inflate(R.layout.confirm_convert_fbe, null);
-
- final Button button = (Button) rootView.findViewById(R.id.button_confirm_convert_fbe);
- button.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- Intent intent = new Intent(Intent.ACTION_FACTORY_RESET);
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- intent.setPackage("android");
- intent.putExtra(Intent.EXTRA_REASON, "convert_fbe");
- getActivity().sendBroadcast(intent);
- }
- });
-
- return rootView;
- }
-
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.CONVERT_FBE_CONFIRM;
- }
-}
diff --git a/src/com/android/settings/applications/ConvertToFbe.java b/src/com/android/settings/applications/ConvertToFbe.java
deleted file mode 100644
index d470011..0000000
--- a/src/com/android/settings/applications/ConvertToFbe.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2015 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.applications;
-
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.app.settings.SettingsEnums;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-
-import com.android.settings.R;
-import com.android.settings.core.InstrumentedFragment;
-import com.android.settings.core.SubSettingLauncher;
-import com.android.settings.password.ChooseLockSettingsHelper;
-
-/* Class to prompt for conversion of userdata to file based encryption
- */
-public class ConvertToFbe extends InstrumentedFragment {
- static final String TAG = "ConvertToFBE";
- private static final int KEYGUARD_REQUEST = 55;
-
- private boolean runKeyguardConfirmation(int request) {
- Resources res = getActivity().getResources();
- final ChooseLockSettingsHelper.Builder builder =
- new ChooseLockSettingsHelper.Builder(getActivity(), this);
- return builder.setRequestCode(request)
- .setTitle(res.getText(R.string.convert_to_file_encryption))
- .show();
- }
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getActivity().setTitle(R.string.convert_to_file_encryption);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View rootView = inflater.inflate(R.layout.convert_fbe, null);
-
- final Button button = rootView.findViewById(R.id.button_convert_fbe);
- button.setOnClickListener(v -> {
- if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
- convert();
- }
- });
-
- return rootView;
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
-
- if (requestCode != KEYGUARD_REQUEST) {
- return;
- }
-
- // If the user entered a valid keyguard credential, start the conversion
- // process
- if (resultCode == Activity.RESULT_OK) {
- convert();
- }
- }
-
- private void convert() {
- new SubSettingLauncher(getContext())
- .setDestination(ConfirmConvertToFbe.class.getName())
- .setTitleRes(R.string.convert_to_file_encryption)
- .setSourceMetricsCategory(getMetricsCategory())
- .launch();
- }
-
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.CONVERT_FBE;
- }
-}
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
index d42e8f1..70140c4 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
@@ -81,9 +81,11 @@
private static final int STAGE_CENTER = 0;
private static final int STAGE_GUIDED = 1;
private static final int STAGE_FINGERTIP = 2;
- private static final int STAGE_EDGES = 3;
+ private static final int STAGE_LEFT_EDGE = 3;
+ private static final int STAGE_RIGHT_EDGE = 4;
- @IntDef({STAGE_UNKNOWN, STAGE_CENTER, STAGE_GUIDED, STAGE_FINGERTIP, STAGE_EDGES})
+ @IntDef({STAGE_UNKNOWN, STAGE_CENTER, STAGE_GUIDED, STAGE_FINGERTIP, STAGE_LEFT_EDGE,
+ STAGE_RIGHT_EDGE})
@Retention(RetentionPolicy.SOURCE)
private @interface EnrollStage {}
@@ -132,7 +134,8 @@
private boolean mIsAccessibilityEnabled;
private LottieAnimationView mIllustrationLottie;
private boolean mHaveShownUdfpsTipLottie;
- private boolean mHaveShownUdfpsSideLottie;
+ private boolean mHaveShownUdfpsLeftEdgeLottie;
+ private boolean mHaveShownUdfpsRightEdgeLottie;
private boolean mShouldShowLottie;
private OrientationEventListener mOrientationEventListener;
@@ -372,12 +375,31 @@
}
break;
- case STAGE_EDGES:
+ case STAGE_LEFT_EDGE:
setHeaderText(R.string.security_settings_udfps_enroll_edge_title);
- if (!mHaveShownUdfpsSideLottie && mIllustrationLottie != null) {
- mHaveShownUdfpsSideLottie = true;
+ if (!mHaveShownUdfpsLeftEdgeLottie && mIllustrationLottie != null) {
+ mHaveShownUdfpsLeftEdgeLottie = true;
setDescriptionText("");
- mIllustrationLottie.setAnimation(R.raw.udfps_edge_hint_lottie);
+ mIllustrationLottie.setAnimation(R.raw.udfps_left_edge_hint_lottie);
+ mIllustrationLottie.setVisibility(View.VISIBLE);
+ mIllustrationLottie.playAnimation();
+ mIllustrationLottie.setContentDescription(
+ getString(R.string.security_settings_udfps_side_fingerprint_help));
+ } else if (mIllustrationLottie == null) {
+ if (isStageHalfCompleted()) {
+ setDescriptionText(
+ R.string.security_settings_fingerprint_enroll_repeat_message);
+ } else {
+ setDescriptionText(R.string.security_settings_udfps_enroll_edge_message);
+ }
+ }
+ break;
+ case STAGE_RIGHT_EDGE:
+ setHeaderText(R.string.security_settings_udfps_enroll_edge_title);
+ if (!mHaveShownUdfpsRightEdgeLottie && mIllustrationLottie != null) {
+ mHaveShownUdfpsRightEdgeLottie = true;
+ setDescriptionText("");
+ mIllustrationLottie.setAnimation(R.raw.udfps_right_edge_hint_lottie);
mIllustrationLottie.setVisibility(View.VISIBLE);
mIllustrationLottie.playAnimation();
mIllustrationLottie.setContentDescription(
@@ -422,8 +444,10 @@
return STAGE_GUIDED;
} else if (progressSteps < getStageThresholdSteps(2)) {
return STAGE_FINGERTIP;
+ } else if (progressSteps < getStageThresholdSteps(3)) {
+ return STAGE_LEFT_EDGE;
} else {
- return STAGE_EDGES;
+ return STAGE_RIGHT_EDGE;
}
}
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
index 9f5e78e..9c7aa58 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
@@ -16,6 +16,7 @@
package com.android.settings.bluetooth;
+import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
@@ -53,7 +54,10 @@
@Override
public boolean isAvailable() {
- return !Utils.isAdvancedDetailsHeader(mCachedDevice.getDevice());
+ boolean hasLeAudio = mCachedDevice.getConnectableProfiles()
+ .stream()
+ .anyMatch(profile -> profile.getProfileId() == BluetoothProfile.LE_AUDIO);
+ return !Utils.isAdvancedDetailsHeader(mCachedDevice.getDevice()) && !hasLeAudio;
}
@Override
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
index aacf41f..b57ea92 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
@@ -16,10 +16,12 @@
package com.android.settings.bluetooth;
+import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.text.TextUtils;
+import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
@@ -31,6 +33,7 @@
import com.android.settings.R;
import com.android.settingslib.bluetooth.A2dpProfile;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LeAudioProfile;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
@@ -39,7 +42,10 @@
import com.android.settingslib.bluetooth.PbapServerProfile;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* This class adds switches for toggling the individual profiles that a Bluetooth device
@@ -48,8 +54,11 @@
public class BluetoothDetailsProfilesController extends BluetoothDetailsController
implements Preference.OnPreferenceClickListener,
LocalBluetoothProfileManager.ServiceListener {
+ private static final String TAG = "BtDetailsProfilesCtrl";
+
private static final String KEY_PROFILES_GROUP = "bluetooth_profiles";
private static final String KEY_BOTTOM_PREFERENCE = "bottom_preference";
+ private static final String HEADSET_CLIENT = "HEADSET_CLIENT";
private static final int ORDINAL = 99;
@VisibleForTesting
@@ -58,6 +67,9 @@
private LocalBluetoothManager mManager;
private LocalBluetoothProfileManager mProfileManager;
private CachedBluetoothDevice mCachedDevice;
+ private List<CachedBluetoothDevice> mAllOfCachedDevices;
+ private Map<String, List<CachedBluetoothDevice>> mProfileDeviceMap =
+ new HashMap<String, List<CachedBluetoothDevice>>();
@VisibleForTesting
PreferenceCategory mProfilesContainer;
@@ -68,6 +80,7 @@
mManager = manager;
mProfileManager = mManager.getProfileManager();
mCachedDevice = device;
+ mAllOfCachedDevices = getAllOfCachedBluetoothDevices();
lifecycle.addObserver(this);
}
@@ -100,11 +113,66 @@
/**
* Refreshes the state for an existing SwitchPreference for a profile.
+ * If the LeAudio profile is enabled on the LeAudio devices, then the SwitchPreferences of
+ * A2dp profile and Hfp profile are graied out.
*/
private void refreshProfilePreference(SwitchPreference profilePref,
LocalBluetoothProfile profile) {
BluetoothDevice device = mCachedDevice.getDevice();
- profilePref.setEnabled(!mCachedDevice.isBusy());
+ boolean isLeAudioEnabled = false;
+ if (profile instanceof A2dpProfile || HEADSET_CLIENT.equals(profile.toString())) {
+ LocalBluetoothProfile leAudio = mProfileManager.getLeAudioProfile();
+ if (leAudio != null) {
+ List<CachedBluetoothDevice> leAudioDeviceList = mProfileDeviceMap.get(
+ leAudio.toString());
+ if (leAudioDeviceList != null
+ && leAudioDeviceList.stream()
+ .anyMatch(item -> leAudio.isEnabled(item.getDevice()))) {
+ isLeAudioEnabled = true;
+ }
+ }
+ if (isLeAudioEnabled) {
+ // If the LeAudio profile is enabled on the LeAudio devices, then the
+ // SwitchPreferences of A2dp profile and Hfp profile are graied out.
+ profilePref.setEnabled(false);
+ } else {
+ List<CachedBluetoothDevice> deviceList = mProfileDeviceMap.get(
+ profile.toString());
+ boolean isBusy = deviceList != null
+ && deviceList.stream().anyMatch(item -> item.isBusy());
+ profilePref.setEnabled(!isBusy);
+ }
+ } else if (profile instanceof LeAudioProfile) {
+ List<CachedBluetoothDevice> leAudioDeviceList = mProfileDeviceMap.get(
+ profile.toString());
+ boolean isLeAudioProfileEnable =
+ leAudioDeviceList != null && leAudioDeviceList.stream().anyMatch(
+ item -> profile.isEnabled(item.getDevice()));
+ boolean isBusy = leAudioDeviceList != null
+ && leAudioDeviceList.stream().anyMatch(item -> item.isBusy());
+ if (isLeAudioProfileEnable && !isBusy) {
+ LocalBluetoothProfile a2dp = mProfileManager.getA2dpProfile();
+ LocalBluetoothProfile hfp = mProfileManager.getHfpClientProfile();
+ // If the LeAudio profile is enabled on the LeAudio devices, then the
+ // SwitchPreferences of A2dp profile and Hfp profile are graied out.
+ if (a2dp != null) {
+ SwitchPreference pref = mProfilesContainer.findPreference(a2dp.toString());
+ if (pref != null) {
+ pref.setEnabled(false);
+ }
+ }
+ if (hfp != null) {
+ SwitchPreference pref = mProfilesContainer.findPreference(hfp.toString());
+ if (pref != null) {
+ pref.setEnabled(false);
+ }
+ }
+ }
+ profilePref.setEnabled(!isBusy);
+ } else {
+ profilePref.setEnabled(!mCachedDevice.isBusy());
+ }
+
if (profile instanceof MapProfile) {
profilePref.setChecked(device.getMessageAccessPermission()
== BluetoothDevice.ACCESS_ALLOWED);
@@ -127,7 +195,7 @@
highQualityPref.setVisible(true);
highQualityPref.setTitle(a2dp.getHighQualityAudioOptionLabel(device));
highQualityPref.setChecked(a2dp.isHighQualityAudioEnabled(device));
- highQualityPref.setEnabled(!mCachedDevice.isBusy());
+ highQualityPref.setEnabled(!mCachedDevice.isBusy() && !isLeAudioEnabled);
} else {
highQualityPref.setVisible(false);
}
@@ -148,6 +216,12 @@
if (profile instanceof MapProfile) {
bluetoothDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_ALLOWED);
}
+
+ if (profile instanceof LeAudioProfile) {
+ enableLeAudioProfile(profile);
+ return;
+ }
+
profile.setEnabled(bluetoothDevice, true);
}
@@ -155,8 +229,14 @@
* Helper method to disable a profile for a device
*/
private void disableProfile(LocalBluetoothProfile profile) {
+ if (profile instanceof LeAudioProfile) {
+ disableLeAudioProfile(profile);
+ return;
+ }
+
final BluetoothDevice bluetoothDevice = mCachedDevice.getDevice();
profile.setEnabled(bluetoothDevice, false);
+
if (profile instanceof MapProfile) {
bluetoothDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_REJECTED);
} else if (profile instanceof PbapServerProfile) {
@@ -190,14 +270,33 @@
return true;
}
-
/**
* Helper to get the list of connectable and special profiles.
*/
private List<LocalBluetoothProfile> getProfiles() {
- List<LocalBluetoothProfile> result = mCachedDevice.getConnectableProfiles();
- final BluetoothDevice device = mCachedDevice.getDevice();
+ List<LocalBluetoothProfile> result = new ArrayList<LocalBluetoothProfile>();
+ mProfileDeviceMap.clear();
+ if (mAllOfCachedDevices == null || mAllOfCachedDevices.isEmpty()) {
+ return result;
+ }
+ for (CachedBluetoothDevice cachedItem : mAllOfCachedDevices) {
+ List<LocalBluetoothProfile> tmpResult = cachedItem.getConnectableProfiles();
+ for (LocalBluetoothProfile profile : tmpResult) {
+ if (mProfileDeviceMap.containsKey(profile.toString())) {
+ mProfileDeviceMap.get(profile.toString()).add(cachedItem);
+ Log.d(TAG, "getProfiles: " + profile.toString() + " add device "
+ + cachedItem.getDevice().getAnonymizedAddress());
+ } else {
+ List<CachedBluetoothDevice> tmpCachedDeviceList =
+ new ArrayList<CachedBluetoothDevice>();
+ tmpCachedDeviceList.add(cachedItem);
+ mProfileDeviceMap.put(profile.toString(), tmpCachedDeviceList);
+ result.add(profile);
+ }
+ }
+ }
+ final BluetoothDevice device = mCachedDevice.getDevice();
final int pbapPermission = device.getPhonebookAccessPermission();
// Only provide PBAP cabability if the client device has requested PBAP.
if (pbapPermission != BluetoothDevice.ACCESS_UNKNOWN) {
@@ -210,10 +309,93 @@
if (mapPermission != BluetoothDevice.ACCESS_UNKNOWN) {
result.add(mapProfile);
}
-
+ Log.d(TAG, "getProfiles:result:" + result);
return result;
}
+ private List<CachedBluetoothDevice> getAllOfCachedBluetoothDevices() {
+ List<CachedBluetoothDevice> cachedBluetoothDevices = new ArrayList<>();
+ if (mCachedDevice == null) {
+ return cachedBluetoothDevices;
+ }
+ cachedBluetoothDevices.add(mCachedDevice);
+ if (mCachedDevice.getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
+ for (CachedBluetoothDevice member : mCachedDevice.getMemberDevice()) {
+ cachedBluetoothDevices.add(member);
+ }
+ }
+ return cachedBluetoothDevices;
+ }
+
+ /**
+ * When user disable the Le Audio profile, the system needs to do two things.
+ * 1) Disable the Le Audio profile for each of the Le Audio devices.
+ * 2) Enable the A2dp profile and Hfp profile for the associated device. The system can't
+ * enable the A2dp profile and Hfp profile if the Le Audio profile is enabled.
+ *
+ * @param profile the LeAudio profile
+ */
+ private void disableLeAudioProfile(LocalBluetoothProfile profile) {
+ if (profile == null || mProfileDeviceMap.get(profile.toString()) == null) {
+ Log.e(TAG, "There is no the LE profile or no device in mProfileDeviceMap. Do nothing.");
+ return;
+ }
+ for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) {
+ profile.setEnabled(leAudioDevice.getDevice(), false);
+ }
+
+ LocalBluetoothProfile a2dp = mProfileManager.getA2dpProfile();
+ LocalBluetoothProfile hfp = mProfileManager.getHfpClientProfile();
+ if (a2dp != null && mProfileDeviceMap.get(a2dp.toString()) != null) {
+ for (CachedBluetoothDevice a2dpDevice : mProfileDeviceMap.get(a2dp.toString())) {
+ if (!a2dp.isEnabled(a2dpDevice.getDevice())) {
+ a2dp.setEnabled(a2dpDevice.getDevice(), true);
+ }
+ }
+ }
+ if (hfp != null && mProfileDeviceMap.get(hfp.toString()) != null) {
+ for (CachedBluetoothDevice hfpDevice : mProfileDeviceMap.get(hfp.toString())) {
+ if (!hfp.isEnabled(hfpDevice.getDevice())) {
+ hfp.setEnabled(hfpDevice.getDevice(), true);
+ }
+ }
+ }
+ }
+
+ /**
+ * When user enable the Le Audio profile, the system needs to do two things.
+ * 1) Disable the A2dp profile and Hfp profile for the associated device. The system can't
+ * enable the Le Audio if the A2dp profile and Hfp profile are enabled.
+ * 2) Enable the Le Audio profile for each of the Le Audio devices.
+ *
+ * @param profile the LeAudio profile
+ */
+ private void enableLeAudioProfile(LocalBluetoothProfile profile) {
+ if (profile == null || mProfileDeviceMap.get(profile.toString()) == null) {
+ Log.e(TAG, "There is no the LE profile or no device in mProfileDeviceMap. Do nothing.");
+ return;
+ }
+ LocalBluetoothProfile a2dp = mProfileManager.getA2dpProfile();
+ LocalBluetoothProfile hfp = mProfileManager.getHfpClientProfile();
+ if (a2dp != null && mProfileDeviceMap.get(a2dp.toString()) != null) {
+ for (CachedBluetoothDevice a2dpDevice : mProfileDeviceMap.get(a2dp.toString())) {
+ if (a2dp.isEnabled(a2dpDevice.getDevice())) {
+ a2dp.setEnabled(a2dpDevice.getDevice(), false);
+ }
+ }
+ }
+ if (hfp != null && mProfileDeviceMap.get(hfp.toString()) != null) {
+ for (CachedBluetoothDevice hfpDevice : mProfileDeviceMap.get(hfp.toString())) {
+ if (hfp.isEnabled(hfpDevice.getDevice())) {
+ hfp.setEnabled(hfpDevice.getDevice(), false);
+ }
+ }
+ }
+ for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) {
+ profile.setEnabled(leAudioDevice.getDevice(), true);
+ }
+ }
+
/**
* This is a helper method to be called after adding a Preference for a profile. If that
* profile happened to be A2dp and the device supports high quality audio, it will add a
@@ -243,17 +425,34 @@
@Override
public void onPause() {
- super.onPause();
+ for (CachedBluetoothDevice item : mAllOfCachedDevices) {
+ item.unregisterCallback(this);
+ }
mProfileManager.removeServiceListener(this);
}
@Override
public void onResume() {
- super.onResume();
+ for (CachedBluetoothDevice item : mAllOfCachedDevices) {
+ item.registerCallback(this);
+ }
mProfileManager.addServiceListener(this);
}
@Override
+ public void onDeviceAttributesChanged() {
+ for (CachedBluetoothDevice item : mAllOfCachedDevices) {
+ item.unregisterCallback(this);
+ }
+ mAllOfCachedDevices = getAllOfCachedBluetoothDevices();
+ for (CachedBluetoothDevice item : mAllOfCachedDevices) {
+ item.registerCallback(this);
+ }
+
+ super.onDeviceAttributesChanged();
+ }
+
+ @Override
public void onServiceConnected() {
refresh();
}
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java b/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java
index 6532482..6d443ee 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java
@@ -117,6 +117,7 @@
return;
}
use(AdvancedBluetoothDetailsHeaderController.class).init(mCachedDevice);
+ use(LeAudioBluetoothDetailsHeaderController.class).init(mCachedDevice, mManager);
final BluetoothFeatureProvider featureProvider = FeatureFactory.getFactory(
context).getBluetoothFeatureProvider(context);
diff --git a/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java
new file mode 100644
index 0000000..06cee85
--- /dev/null
+++ b/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java
@@ -0,0 +1,323 @@
+/*
+ * 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 android.bluetooth.BluetoothCsipSetCoordinator;
+import android.bluetooth.BluetoothLeAudio;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.util.Pair;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.fuelgauge.BatteryMeterView;
+import com.android.settingslib.bluetooth.BluetoothUtils;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LeAudioProfile;
+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.OnDestroy;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+import com.android.settingslib.widget.LayoutPreference;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class adds a header with device name and status (connected/disconnected, etc.).
+ */
+public class LeAudioBluetoothDetailsHeaderController extends BasePreferenceController implements
+ LifecycleObserver, OnStart, OnStop, OnDestroy, CachedBluetoothDevice.Callback {
+ private static final String TAG = "LeAudioBtHeaderCtrl";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ @VisibleForTesting
+ static final int LEFT_DEVICE_ID =
+ BluetoothLeAudio.AUDIO_LOCATION_FRONT_LEFT
+ | BluetoothLeAudio.AUDIO_LOCATION_BACK_LEFT
+ | BluetoothLeAudio.AUDIO_LOCATION_FRONT_LEFT_OF_CENTER
+ | BluetoothLeAudio.AUDIO_LOCATION_SIDE_LEFT
+ | BluetoothLeAudio.AUDIO_LOCATION_TOP_FRONT_LEFT
+ | BluetoothLeAudio.AUDIO_LOCATION_TOP_BACK_LEFT
+ | BluetoothLeAudio.AUDIO_LOCATION_TOP_SIDE_LEFT
+ | BluetoothLeAudio.AUDIO_LOCATION_BOTTOM_FRONT_LEFT
+ | BluetoothLeAudio.AUDIO_LOCATION_FRONT_LEFT_WIDE
+ | BluetoothLeAudio.AUDIO_LOCATION_LEFT_SURROUND;
+
+ @VisibleForTesting
+ static final int RIGHT_DEVICE_ID =
+ BluetoothLeAudio.AUDIO_LOCATION_FRONT_RIGHT
+ | BluetoothLeAudio.AUDIO_LOCATION_BACK_RIGHT
+ | BluetoothLeAudio.AUDIO_LOCATION_FRONT_RIGHT_OF_CENTER
+ | BluetoothLeAudio.AUDIO_LOCATION_SIDE_RIGHT
+ | BluetoothLeAudio.AUDIO_LOCATION_TOP_FRONT_RIGHT
+ | BluetoothLeAudio.AUDIO_LOCATION_TOP_BACK_RIGHT
+ | BluetoothLeAudio.AUDIO_LOCATION_TOP_SIDE_RIGHT
+ | BluetoothLeAudio.AUDIO_LOCATION_BOTTOM_FRONT_RIGHT
+ | BluetoothLeAudio.AUDIO_LOCATION_FRONT_RIGHT_WIDE
+ | BluetoothLeAudio.AUDIO_LOCATION_RIGHT_SURROUND;
+
+ @VisibleForTesting
+ static final int INVALID_RESOURCE_ID = -1;
+
+ @VisibleForTesting
+ LayoutPreference mLayoutPreference;
+ private CachedBluetoothDevice mCachedDevice;
+ @VisibleForTesting
+ Handler mHandler = new Handler(Looper.getMainLooper());
+ @VisibleForTesting
+ boolean mIsRegisterCallback = false;
+
+ private LocalBluetoothProfileManager mProfileManager;
+
+ public LeAudioBluetoothDetailsHeaderController(Context context, String prefKey) {
+ super(context, prefKey);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ if (mCachedDevice == null || mProfileManager == null) {
+ return CONDITIONALLY_UNAVAILABLE;
+ }
+ boolean hasLeAudio = mCachedDevice.getConnectableProfiles()
+ .stream()
+ .anyMatch(profile -> profile.getProfileId() == BluetoothProfile.LE_AUDIO);
+
+ return !Utils.isAdvancedDetailsHeader(mCachedDevice.getDevice()) && hasLeAudio
+ ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mLayoutPreference = screen.findPreference(getPreferenceKey());
+ mLayoutPreference.setVisible(isAvailable());
+ }
+
+ @Override
+ public void onStart() {
+ if (!isAvailable()) {
+ return;
+ }
+ mIsRegisterCallback = true;
+ mCachedDevice.registerCallback(this);
+ refresh();
+ }
+
+ @Override
+ public void onStop() {
+ if (!mIsRegisterCallback) {
+ return;
+ }
+ mCachedDevice.unregisterCallback(this);
+ mIsRegisterCallback = false;
+ }
+
+ @Override
+ public void onDestroy() {
+ }
+
+ public void init(CachedBluetoothDevice cachedBluetoothDevice,
+ LocalBluetoothManager bluetoothManager) {
+ mCachedDevice = cachedBluetoothDevice;
+ mProfileManager = bluetoothManager.getProfileManager();
+ }
+
+ @VisibleForTesting
+ void refresh() {
+ if (mLayoutPreference == null || mCachedDevice == null) {
+ return;
+ }
+ final ImageView imageView = mLayoutPreference.findViewById(R.id.entity_header_icon);
+ if (imageView != null) {
+ final Pair<Drawable, String> pair =
+ BluetoothUtils.getBtRainbowDrawableWithDescription(mContext, mCachedDevice);
+ imageView.setImageDrawable(pair.first);
+ imageView.setContentDescription(pair.second);
+ }
+
+ final TextView title = mLayoutPreference.findViewById(R.id.entity_header_title);
+ if (title != null) {
+ title.setText(mCachedDevice.getName());
+ }
+ final TextView summary = mLayoutPreference.findViewById(R.id.entity_header_summary);
+ if (summary != null) {
+ summary.setText(mCachedDevice.getConnectionSummary(true /* shortSummary */));
+ }
+
+ if (!mCachedDevice.isConnected() || mCachedDevice.isBusy()) {
+ hideAllOfBatteryLayouts();
+ return;
+ }
+
+ updateBatteryLayout();
+ }
+
+ @VisibleForTesting
+ Drawable createBtBatteryIcon(Context context, int level) {
+ final BatteryMeterView.BatteryMeterDrawable drawable =
+ new BatteryMeterView.BatteryMeterDrawable(context,
+ context.getColor(R.color.meter_background_color),
+ context.getResources().getDimensionPixelSize(
+ R.dimen.advanced_bluetooth_battery_meter_width),
+ context.getResources().getDimensionPixelSize(
+ R.dimen.advanced_bluetooth_battery_meter_height));
+ drawable.setBatteryLevel(level);
+ drawable.setColorFilter(new PorterDuffColorFilter(
+ com.android.settings.Utils.getColorAttrDefaultColor(context,
+ android.R.attr.colorControlNormal),
+ PorterDuff.Mode.SRC));
+ return drawable;
+ }
+
+ private int getBatteryTitleResource(int deviceId) {
+ if (deviceId == LEFT_DEVICE_ID) {
+ return R.id.bt_battery_left_title;
+ }
+ if (deviceId == RIGHT_DEVICE_ID) {
+ return R.id.bt_battery_right_title;
+ }
+ Log.d(TAG, "No resource id. The deviceId is " + deviceId);
+ return INVALID_RESOURCE_ID;
+ }
+
+ private int getBatterySummaryResource(int deviceId) {
+ if (deviceId == LEFT_DEVICE_ID) {
+ return R.id.bt_battery_left_summary;
+ }
+ if (deviceId == RIGHT_DEVICE_ID) {
+ return R.id.bt_battery_right_summary;
+ }
+ Log.d(TAG, "No resource id. The deviceId is " + deviceId);
+ return INVALID_RESOURCE_ID;
+ }
+
+ private void hideAllOfBatteryLayouts() {
+ // hide the case
+ updateBatteryLayout(R.id.bt_battery_case_title, R.id.bt_battery_case_summary,
+ BluetoothUtils.META_INT_ERROR);
+ // hide the left
+ updateBatteryLayout(R.id.bt_battery_left_title, R.id.bt_battery_left_summary,
+ BluetoothUtils.META_INT_ERROR);
+ // hide the right
+ updateBatteryLayout(R.id.bt_battery_right_title, R.id.bt_battery_right_summary,
+ BluetoothUtils.META_INT_ERROR);
+ }
+
+ private List<CachedBluetoothDevice> getAllOfLeAudioDevices() {
+ if (mCachedDevice == null) {
+ return null;
+ }
+ List<CachedBluetoothDevice> leAudioDevices = new ArrayList<>();
+ leAudioDevices.add(mCachedDevice);
+ if (mCachedDevice.getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
+ for (CachedBluetoothDevice member : mCachedDevice.getMemberDevice()) {
+ leAudioDevices.add(member);
+ }
+ }
+ return leAudioDevices;
+ }
+
+ private void updateBatteryLayout() {
+ // Init the battery layouts.
+ hideAllOfBatteryLayouts();
+ final List<CachedBluetoothDevice> leAudioDevices = getAllOfLeAudioDevices();
+ LeAudioProfile leAudioProfile = mProfileManager.getLeAudioProfile();
+ if (leAudioDevices == null || leAudioDevices.isEmpty()) {
+ Log.e(TAG, "There is no LeAudioProfile.");
+ return;
+ }
+
+ if (!leAudioProfile.isEnabled(mCachedDevice.getDevice())) {
+ Log.d(TAG, "Show the legacy battery style if the LeAudio is not enabled.");
+ final TextView summary = mLayoutPreference.findViewById(R.id.entity_header_summary);
+ if (summary != null) {
+ summary.setText(mCachedDevice.getConnectionSummary());
+ }
+ return;
+ }
+
+ for (CachedBluetoothDevice cachedDevice : leAudioDevices) {
+ int deviceId = leAudioProfile.getAudioLocation(cachedDevice.getDevice());
+ Log.d(TAG, "LeAudioDevices:" + cachedDevice.getDevice().getAnonymizedAddress()
+ + ", deviceId:" + deviceId);
+
+ if (deviceId == BluetoothLeAudio.AUDIO_LOCATION_INVALID) {
+ Log.d(TAG, "The device does not support the AUDIO_LOCATION.");
+ return;
+ }
+ boolean isLeft = (deviceId & LEFT_DEVICE_ID) != 0;
+ boolean isRight = (deviceId & LEFT_DEVICE_ID) != 0;
+ boolean isLeftRight = isLeft && isRight;
+ // The LE device updates the BatteryLayout
+ if (isLeftRight) {
+ Log.d(TAG, "The device id is left+right. Do nothing.");
+ } else if (isLeft) {
+ updateBatteryLayout(getBatteryTitleResource(LEFT_DEVICE_ID),
+ getBatterySummaryResource(LEFT_DEVICE_ID), cachedDevice.getBatteryLevel());
+ } else if (isRight) {
+ updateBatteryLayout(getBatteryTitleResource(RIGHT_DEVICE_ID),
+ getBatterySummaryResource(RIGHT_DEVICE_ID), cachedDevice.getBatteryLevel());
+ } else {
+ Log.d(TAG, "The device id is other Audio Location. Do nothing.");
+ }
+ }
+ }
+
+ private void updateBatteryLayout(int titleResId, int summaryResId, int batteryLevel) {
+ final TextView batteryTitleView = mLayoutPreference.findViewById(titleResId);
+ final TextView batterySummaryView = mLayoutPreference.findViewById(summaryResId);
+ if (batteryTitleView == null || batterySummaryView == null) {
+ Log.e(TAG, "updateBatteryLayout: No TextView");
+ return;
+ }
+ if (batteryLevel != BluetoothUtils.META_INT_ERROR) {
+ batteryTitleView.setVisibility(View.VISIBLE);
+ batterySummaryView.setVisibility(View.VISIBLE);
+ batterySummaryView.setText(
+ com.android.settings.Utils.formatPercentage(batteryLevel));
+ batterySummaryView.setCompoundDrawablesRelativeWithIntrinsicBounds(
+ createBtBatteryIcon(mContext, batteryLevel), /* top */ null,
+ /* end */ null, /* bottom */ null);
+ } else {
+ Log.d(TAG, "updateBatteryLayout: Hide it if it doesn't have battery information.");
+ batteryTitleView.setVisibility(View.GONE);
+ batterySummaryView.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public void onDeviceAttributesChanged() {
+ if (mCachedDevice != null) {
+ refresh();
+ }
+ }
+}
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 636404e..085a372 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -505,7 +505,6 @@
controllers.add(new HdcpCheckingPreferenceController(context));
controllers.add(new BluetoothSnoopLogPreferenceController(context));
controllers.add(new OemUnlockPreferenceController(context, activity, fragment));
- controllers.add(new FileEncryptionPreferenceController(context));
controllers.add(new PictureColorModePreferenceController(context, lifecycle));
controllers.add(new WebViewAppPreferenceController(context));
controllers.add(new CoolColorTemperaturePreferenceController(context));
diff --git a/src/com/android/settings/development/FileEncryptionPreferenceController.java b/src/com/android/settings/development/FileEncryptionPreferenceController.java
deleted file mode 100644
index 82a58ba..0000000
--- a/src/com/android/settings/development/FileEncryptionPreferenceController.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import android.content.Context;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.storage.IStorageManager;
-import android.text.TextUtils;
-import android.sysprop.CryptoProperties;
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-
-import com.android.settings.R;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.development.DeveloperOptionsPreferenceController;
-
-public class FileEncryptionPreferenceController extends DeveloperOptionsPreferenceController
- implements PreferenceControllerMixin {
-
- private static final String KEY_CONVERT_FBE = "convert_to_file_encryption";
- private static final String KEY_STORAGE_MANAGER = "mount";
-
- private final IStorageManager mStorageManager;
-
- public FileEncryptionPreferenceController(Context context) {
- super(context);
-
- mStorageManager = getStorageManager();
- }
-
- @Override
- public boolean isAvailable() {
- if (mStorageManager == null) {
- return false;
- }
-
- try {
- return mStorageManager.isConvertibleToFBE();
- } catch (RemoteException e) {
- return false;
- }
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY_CONVERT_FBE;
- }
-
- @Override
- public void updateState(Preference preference) {
- if (CryptoProperties.type().orElse(CryptoProperties.type_values.NONE) !=
- CryptoProperties.type_values.FILE) {
- return;
- }
-
- mPreference.setEnabled(false);
- mPreference.setSummary(
- mContext.getResources().getString(R.string.convert_to_file_encryption_done));
- }
-
- private IStorageManager getStorageManager() {
- try {
- return IStorageManager.Stub.asInterface(
- ServiceManager.getService(KEY_STORAGE_MANAGER));
- } catch (VerifyError e) {
- // Used for tests since Robolectric cannot initialize this class.
- return null;
- }
- }
-}
\ No newline at end of file
diff --git a/src/com/android/settings/deviceinfo/StorageItemPreference.java b/src/com/android/settings/deviceinfo/StorageItemPreference.java
index d3549d4..91102a0 100644
--- a/src/com/android/settings/deviceinfo/StorageItemPreference.java
+++ b/src/com/android/settings/deviceinfo/StorageItemPreference.java
@@ -16,6 +16,8 @@
package com.android.settings.deviceinfo;
+import android.animation.TypeEvaluator;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ProgressBar;
@@ -30,6 +32,7 @@
public int userHandle;
private static final int UNINITIALIZED = -1;
+ private static final int ANIMATE_DURATION_IN_MILLIS = 1000;
private ProgressBar mProgressBar;
private static final int PROGRESS_MAX = 100;
@@ -46,15 +49,33 @@
}
public void setStorageSize(long size, long total) {
- mStorageSize = size;
- setSummary(StorageUtils.getStorageSizeLabel(getContext(), size));
+ setStorageSize(size, total, false /* animate */);
+ }
- if (total == 0) {
- mProgressPercent = 0;
+ /**
+ * Set the storage size info with/without animation
+ */
+ public void setStorageSize(long size, long total, boolean animate) {
+ if (animate) {
+ TypeEvaluator<Long> longEvaluator =
+ (fraction, startValue, endValue) -> {
+ // Directly returns end value if fraction is 1.0 and the end value is 0.
+ if (fraction >= 1.0f && endValue == 0) {
+ return endValue;
+ }
+ return startValue + (long) (fraction * (endValue - startValue));
+ };
+ ValueAnimator valueAnimator = ValueAnimator.ofObject(longEvaluator, mStorageSize, size);
+ valueAnimator.setDuration(ANIMATE_DURATION_IN_MILLIS);
+ valueAnimator.addUpdateListener(
+ animation -> {
+ updateProgressBarAndSizeInfo((long) animation.getAnimatedValue(), total);
+ });
+ valueAnimator.start();
} else {
- mProgressPercent = (int)(size * PROGRESS_MAX / total);
+ updateProgressBarAndSizeInfo(size, total);
}
- updateProgressBar();
+ mStorageSize = size;
}
public long getStorageSize() {
@@ -62,11 +83,18 @@
}
protected void updateProgressBar() {
- if (mProgressBar == null || mProgressPercent == UNINITIALIZED)
+ if (mProgressBar == null || mProgressPercent == UNINITIALIZED) {
return;
+ }
mProgressBar.setMax(PROGRESS_MAX);
- mProgressBar.setProgress(mProgressPercent, true /* animate */);
+ mProgressBar.setProgress(mProgressPercent);
+ }
+
+ private void updateProgressBarAndSizeInfo(long size, long total) {
+ setSummary(StorageUtils.getStorageSizeLabel(getContext(), size));
+ mProgressPercent = total == 0 ? 0 : (int) (size * PROGRESS_MAX / total);
+ updateProgressBar();
}
@Override
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
index 9813439..7e27414 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
@@ -378,18 +378,22 @@
*/
public void onLoadFinished(@Nullable SparseArray<StorageAsyncLoader.StorageResult> result,
int userId) {
+ // Enable animation when the storage size info is from StorageAsyncLoader whereas disable
+ // animation when the cached storage size info is used instead.
+ boolean animate = result != null && mIsPreferenceOrderedBySize;
// Calculate the size info for each category
StorageCacheHelper.StorageCache storageCache = getSizeInfo(result, userId);
// Set size info to each preference
- mImagesPreference.setStorageSize(storageCache.imagesSize, mTotalSize);
- mVideosPreference.setStorageSize(storageCache.videosSize, mTotalSize);
- mAudioPreference.setStorageSize(storageCache.audioSize, mTotalSize);
- mAppsPreference.setStorageSize(storageCache.allAppsExceptGamesSize, mTotalSize);
- mGamesPreference.setStorageSize(storageCache.gamesSize, mTotalSize);
- mDocumentsAndOtherPreference.setStorageSize(storageCache.documentsAndOtherSize, mTotalSize);
- mTrashPreference.setStorageSize(storageCache.trashSize, mTotalSize);
+ mImagesPreference.setStorageSize(storageCache.imagesSize, mTotalSize, animate);
+ mVideosPreference.setStorageSize(storageCache.videosSize, mTotalSize, animate);
+ mAudioPreference.setStorageSize(storageCache.audioSize, mTotalSize, animate);
+ mAppsPreference.setStorageSize(storageCache.allAppsExceptGamesSize, mTotalSize, animate);
+ mGamesPreference.setStorageSize(storageCache.gamesSize, mTotalSize, animate);
+ mDocumentsAndOtherPreference.setStorageSize(storageCache.documentsAndOtherSize, mTotalSize,
+ animate);
+ mTrashPreference.setStorageSize(storageCache.trashSize, mTotalSize, animate);
if (mSystemPreference != null) {
- mSystemPreference.setStorageSize(storageCache.systemSize, mTotalSize);
+ mSystemPreference.setStorageSize(storageCache.systemSize, mTotalSize, animate);
}
// Cache the size info
if (result != null) {
@@ -519,7 +523,7 @@
if (mTrashPreference == null) {
return;
}
- mTrashPreference.setStorageSize(0, mTotalSize);
+ mTrashPreference.setStorageSize(0, mTotalSize, true /* animate */);
updatePrivateStorageCategoryPreferencesOrder();
}
diff --git a/src/com/android/settings/fuelgauge/BatteryDiffEntry.java b/src/com/android/settings/fuelgauge/BatteryDiffEntry.java
index e524e98..ca29cfe 100644
--- a/src/com/android/settings/fuelgauge/BatteryDiffEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryDiffEntry.java
@@ -25,6 +25,7 @@
import androidx.annotation.VisibleForTesting;
+import com.android.settings.R;
import com.android.settingslib.utils.StringUtil;
import java.util.Comparator;
@@ -52,6 +53,7 @@
public double mConsumePower;
// A BatteryHistEntry corresponding to this diff usage data.
public final BatteryHistEntry mBatteryHistEntry;
+
private double mTotalConsumePower;
private double mPercentOfTotal;
@@ -151,8 +153,13 @@
case ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY:
return true;
case ConvertUtils.CONSUMER_TYPE_UID_BATTERY:
- return isSystemUid((int) mBatteryHistEntry.mUid)
- || mBatteryHistEntry.mIsHidden;
+ if (mBatteryHistEntry.mIsHidden) {
+ return true;
+ }
+ final boolean combineSystemComponents =
+ mContext.getResources().getBoolean(
+ R.bool.config_battery_combine_system_components);
+ return combineSystemComponents && isSystemUid((int) mBatteryHistEntry.mUid);
}
return false;
}
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index 73c473a..3ed305e 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -182,6 +182,8 @@
showSuggestionFragment(scrollNeeded);
if (FeatureFlagUtils.isEnabled(this, FeatureFlags.CONTEXTUAL_HOME)) {
showFragment(() -> new ContextualCardsFragment(), R.id.contextual_cards_content);
+ ((FrameLayout) findViewById(R.id.main_content))
+ .getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
}
}
mMainFragment = showFragment(() -> {
@@ -191,9 +193,6 @@
return fragment;
}, R.id.main_content);
- ((FrameLayout) findViewById(R.id.main_content))
- .getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
-
// Launch the intent from deep link for large screen devices.
launchDeepLinkIntentToRight();
}
diff --git a/src/com/android/settings/homepage/TopLevelHighlightMixin.java b/src/com/android/settings/homepage/TopLevelHighlightMixin.java
index ebfe7f2..c473e87 100644
--- a/src/com/android/settings/homepage/TopLevelHighlightMixin.java
+++ b/src/com/android/settings/homepage/TopLevelHighlightMixin.java
@@ -23,7 +23,6 @@
import android.text.TextUtils;
import android.util.Log;
-import androidx.fragment.app.FragmentActivity;
import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView;
@@ -43,14 +42,17 @@
private String mHiddenKey;
private DialogInterface mDialog;
private HighlightableTopLevelPreferenceAdapter mTopLevelAdapter;
+ private boolean mActivityEmbedded;
- public TopLevelHighlightMixin() {
+ public TopLevelHighlightMixin(boolean activityEmbedded) {
+ mActivityEmbedded = activityEmbedded;
}
public TopLevelHighlightMixin(Parcel source) {
mCurrentKey = source.readString();
mPreviousKey = source.readString();
mHiddenKey = source.readString();
+ mActivityEmbedded = source.readBoolean();
}
@Override
@@ -58,6 +60,7 @@
dest.writeString(mCurrentKey);
dest.writeString(mPreviousKey);
dest.writeString(mHiddenKey);
+ dest.writeBoolean(mActivityEmbedded);
}
@Override
@@ -96,8 +99,16 @@
}
}
+ void setActivityEmbedded(boolean activityEmbedded) {
+ mActivityEmbedded = activityEmbedded;
+ }
+
+ boolean isActivityEmbedded() {
+ return mActivityEmbedded;
+ }
+
RecyclerView.Adapter onCreateAdapter(TopLevelSettings topLevelSettings,
- PreferenceScreen preferenceScreen) {
+ PreferenceScreen preferenceScreen, boolean scrollNeeded) {
if (TextUtils.isEmpty(mCurrentKey)) {
mCurrentKey = getHighlightPrefKeyFromArguments(topLevelSettings.getArguments());
}
@@ -105,7 +116,7 @@
Log.d(TAG, "onCreateAdapter, pref key: " + mCurrentKey);
mTopLevelAdapter = new HighlightableTopLevelPreferenceAdapter(
(SettingsHomepageActivity) topLevelSettings.getActivity(), preferenceScreen,
- topLevelSettings.getListView(), mCurrentKey);
+ topLevelSettings.getListView(), mCurrentKey, scrollNeeded);
return mTopLevelAdapter;
}
@@ -129,7 +140,7 @@
}
}
- void highlightPreferenceIfNeeded(FragmentActivity activity) {
+ void highlightPreferenceIfNeeded() {
if (mTopLevelAdapter != null) {
mTopLevelAdapter.requestHighlight();
}
diff --git a/src/com/android/settings/homepage/TopLevelSettings.java b/src/com/android/settings/homepage/TopLevelSettings.java
index 7d57834..334462b 100644
--- a/src/com/android/settings/homepage/TopLevelSettings.java
+++ b/src/com/android/settings/homepage/TopLevelSettings.java
@@ -58,6 +58,7 @@
private boolean mIsEmbeddingActivityEnabled;
private TopLevelHighlightMixin mHighlightMixin;
+ private boolean mScrollNeeded = true;
private boolean mFirstStarted = true;
public TopLevelSettings() {
@@ -133,11 +134,14 @@
return;
}
+ boolean activityEmbedded = SplitController.getInstance().isActivityEmbedded(getActivity());
if (icicle != null) {
mHighlightMixin = icicle.getParcelable(SAVED_HIGHLIGHT_MIXIN);
+ mScrollNeeded = !mHighlightMixin.isActivityEmbedded() && activityEmbedded;
+ mHighlightMixin.setActivityEmbedded(activityEmbedded);
}
if (mHighlightMixin == null) {
- mHighlightMixin = new TopLevelHighlightMixin();
+ mHighlightMixin = new TopLevelHighlightMixin(activityEmbedded);
}
}
@@ -201,7 +205,7 @@
@Override
public void highlightPreferenceIfNeeded() {
if (mHighlightMixin != null) {
- mHighlightMixin.highlightPreferenceIfNeeded(getActivity());
+ mHighlightMixin.highlightPreferenceIfNeeded();
}
}
@@ -243,7 +247,7 @@
if (!mIsEmbeddingActivityEnabled || !(getActivity() instanceof SettingsHomepageActivity)) {
return super.onCreateAdapter(preferenceScreen);
}
- return mHighlightMixin.onCreateAdapter(this, preferenceScreen);
+ return mHighlightMixin.onCreateAdapter(this, preferenceScreen, mScrollNeeded);
}
@Override
diff --git a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
index 8e3f21a..6246b91 100644
--- a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
+++ b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
@@ -251,6 +251,10 @@
}
void setPreferenceEntries() {
+ mTelephonyManager = mTelephonyManager.createForSubscriptionId(mSubId);
+ final PersistableBundle carrierConfig = mCarrierConfigCache.getConfigForSubId(mSubId);
+ final boolean display2gOptions = carrierConfig
+ .getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL);
clearAllEntries();
String[] entryValues;
int[] entryValuesInt;
@@ -266,7 +270,9 @@
add5gEntry(addNrToLteNetworkType(entryValuesInt[0]));
addLteEntry(entryValuesInt[0]);
add3gEntry(entryValuesInt[1]);
- add1xEntry(entryValuesInt[2]);
+ if (display2gOptions) {
+ add1xEntry(entryValuesInt[2]);
+ }
addGlobalEntry(entryValuesInt[3]);
break;
case ENABLED_NETWORKS_CDMA_NO_LTE_CHOICES:
@@ -278,7 +284,9 @@
"ENABLED_NETWORKS_CDMA_NO_LTE_CHOICES index error.");
}
add3gEntry(entryValuesInt[0]);
- add1xEntry(entryValuesInt[1]);
+ if (display2gOptions) {
+ add1xEntry(entryValuesInt[1]);
+ }
break;
case ENABLED_NETWORKS_CDMA_ONLY_LTE_CHOICES:
entryValues = getResourcesForSubId().getStringArray(
@@ -302,7 +310,9 @@
add5gEntry(addNrToLteNetworkType(entryValuesInt[0]));
addLteEntry(entryValuesInt[0]);
add3gEntry(entryValuesInt[1]);
- add2gEntry(entryValuesInt[2]);
+ if (display2gOptions) {
+ add2gEntry(entryValuesInt[2]);
+ }
break;
case ENABLED_NETWORKS_EXCEPT_GSM_LTE_CHOICES:
entryValues = getResourcesForSubId().getStringArray(
@@ -347,7 +357,9 @@
"ENABLED_NETWORKS_EXCEPT_LTE_CHOICES index error.");
}
add3gEntry(entryValuesInt[0]);
- add2gEntry(entryValuesInt[1]);
+ if (carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)) {
+ add2gEntry(entryValuesInt[1]);
+ }
break;
case ENABLED_NETWORKS_4G_CHOICES:
entryValues = getResourcesForSubId().getStringArray(
@@ -361,7 +373,9 @@
entryValuesInt[0]));
add4gEntry(entryValuesInt[0]);
add3gEntry(entryValuesInt[1]);
- add2gEntry(entryValuesInt[2]);
+ if (display2gOptions) {
+ add2gEntry(entryValuesInt[2]);
+ }
break;
case ENABLED_NETWORKS_CHOICES:
entryValues = getResourcesForSubId().getStringArray(
@@ -373,7 +387,9 @@
add5gEntry(addNrToLteNetworkType(entryValuesInt[0]));
addLteEntry(entryValuesInt[0]);
add3gEntry(entryValuesInt[1]);
- add2gEntry(entryValuesInt[2]);
+ if (display2gOptions) {
+ add2gEntry(entryValuesInt[2]);
+ }
break;
case PREFERRED_NETWORK_MODE_CHOICES_WORLD_MODE:
entryValues = getResourcesForSubId().getStringArray(
diff --git a/src/com/android/settings/nfc/DefaultPaymentSettings.java b/src/com/android/settings/nfc/DefaultPaymentSettings.java
index 4dceefc..08b843d 100644
--- a/src/com/android/settings/nfc/DefaultPaymentSettings.java
+++ b/src/com/android/settings/nfc/DefaultPaymentSettings.java
@@ -143,7 +143,8 @@
CandidateInfo info, String defaultKey, String systemDefaultKey) {
final NfcPaymentCandidateInfo candidateInfo = (NfcPaymentCandidateInfo) info;
if (candidateInfo.isManagedProfile()) {
- pref.setSummary("Work");
+ final String textWork = getContext().getString(R.string.nfc_work_text);
+ pref.setSummary(textWork);
}
}
diff --git a/src/com/android/settings/nfc/PaymentDefaultDialog.java b/src/com/android/settings/nfc/PaymentDefaultDialog.java
index 75746ce..d333b3d 100644
--- a/src/com/android/settings/nfc/PaymentDefaultDialog.java
+++ b/src/com/android/settings/nfc/PaymentDefaultDialog.java
@@ -59,10 +59,13 @@
CardEmulation.EXTRA_SERVICE_COMPONENT);
String category = intent.getStringExtra(CardEmulation.EXTRA_CATEGORY);
UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
+
+ int userId;
if (userHandle == null) {
- userHandle = UserHandle.CURRENT;
+ userId = UserHandle.myUserId();
+ } else {
+ userId = userHandle.getIdentifier();
}
- int userId = userHandle.getIdentifier();
setResult(RESULT_CANCELED);
if (!buildDialog(component, category, userId)) {
diff --git a/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java b/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java
index 38458d9..dec06b0 100644
--- a/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java
+++ b/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java
@@ -26,6 +26,7 @@
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.safetycenter.SafetyCenterManager;
import android.safetycenter.SafetyEvent;
import com.android.settings.security.ScreenLockPreferenceDetailsUtils;
@@ -37,8 +38,6 @@
/** Broadcast receiver for handling requests from Safety Center for fresh data. */
public class SafetySourceBroadcastReceiver extends BroadcastReceiver {
- private static final SafetyEvent EVENT_REFRESH_REQUESTED =
- new SafetyEvent.Builder(SAFETY_EVENT_TYPE_REFRESH_REQUESTED).build();
private static final SafetyEvent EVENT_DEVICE_REBOOTED =
new SafetyEvent.Builder(SAFETY_EVENT_TYPE_DEVICE_REBOOTED).build();
@@ -52,10 +51,15 @@
String[] sourceIdsExtra =
intent.getStringArrayExtra(EXTRA_REFRESH_SAFETY_SOURCE_IDS);
if (sourceIdsExtra != null && sourceIdsExtra.length > 0) {
+ final String refreshBroadcastId = intent.getStringExtra(
+ SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID);
+ final SafetyEvent safetyEvent = new SafetyEvent.Builder(
+ SAFETY_EVENT_TYPE_REFRESH_REQUESTED)
+ .setRefreshBroadcastId(refreshBroadcastId).build();
refreshSafetySources(
context,
ImmutableList.copyOf(sourceIdsExtra),
- EVENT_REFRESH_REQUESTED);
+ safetyEvent);
}
return;
}
diff --git a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
index ddd57f3..911aabb 100644
--- a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
+++ b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
@@ -67,10 +67,12 @@
private SparseArray<PreferenceViewHolder> mViewHolders;
public HighlightableTopLevelPreferenceAdapter(SettingsHomepageActivity homepageActivity,
- PreferenceGroup preferenceGroup, RecyclerView recyclerView, String key) {
+ PreferenceGroup preferenceGroup, RecyclerView recyclerView, String key,
+ boolean scrollNeeded) {
super(preferenceGroup);
mRecyclerView = recyclerView;
mHighlightKey = key;
+ mScrolled = !scrollNeeded;
mViewHolders = new SparseArray<>();
mContext = preferenceGroup.getContext();
mHomepageActivity = homepageActivity;
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index d8bdf32..528fbc3 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -168,10 +168,18 @@
break;
case MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS:
+ final Context context = getContext();
+ if (context == null) {
+ // Context may be null if the message is received after the Activity has
+ // been destroyed
+ Log.d(TAG, "Scan success but context is null");
+ return;
+ }
+
// We may get 2 WifiConfiguration if the QR code has no password in it,
// one for open network and one for enhanced open network.
final WifiManager wifiManager =
- getContext().getSystemService(WifiManager.class);
+ context.getSystemService(WifiManager.class);
final WifiNetworkConfig qrCodeWifiNetworkConfig =
(WifiNetworkConfig)msg.obj;
final List<WifiConfiguration> qrCodeWifiConfigurations =
diff --git a/src/com/android/settings/wifi/qrcode/QrCamera.java b/src/com/android/settings/wifi/qrcode/QrCamera.java
index 3865eb1..d07c543 100644
--- a/src/com/android/settings/wifi/qrcode/QrCamera.java
+++ b/src/com/android/settings/wifi/qrcode/QrCamera.java
@@ -124,6 +124,7 @@
}
if (mCamera != null) {
mCamera.stopPreview();
+ releaseCamera();
}
}
diff --git a/tests/robotests/assets/exempt_not_implementing_index_provider b/tests/robotests/assets/exempt_not_implementing_index_provider
index d4a1c2e..6a1a1ff 100644
--- a/tests/robotests/assets/exempt_not_implementing_index_provider
+++ b/tests/robotests/assets/exempt_not_implementing_index_provider
@@ -15,7 +15,6 @@
com.android.settings.applications.appinfo.WriteSettingsDetails
com.android.settings.applications.AppLaunchSettings
com.android.settings.applications.AppStorageSettings
-com.android.settings.applications.ConfirmConvertToFbe
com.android.settings.applications.ProcessStatsDetail
com.android.settings.applications.ProcessStatsSummary
com.android.settings.applications.ProcessStatsUi
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityFooterPreferenceControllerTest.java
index cc8520b..cce240d 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityFooterPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityFooterPreferenceControllerTest.java
@@ -121,4 +121,16 @@
assertThat(learnMoreView.getVisibility()).isEqualTo(View.GONE);
assertThat(mPreference.isLinkEnabled()).isFalse();
}
+
+ @Test
+ public void onBindViewHolder_setHelpResource_expectSummaryViewIsNonFocusable() {
+ mController.setupHelpLink(R.string.help_url_timeout, TEST_CONTENT_DESCRIPTION);
+ mController.displayPreference(mScreen);
+
+ mPreference.onBindViewHolder(mPreferenceViewHolder);
+
+ final TextView summaryView = (TextView) mPreferenceViewHolder
+ .findViewById(android.R.id.title);
+ assertThat(summaryView.isFocusable()).isFalse();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityFooterPreferenceTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityFooterPreferenceTest.java
index 14c56e8..0f83bc3 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityFooterPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityFooterPreferenceTest.java
@@ -71,4 +71,15 @@
android.R.id.title);
assertThat(summaryView.getMovementMethod()).isInstanceOf(MovementMethod.class);
}
+
+ @Test
+ public void onBindViewHolder_setLinkEnabled_expectSummaryViewIsNonFocusable() {
+ mAccessibilityFooterPreference.setLinkEnabled(true);
+
+ mAccessibilityFooterPreference.onBindViewHolder(mPreferenceViewHolder);
+
+ final TextView summaryView = (TextView) mPreferenceViewHolder.findViewById(
+ android.R.id.title);
+ assertThat(summaryView.isFocusable()).isFalse();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
index 04018a6..114f969 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
@@ -322,7 +322,7 @@
(AccessibilityFooterPreference) mFragment.getPreferenceScreen().getPreference(
mFragment.getPreferenceScreen().getPreferenceCount() - 1);
assertThat(accessibilityFooterPreference.getSummary()).isEqualTo(DEFAULT_SUMMARY);
- assertThat(accessibilityFooterPreference.isSelectable()).isEqualTo(true);
+ assertThat(accessibilityFooterPreference.isSelectable()).isEqualTo(false);
assertThat(accessibilityFooterPreference.getOrder()).isEqualTo(Integer.MAX_VALUE - 1);
}
diff --git a/tests/robotests/src/com/android/settings/development/FileEncryptionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/FileEncryptionPreferenceControllerTest.java
deleted file mode 100644
index 0784a61..0000000
--- a/tests/robotests/src/com/android/settings/development/FileEncryptionPreferenceControllerTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.os.RemoteException;
-import android.os.storage.IStorageManager;
-import android.sysprop.CryptoProperties;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.R;
-
-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 org.robolectric.RuntimeEnvironment;
-import org.robolectric.util.ReflectionHelpers;
-
-@RunWith(RobolectricTestRunner.class)
-public class FileEncryptionPreferenceControllerTest {
-
- @Mock
- private Preference mPreference;
- @Mock
- private PreferenceScreen mPreferenceScreen;
- @Mock
- private IStorageManager mStorageManager;
-
- private Context mContext;
- private FileEncryptionPreferenceController mController;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
- mController = new FileEncryptionPreferenceController(mContext);
- when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
- .thenReturn(mPreference);
- }
-
- @Test
- public void isAvailable_storageManagerNull_shouldBeFalse() {
- ReflectionHelpers.setField(mController, "mStorageManager", null);
-
- assertThat(mController.isAvailable()).isFalse();
- }
-
- @Test
- public void isAvailable_notConvertibleToFBE_shouldBeFalse() throws RemoteException {
- ReflectionHelpers.setField(mController, "mStorageManager", mStorageManager);
- when(mStorageManager.isConvertibleToFBE()).thenReturn(false);
-
- assertThat(mController.isAvailable()).isFalse();
- }
-
- @Test
- public void isAvailable_convertibleToFBE_shouldBeTrue() throws RemoteException {
- ReflectionHelpers.setField(mController, "mStorageManager", mStorageManager);
- when(mStorageManager.isConvertibleToFBE()).thenReturn(true);
-
- assertThat(mController.isAvailable()).isTrue();
- }
-
- @Test
- public void updateState_settingIsNotFile_shouldDoNothing() throws RemoteException {
- ReflectionHelpers.setField(mController, "mStorageManager", mStorageManager);
- when(mStorageManager.isConvertibleToFBE()).thenReturn(true);
- mController.displayPreference(mPreferenceScreen);
- CryptoProperties.type(CryptoProperties.type_values.NONE);
-
- mController.updateState(mPreference);
-
- verify(mPreference, never()).setEnabled(anyBoolean());
- verify(mPreference, never()).setSummary(anyString());
- }
-
- @Test
- public void updateState_settingIsFile_shouldSetSummaryAndDisablePreference()
- throws RemoteException {
- ReflectionHelpers.setField(mController, "mStorageManager", mStorageManager);
- when(mStorageManager.isConvertibleToFBE()).thenReturn(true);
- mController.displayPreference(mPreferenceScreen);
- CryptoProperties.type(CryptoProperties.type_values.FILE);
-
- mController.updateState(mPreference);
-
- verify(mPreference).setEnabled(false);
- verify(mPreference).setSummary(mContext.getString(R.string.convert_to_file_encryption_done));
- }
-}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryDiffEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryDiffEntryTest.java
index b1d8f0d..13ce29e 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryDiffEntryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryDiffEntryTest.java
@@ -349,12 +349,12 @@
}
@Test
- public void testIsSystemEntry_uidBatteryWithSystemProcess_returnTrue() {
+ public void testIsSystemEntry_uidBatteryWithSystemProcess_returnFalse() {
final BatteryDiffEntry entry =
createBatteryDiffEntry(
ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
/*uid=*/ 1230, /*isHidden=*/ false);
- assertThat(entry.isSystemEntry()).isTrue();
+ assertThat(entry.isSystemEntry()).isFalse();
}
@Test
diff --git a/tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java
index 1ada051..9c4df36 100644
--- a/tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java
@@ -19,8 +19,11 @@
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
+import android.os.Looper;
import android.provider.Settings;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -37,6 +40,7 @@
@RunWith(AndroidJUnit4.class)
public class HighTextContrastPreferenceControllerTest {
+ private static final String PREF_KEY = "text_contrast";
private static final int ON = 1;
private static final int OFF = 0;
private static final int UNKNOWN = -1;
@@ -44,12 +48,20 @@
private Context mContext;
private SwitchPreference mPreference;
private HighTextContrastPreferenceController mController;
+ private PreferenceScreen mScreen;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ final PreferenceManager preferenceManager = new PreferenceManager(mContext);
+ mScreen = preferenceManager.createPreferenceScreen(mContext);
mPreference = new SwitchPreference(mContext);
- mController = new HighTextContrastPreferenceController(mContext, "text_contrast");
+ mPreference.setKey(PREF_KEY);
+ mScreen.addPreference(mPreference);
+ mController = new HighTextContrastPreferenceController(mContext, PREF_KEY);
}
@Test
@@ -99,10 +111,13 @@
@Test
public void resetState_shouldDisableTextContrast() {
+ mController.displayPreference(mScreen);
mController.setChecked(true);
+ mPreference.setChecked(true);
mController.resetState();
+ assertThat(mPreference.isChecked()).isFalse();
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, UNKNOWN)).isEqualTo(OFF);
}
diff --git a/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java b/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java
index 8a4214c..8004d60 100644
--- a/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java
+++ b/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java
@@ -17,6 +17,7 @@
package com.android.settings.safetycenter;
import static android.safetycenter.SafetyCenterManager.ACTION_REFRESH_SAFETY_SOURCES;
+import static android.safetycenter.SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID;
import static android.safetycenter.SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCE_IDS;
import static android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_DEVICE_REBOOTED;
import static android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_REFRESH_REQUESTED;
@@ -148,6 +149,29 @@
}
@Test
+ public void onReceive_onRefreshWithBroadcastId_setsRefreshEventWithBroadcastId() {
+ final String refreshBroadcastId = "REFRESH_BROADCAST_ID";
+ when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
+ Intent intent =
+ new Intent()
+ .setAction(ACTION_REFRESH_SAFETY_SOURCES)
+ .putExtra(
+ EXTRA_REFRESH_SAFETY_SOURCE_IDS,
+ new String[]{ LockScreenSafetySource.SAFETY_SOURCE_ID })
+ .putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, refreshBroadcastId);
+
+ new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent);
+ ArgumentCaptor<SafetyEvent> captor = ArgumentCaptor.forClass(SafetyEvent.class);
+ verify(mSafetyCenterManagerWrapper, times(1))
+ .setSafetySourceData(any(), any(), any(), captor.capture());
+
+ assertThat(captor.getValue().getRefreshBroadcastId()).isEqualTo(refreshBroadcastId);
+ assertThat(captor.getValue()).isEqualTo(
+ new SafetyEvent.Builder(SAFETY_EVENT_TYPE_REFRESH_REQUESTED)
+ .setRefreshBroadcastId(refreshBroadcastId).build());
+ }
+
+ @Test
public void onReceive_onRefresh_withLockscreenSourceId_setsLockscreenData() {
when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
Intent intent =