Snap for 7394644 from 49f904c649 to sc-release
Change-Id: I1ef8ed8654eece10b45fc30bec35936e5533e8cf
This commit is contained in:
@@ -13,45 +13,54 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:padding="@dimen/admin_details_dialog_padding"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:paddingTop="@dimen/admin_details_dialog_padding"
|
||||||
|
android:paddingStart="@dimen/admin_details_dialog_padding"
|
||||||
|
android:paddingEnd="@dimen/admin_details_dialog_padding"
|
||||||
|
android:paddingBottom="@dimen/admin_details_dialog_padding_bottom"
|
||||||
|
android:orientation="vertical">
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:paddingBottom="@dimen/admin_details_dialog_title_bottom_padding">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/admin_support_icon"
|
||||||
|
android:layout_width="@dimen/admin_details_dialog_icon_size"
|
||||||
|
android:layout_height="@dimen/admin_details_dialog_icon_size"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:contentDescription="@null"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/admin_support_dialog_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:layout_marginTop="16dp"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_horizontal"
|
||||||
android:paddingBottom="@dimen/admin_details_dialog_title_bottom_padding">
|
android:text="@string/disabled_by_policy_title"
|
||||||
<ImageView android:id="@+id/admin_support_icon"
|
android:textAppearance="@style/TextAppearance.AdminDialogTitle"/>
|
||||||
android:layout_width="@dimen/admin_details_dialog_icon_size"
|
|
||||||
android:layout_height="@dimen/admin_details_dialog_icon_size"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:contentDescription="@null" />
|
|
||||||
<TextView android:id="@+id/admin_support_dialog_title"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingStart="@dimen/admin_details_dialog_padding"
|
|
||||||
android:text="@string/disabled_by_policy_title"
|
|
||||||
android:textAppearance="@style/TextAppearance.HeadLineFontFamily"/>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<ScrollView
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fadeScrollbars="false">
|
||||||
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fadeScrollbars="false">
|
android:orientation="vertical">
|
||||||
<LinearLayout
|
<TextView
|
||||||
|
android:id="@+id/admin_support_msg"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:textAppearance="@style/TextAppearance.AdminDialogMessage"
|
||||||
<TextView android:id="@+id/admin_support_msg"
|
android:maxLength="200"
|
||||||
android:layout_width="match_parent"
|
android:gravity="center_horizontal"
|
||||||
android:layout_height="wrap_content"
|
android:autoLink="email|phone|web"
|
||||||
android:textAppearance="@style/TextAppearance.HeadLineFontFamily.Subhead"
|
android:textColor="?android:attr/textColorSecondary"/>
|
||||||
android:maxLength="200"
|
|
||||||
android:autoLink="email|phone|web"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"/>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -133,26 +133,6 @@
|
|||||||
android:text="@string/security_settings_fingerprint_v2_enroll_introduction_footer_message_4" />
|
android:text="@string/security_settings_fingerprint_v2_enroll_introduction_footer_message_4" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingTop="12dp">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:contentDescription="@null"
|
|
||||||
android:src="@drawable/ic_link_24dp"/>
|
|
||||||
<Space
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/security_settings_fingerprint_v2_enroll_introduction_message_learn_more" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<!-- Keep in mind -->
|
<!-- Keep in mind -->
|
||||||
|
|||||||
@@ -262,8 +262,9 @@
|
|||||||
|
|
||||||
<!-- Admin support contact details dialog. -->
|
<!-- Admin support contact details dialog. -->
|
||||||
<dimen name="admin_details_dialog_padding">24dp</dimen>
|
<dimen name="admin_details_dialog_padding">24dp</dimen>
|
||||||
<dimen name="admin_details_dialog_title_bottom_padding">20dp</dimen>
|
<dimen name="admin_details_dialog_padding_bottom">32dp</dimen>
|
||||||
<dimen name="admin_details_dialog_icon_size">48dp</dimen>
|
<dimen name="admin_details_dialog_title_bottom_padding">16dp</dimen>
|
||||||
|
<dimen name="admin_details_dialog_icon_size">32dp</dimen>
|
||||||
<dimen name="admin_details_dialog_link_padding_top">36dp</dimen>
|
<dimen name="admin_details_dialog_link_padding_top">36dp</dimen>
|
||||||
<dimen name="admin_details_dialog_learn_more_button_top_margin">24dp</dimen>
|
<dimen name="admin_details_dialog_learn_more_button_top_margin">24dp</dimen>
|
||||||
<dimen name="admin_details_dialog_learn_more_button_padding">8dp</dimen>
|
<dimen name="admin_details_dialog_learn_more_button_padding">8dp</dimen>
|
||||||
|
|||||||
@@ -685,24 +685,24 @@
|
|||||||
<!-- Location settings, loading the number of apps which have location permission [CHAR LIMIT=30] -->
|
<!-- Location settings, loading the number of apps which have location permission [CHAR LIMIT=30] -->
|
||||||
<string name="location_settings_loading_app_permission_stats">Loading\u2026</string>
|
<string name="location_settings_loading_app_permission_stats">Loading\u2026</string>
|
||||||
<!-- Location settings footer warning text when location is on [CHAR LIMIT=NONE] -->
|
<!-- Location settings footer warning text when location is on [CHAR LIMIT=NONE] -->
|
||||||
<string name="location_settings_footer_location_on">
|
<string name="location_settings_footer_general">
|
||||||
<br><br>Apps with the Nearby devices permission can determine the
|
Apps with the Nearby devices permission can determine the
|
||||||
relative position of connected devices.
|
relative position of connected devices.
|
||||||
|
|
||||||
<br><br><a href="<xliff:g example="http://www.google.com" id="url">
|
|
||||||
https://support.google.com/android/answer/3467281</xliff:g>">Learn more</a>
|
|
||||||
</string>
|
</string>
|
||||||
<!-- Location settings footer warning text when location is off [CHAR LIMIT=NONE] -->
|
<!-- Location settings footer warning text when location is off [CHAR LIMIT=NONE] -->
|
||||||
<string name="location_settings_footer_location_off">
|
<string name="location_settings_footer_location_off">
|
||||||
Location access is off for apps and services. Your device location may still be sent to
|
Location access is off for apps and services. Your device location may still be sent to
|
||||||
emergency responders when you call or text an emergency number.
|
emergency responders when you call or text an emergency number.
|
||||||
|
</string>
|
||||||
<br><br>Apps with the Nearby devices permission can determine the relative
|
<!-- Location settings footer link to support page [CHAR LIMIT=NONE] -->
|
||||||
position of connected devices.
|
<string name="location_settings_footer_learn_more">
|
||||||
|
<a href="<xliff:g example="http://www.google.com"
|
||||||
<br><br><a href="<xliff:g example="http://www.google.com"
|
|
||||||
id="url"> https://support.google.com/android/answer/3467281</xliff:g>">Learn more</a>
|
id="url"> https://support.google.com/android/answer/3467281</xliff:g>">Learn more</a>
|
||||||
</string>
|
</string>
|
||||||
|
<!-- Location settings footer link content description [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="location_settings_footer_learn_more_content_description">
|
||||||
|
Learn more about Location Settings.
|
||||||
|
</string>
|
||||||
|
|
||||||
<!-- Main Settings screen setting option title for the item to take you to the accounts screen [CHAR LIMIT=22] -->
|
<!-- Main Settings screen setting option title for the item to take you to the accounts screen [CHAR LIMIT=22] -->
|
||||||
<string name="account_settings_title">Accounts</string>
|
<string name="account_settings_title">Accounts</string>
|
||||||
|
|||||||
@@ -871,4 +871,15 @@
|
|||||||
<item name="android:textSize">16sp</item>
|
<item name="android:textSize">16sp</item>
|
||||||
<item name="android:textColor">?android:attr/textColorSecondary</item>
|
<item name="android:textColor">?android:attr/textColorSecondary</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="TextAppearance.AdminDialogTitle"
|
||||||
|
parent="@*android:style/TextAppearance.DeviceDefault.Title">
|
||||||
|
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
|
||||||
|
<item name="android:textSize">24sp</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="TextAppearance.AdminDialogMessage"
|
||||||
|
parent="@*android:style/TextAppearance.DeviceDefault">
|
||||||
|
<item name="android:textColor">?android:attr/textColorSecondary</item>
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
<item name="android:layout">@layout/preference_widget_seekbar_settings</item>
|
<item name="android:layout">@layout/preference_widget_seekbar_settings</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="SyncSwitchPreference" parent="@style/Preference.Material">
|
<style name="SyncSwitchPreference" parent="@style/SettingsSwitchPreference.SettingsLib">
|
||||||
<item name="android:widgetLayout">@layout/preference_widget_sync_toggle</item>
|
<item name="android:widgetLayout">@layout/preference_widget_sync_toggle</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
android:key="accessibility_button_opacity"
|
android:key="accessibility_button_opacity"
|
||||||
android:title="@string/accessibility_button_opacity_title"
|
android:title="@string/accessibility_button_opacity_title"
|
||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
settings:controller="com.android.settings.accessibility.FloatingMenuOpacityPreferenceController"/>
|
settings:controller="com.android.settings.accessibility.FloatingMenuTransparencyPreferenceController"/>
|
||||||
|
|
||||||
<com.android.settings.accessibility.AccessibilityFooterPreference
|
<com.android.settings.accessibility.AccessibilityFooterPreference
|
||||||
android:key="accessibility_button_footer"
|
android:key="accessibility_button_footer"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:key="important_conversations"
|
android:key="important_conversations"
|
||||||
android:title="@string/important_conversations"
|
android:title="@string/important_conversations"
|
||||||
android:visibility="gone"
|
settings:isPreferenceVisible="false"
|
||||||
settings:allowDividerAbove="false"
|
settings:allowDividerAbove="false"
|
||||||
settings:allowDividerBelow="true" >
|
settings:allowDividerBelow="true" >
|
||||||
<Preference
|
<Preference
|
||||||
@@ -48,6 +48,7 @@
|
|||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="@string/other_conversations"
|
android:title="@string/other_conversations"
|
||||||
android:key="other_conversations"
|
android:key="other_conversations"
|
||||||
|
settings:isPreferenceVisible="false"
|
||||||
settings:allowDividerAbove="true"
|
settings:allowDividerAbove="true"
|
||||||
settings:allowDividerBelow="false" />
|
settings:allowDividerBelow="false" />
|
||||||
|
|
||||||
@@ -55,6 +56,7 @@
|
|||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="@string/recent_conversations"
|
android:title="@string/recent_conversations"
|
||||||
android:key="recent_conversations"
|
android:key="recent_conversations"
|
||||||
|
settings:isPreferenceVisible="false"
|
||||||
settings:allowDividerAbove="true"
|
settings:allowDividerAbove="true"
|
||||||
settings:allowDividerBelow="false" />
|
settings:allowDividerBelow="false" />
|
||||||
|
|
||||||
|
|||||||
@@ -70,8 +70,9 @@
|
|||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<com.android.settingslib.widget.FooterPreference
|
<com.android.settingslib.widget.FooterPreference
|
||||||
android:title="@string/location_settings_footer_location_on"
|
android:title="@string/location_settings_footer_general"
|
||||||
android:key="location_footer"
|
android:key="location_footer"
|
||||||
android:selectable="false"
|
android:selectable="false"
|
||||||
|
settings:searchable="false"
|
||||||
settings:controller="com.android.settings.location.LocationSettingsFooterPreferenceController"/>
|
settings:controller="com.android.settings.location.LocationSettingsFooterPreferenceController"/>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
settings:controller="com.android.settings.location.LocationServicesPreferenceController"/>
|
settings:controller="com.android.settings.location.LocationServicesPreferenceController"/>
|
||||||
|
|
||||||
<com.android.settingslib.widget.FooterPreference
|
<com.android.settingslib.widget.FooterPreference
|
||||||
android:title="@string/location_settings_footer_location_on"
|
android:title="@string/location_settings_footer_general"
|
||||||
android:key="location_footer"
|
android:key="location_footer"
|
||||||
settings:controller="com.android.settings.location.LocationSettingsFooterPreferenceController"
|
settings:controller="com.android.settings.location.LocationSettingsFooterPreferenceController"
|
||||||
android:selectable="false"/>
|
android:selectable="false"/>
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
settings:controller="com.android.settings.location.LocationServicesForWorkPreferenceController"/>
|
settings:controller="com.android.settings.location.LocationServicesForWorkPreferenceController"/>
|
||||||
|
|
||||||
<com.android.settingslib.widget.FooterPreference
|
<com.android.settingslib.widget.FooterPreference
|
||||||
android:title="@string/location_settings_footer_location_on"
|
android:title="@string/location_settings_footer_general"
|
||||||
android:key="location_footer"
|
android:key="location_footer"
|
||||||
settings:controller="com.android.settings.location.LocationSettingsFooterPreferenceController"
|
settings:controller="com.android.settings.location.LocationSettingsFooterPreferenceController"
|
||||||
android:selectable="false"/>
|
android:selectable="false"/>
|
||||||
|
|||||||
@@ -59,12 +59,6 @@
|
|||||||
</intent>
|
</intent>
|
||||||
</Preference>
|
</Preference>
|
||||||
|
|
||||||
<Preference
|
|
||||||
android:key="network_scorer_picker"
|
|
||||||
android:title="@string/network_scorer_picker_title"
|
|
||||||
android:fragment="com.android.settings.network.NetworkScorerPicker"
|
|
||||||
settings:controller="com.android.settings.network.NetworkScorerPickerPreferenceController" />
|
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:key="wifi_direct"
|
android:key="wifi_direct"
|
||||||
android:title="@string/wifi_menu_p2p"
|
android:title="@string/wifi_menu_p2p"
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.os.Handler;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
|
import androidx.annotation.FloatRange;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.preference.PreferenceScreen;
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
@@ -32,15 +33,18 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
|||||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||||
|
|
||||||
/** Preference controller that controls the opacity seekbar in accessibility button page. */
|
/** Preference controller that controls the transparency seekbar in accessibility button page. */
|
||||||
public class FloatingMenuOpacityPreferenceController extends SliderPreferenceController
|
public class FloatingMenuTransparencyPreferenceController extends SliderPreferenceController
|
||||||
implements LifecycleObserver, OnResume, OnPause {
|
implements LifecycleObserver, OnResume, OnPause {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final float DEFAULT_OPACITY = 0.55f;
|
@FloatRange(from = 0.0, to = 1.0)
|
||||||
|
static final float DEFAULT_TRANSPARENCY = 0.45f;
|
||||||
|
@VisibleForTesting
|
||||||
|
static final float MAXIMUM_TRANSPARENCY = 1.0f;
|
||||||
private static final int FADE_ENABLED = 1;
|
private static final int FADE_ENABLED = 1;
|
||||||
private static final float MIN_PROGRESS = 10f;
|
private static final float MIN_PROGRESS = 0f;
|
||||||
private static final float MAX_PROGRESS = 100f;
|
private static final float MAX_PROGRESS = 90f;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final float PRECISION = 100f;
|
static final float PRECISION = 100f;
|
||||||
|
|
||||||
@@ -51,7 +55,7 @@ public class FloatingMenuOpacityPreferenceController extends SliderPreferenceCon
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
SeekBarPreference mPreference;
|
SeekBarPreference mPreference;
|
||||||
|
|
||||||
public FloatingMenuOpacityPreferenceController(Context context,
|
public FloatingMenuTransparencyPreferenceController(Context context,
|
||||||
String preferenceKey) {
|
String preferenceKey) {
|
||||||
super(context, preferenceKey);
|
super(context, preferenceKey);
|
||||||
mContentResolver = context.getContentResolver();
|
mContentResolver = context.getContentResolver();
|
||||||
@@ -101,15 +105,14 @@ public class FloatingMenuOpacityPreferenceController extends SliderPreferenceCon
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSliderPosition() {
|
public int getSliderPosition() {
|
||||||
return convertOpacityFloatToInt(getOpacity());
|
return convertTransparencyFloatToInt(getTransparency());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setSliderPosition(int position) {
|
public boolean setSliderPosition(int position) {
|
||||||
final float value = convertOpacityIntToFloat(position);
|
final float opacityValue = MAXIMUM_TRANSPARENCY - convertTransparencyIntToFloat(position);
|
||||||
|
|
||||||
return Settings.Secure.putFloat(mContentResolver,
|
return Settings.Secure.putFloat(mContentResolver,
|
||||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, value);
|
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, opacityValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -130,21 +133,21 @@ public class FloatingMenuOpacityPreferenceController extends SliderPreferenceCon
|
|||||||
mPreference.setEnabled(AccessibilityUtil.isFloatingMenuEnabled(mContext) && fadeEnabled);
|
mPreference.setEnabled(AccessibilityUtil.isFloatingMenuEnabled(mContext) && fadeEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int convertOpacityFloatToInt(float value) {
|
private int convertTransparencyFloatToInt(float value) {
|
||||||
return Math.round(value * PRECISION);
|
return Math.round(value * PRECISION);
|
||||||
}
|
}
|
||||||
|
|
||||||
private float convertOpacityIntToFloat(int value) {
|
private float convertTransparencyIntToFloat(int value) {
|
||||||
return (float) value / PRECISION;
|
return (float) value / PRECISION;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float getOpacity() {
|
private float getTransparency() {
|
||||||
float value = Settings.Secure.getFloat(mContentResolver,
|
float transparencyValue = MAXIMUM_TRANSPARENCY - (Settings.Secure.getFloat(mContentResolver,
|
||||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, DEFAULT_OPACITY);
|
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, DEFAULT_TRANSPARENCY));
|
||||||
final float minValue = MIN_PROGRESS / PRECISION;
|
final float minValue = MIN_PROGRESS / PRECISION;
|
||||||
final float maxValue = MAX_PROGRESS / PRECISION;
|
final float maxValue = MAX_PROGRESS / PRECISION;
|
||||||
|
|
||||||
return (value < minValue || value > maxValue) ? DEFAULT_OPACITY : value;
|
return (transparencyValue < minValue || transparencyValue > maxValue)
|
||||||
|
? DEFAULT_TRANSPARENCY : transparencyValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +52,7 @@ import com.android.settings.SettingsActivity;
|
|||||||
import com.android.settings.SettingsPreferenceFragment;
|
import com.android.settings.SettingsPreferenceFragment;
|
||||||
import com.android.settings.accessibility.AccessibilityEditDialogUtils.DialogType;
|
import com.android.settings.accessibility.AccessibilityEditDialogUtils.DialogType;
|
||||||
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
|
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
|
||||||
|
import com.android.settings.utils.LocaleUtils;
|
||||||
import com.android.settings.widget.SettingsMainSwitchBar;
|
import com.android.settings.widget.SettingsMainSwitchBar;
|
||||||
import com.android.settings.widget.SettingsMainSwitchPreference;
|
import com.android.settings.widget.SettingsMainSwitchPreference;
|
||||||
import com.android.settingslib.accessibility.AccessibilityUtils;
|
import com.android.settingslib.accessibility.AccessibilityUtils;
|
||||||
@@ -659,10 +660,9 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
|
|||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
list.add(softwareTitle);
|
list.add(softwareTitle);
|
||||||
}
|
}
|
||||||
final String joinStrings = TextUtils.join(/* delimiter= */", ", list);
|
|
||||||
|
|
||||||
return CaseMap.toTitle().wholeString().noLowercase().apply(Locale.getDefault(), /* iter= */
|
return CaseMap.toTitle().wholeString().noLowercase().apply(Locale.getDefault(), /* iter= */
|
||||||
null, joinStrings);
|
null, LocaleUtils.getConcatenatedString(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import com.android.settings.DialogCreatable;
|
|||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.accessibility.AccessibilityEditDialogUtils.DialogType;
|
import com.android.settings.accessibility.AccessibilityEditDialogUtils.DialogType;
|
||||||
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
|
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
|
||||||
|
import com.android.settings.utils.LocaleUtils;
|
||||||
|
|
||||||
import com.google.android.setupcompat.util.WizardManagerHelper;
|
import com.google.android.setupcompat.util.WizardManagerHelper;
|
||||||
|
|
||||||
@@ -282,10 +283,9 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
|||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
list.add(softwareTitle);
|
list.add(softwareTitle);
|
||||||
}
|
}
|
||||||
final String joinStrings = TextUtils.join(/* delimiter= */", ", list);
|
|
||||||
|
|
||||||
return CaseMap.toTitle().wholeString().noLowercase().apply(Locale.getDefault(), /* iter= */
|
return CaseMap.toTitle().wholeString().noLowercase().apply(Locale.getDefault(), /* iter= */
|
||||||
null, joinStrings);
|
null, LocaleUtils.getConcatenatedString(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ public class AccountTypePreferenceLoader {
|
|||||||
private static final String LAUNCHING_LOCATION_SETTINGS =
|
private static final String LAUNCHING_LOCATION_SETTINGS =
|
||||||
"com.android.settings.accounts.LAUNCHING_LOCATION_SETTINGS";
|
"com.android.settings.accounts.LAUNCHING_LOCATION_SETTINGS";
|
||||||
|
|
||||||
|
|
||||||
private AuthenticatorHelper mAuthenticatorHelper;
|
private AuthenticatorHelper mAuthenticatorHelper;
|
||||||
private UserHandle mUserHandle;
|
private UserHandle mUserHandle;
|
||||||
private PreferenceFragmentCompat mFragment;
|
private PreferenceFragmentCompat mFragment;
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ public class SettingsBaseActivity extends FragmentActivity {
|
|||||||
final int appliedTheme = ThemeHelper.isSetupWizardDayNightEnabled(this)
|
final int appliedTheme = ThemeHelper.isSetupWizardDayNightEnabled(this)
|
||||||
? R.style.SubSettings_SetupWizard : R.style.SudThemeGlifV3_Light;
|
? R.style.SubSettings_SetupWizard : R.style.SudThemeGlifV3_Light;
|
||||||
setTheme(appliedTheme);
|
setTheme(appliedTheme);
|
||||||
|
ThemeHelper.trySetDynamicColor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SILKY_HOME)
|
if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SILKY_HOME)
|
||||||
|
|||||||
@@ -22,12 +22,8 @@ import android.app.Activity;
|
|||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.ColorStateList;
|
|
||||||
import android.content.res.TypedArray;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.util.IconDrawableFactory;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -38,7 +34,6 @@ import androidx.annotation.VisibleForTesting;
|
|||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.Utils;
|
|
||||||
import com.android.settingslib.RestrictedLockUtils;
|
import com.android.settingslib.RestrictedLockUtils;
|
||||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||||
@@ -143,21 +138,8 @@ public class ActionDisabledByAdminDialogHelper {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void setAdminSupportIcon(View root, ComponentName admin, int userId) {
|
void setAdminSupportIcon(View root, ComponentName admin, int userId) {
|
||||||
ImageView supportIconView = root.requireViewById(R.id.admin_support_icon);
|
ImageView supportIconView = root.requireViewById(R.id.admin_support_icon);
|
||||||
if (isNotCurrentUserOrProfile(admin, userId)) {
|
supportIconView.setImageDrawable(
|
||||||
supportIconView.setImageDrawable(
|
mActivity.getDrawable(com.android.internal.R.drawable.ic_corp_badge));
|
||||||
mActivity.getDrawable(com.android.internal.R.drawable.ic_info));
|
|
||||||
|
|
||||||
TypedArray ta = mActivity.obtainStyledAttributes(new int[]{android.R.attr.colorAccent});
|
|
||||||
supportIconView.setImageTintList(ColorStateList.valueOf(ta.getColor(0, 0)));
|
|
||||||
ta.recycle();
|
|
||||||
} else {
|
|
||||||
final Drawable badgedIcon = Utils.getBadgedIcon(
|
|
||||||
IconDrawableFactory.newInstance(mActivity),
|
|
||||||
mActivity.getPackageManager(),
|
|
||||||
admin.getPackageName(),
|
|
||||||
userId);
|
|
||||||
supportIconView.setImageDrawable(badgedIcon);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import android.app.settings.SettingsEnums;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
@@ -64,7 +65,6 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
|||||||
ExpandDividerPreference.OnExpandListener {
|
ExpandDividerPreference.OnExpandListener {
|
||||||
private static final String TAG = "BatteryChartPreferenceController";
|
private static final String TAG = "BatteryChartPreferenceController";
|
||||||
private static final String KEY_FOOTER_PREF = "battery_graph_footer";
|
private static final String KEY_FOOTER_PREF = "battery_graph_footer";
|
||||||
private static final int ADD_FOOTER_DELAYED_MS = 250;
|
|
||||||
|
|
||||||
/** Desired battery history size for timestamp slots. */
|
/** Desired battery history size for timestamp slots. */
|
||||||
public static final int DESIRED_HISTORY_SIZE = 25;
|
public static final int DESIRED_HISTORY_SIZE = 25;
|
||||||
@@ -267,11 +267,6 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
|||||||
|
|
||||||
void setBatteryHistoryMap(
|
void setBatteryHistoryMap(
|
||||||
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
|
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
|
||||||
mHandler.post(() -> setBatteryHistoryMapInner(batteryHistoryMap));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setBatteryHistoryMapInner(
|
|
||||||
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
|
|
||||||
// Resets all battery history data relative variables.
|
// Resets all battery history data relative variables.
|
||||||
if (batteryHistoryMap == null || batteryHistoryMap.isEmpty()) {
|
if (batteryHistoryMap == null || batteryHistoryMap.isEmpty()) {
|
||||||
mBatteryIndexedMap = null;
|
mBatteryIndexedMap = null;
|
||||||
@@ -298,19 +293,15 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
|||||||
mBatteryHistoryLevels[index] =
|
mBatteryHistoryLevels[index] =
|
||||||
Math.round(batteryLevelCounter / entryMap.size());
|
Math.round(batteryLevelCounter / entryMap.size());
|
||||||
}
|
}
|
||||||
// Generates indexed usage map for chart.
|
|
||||||
mBatteryIndexedMap =
|
|
||||||
ConvertUtils.getIndexedUsageMap(
|
|
||||||
mPrefContext, /*timeSlotSize=*/ CHART_LEVEL_ARRAY_SIZE - 1,
|
|
||||||
mBatteryHistoryKeys, batteryHistoryMap,
|
|
||||||
/*purgeLowPercentageAndFakeData=*/ true);
|
|
||||||
forceRefreshUi();
|
forceRefreshUi();
|
||||||
|
|
||||||
Log.d(TAG, String.format(
|
Log.d(TAG, String.format(
|
||||||
"setBatteryHistoryMap() size=%d\nkeys=%s\nlevels=%s",
|
"setBatteryHistoryMap() size=%d\nkeys=%s\nlevels=%s",
|
||||||
batteryHistoryMap.size(),
|
batteryHistoryMap.size(),
|
||||||
utcToLocalTime(mBatteryHistoryKeys),
|
utcToLocalTime(mBatteryHistoryKeys),
|
||||||
Arrays.toString(mBatteryHistoryLevels)));
|
Arrays.toString(mBatteryHistoryLevels)));
|
||||||
|
|
||||||
|
// Loads item icon and label in the background.
|
||||||
|
new LoadAllItemsInfoTask(batteryHistoryMap).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBatteryChartView(final BatteryChartView batteryChartView) {
|
void setBatteryChartView(final BatteryChartView batteryChartView) {
|
||||||
@@ -599,9 +590,7 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
|||||||
containAppItems
|
containAppItems
|
||||||
? R.string.battery_usage_screen_footer
|
? R.string.battery_usage_screen_footer
|
||||||
: R.string.battery_usage_screen_footer_empty));
|
: R.string.battery_usage_screen_footer_empty));
|
||||||
mHandler.postDelayed(
|
mHandler.post(() -> mPreferenceScreen.addPreference(mFooterPreference));
|
||||||
() -> mPreferenceScreen.addPreference(mFooterPreference),
|
|
||||||
ADD_FOOTER_DELAYED_MS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String utcToLocalTime(long[] timestamps) {
|
private static String utcToLocalTime(long[] timestamps) {
|
||||||
@@ -670,4 +659,53 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
|||||||
}
|
}
|
||||||
return batteryHistoryKeys;
|
return batteryHistoryKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Loads all items icon and label in the background.
|
||||||
|
private final class LoadAllItemsInfoTask
|
||||||
|
extends AsyncTask<Void, Void, Map<Integer, List<BatteryDiffEntry>>> {
|
||||||
|
|
||||||
|
private long[] mBatteryHistoryKeysCache;
|
||||||
|
private Map<Long, Map<String, BatteryHistEntry>> mBatteryHistoryMap;
|
||||||
|
|
||||||
|
private LoadAllItemsInfoTask(
|
||||||
|
Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
|
||||||
|
this.mBatteryHistoryMap = batteryHistoryMap;
|
||||||
|
this.mBatteryHistoryKeysCache = mBatteryHistoryKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Map<Integer, List<BatteryDiffEntry>> doInBackground(Void... voids) {
|
||||||
|
if (mPrefContext == null || mBatteryHistoryKeysCache == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final long startTime = System.currentTimeMillis();
|
||||||
|
final Map<Integer, List<BatteryDiffEntry>> indexedUsageMap =
|
||||||
|
ConvertUtils.getIndexedUsageMap(
|
||||||
|
mPrefContext, /*timeSlotSize=*/ CHART_LEVEL_ARRAY_SIZE - 1,
|
||||||
|
mBatteryHistoryKeysCache, mBatteryHistoryMap,
|
||||||
|
/*purgeLowPercentageAndFakeData=*/ true);
|
||||||
|
// Pre-loads each BatteryDiffEntry relative icon and label for all slots.
|
||||||
|
for (List<BatteryDiffEntry> entries : indexedUsageMap.values()) {
|
||||||
|
entries.forEach(entry -> entry.loadLabelAndIcon());
|
||||||
|
}
|
||||||
|
Log.d(TAG, String.format("execute LoadAllItemsInfoTask in %d/ms",
|
||||||
|
(System.currentTimeMillis() - startTime)));
|
||||||
|
return indexedUsageMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(
|
||||||
|
Map<Integer, List<BatteryDiffEntry>> indexedUsageMap) {
|
||||||
|
mBatteryHistoryMap = null;
|
||||||
|
mBatteryHistoryKeysCache = null;
|
||||||
|
if (indexedUsageMap == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Posts results back to main thread to refresh UI.
|
||||||
|
mHandler.post(() -> {
|
||||||
|
mBatteryIndexedMap = indexedUsageMap;
|
||||||
|
forceRefreshUi();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ public class BatteryDiffEntry {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadLabelAndIcon() {
|
void loadLabelAndIcon() {
|
||||||
if (mIsLoaded) {
|
if (mIsLoaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.content.pm.PackageManager;
|
|||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
@@ -42,6 +43,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class LocationSettingsFooterPreferenceController extends LocationBasePreferenceController {
|
public class LocationSettingsFooterPreferenceController extends LocationBasePreferenceController {
|
||||||
private static final String TAG = "LocationFooter";
|
private static final String TAG = "LocationFooter";
|
||||||
|
private static final String PARAGRAPH_SEPARATOR = "<br><br>";
|
||||||
private static final Intent INJECT_INTENT =
|
private static final Intent INJECT_INTENT =
|
||||||
new Intent(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
|
new Intent(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
|
||||||
|
|
||||||
@@ -90,24 +92,33 @@ public class LocationSettingsFooterPreferenceController extends LocationBasePref
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateFooterPreference() {
|
private void updateFooterPreference() {
|
||||||
String footerString = mContext.getString(
|
String footerString = mContext.getString(R.string.location_settings_footer_general);
|
||||||
mLocationEnabled ? R.string.location_settings_footer_location_on
|
|
||||||
: R.string.location_settings_footer_location_off);
|
|
||||||
if (mLocationEnabled) {
|
if (mLocationEnabled) {
|
||||||
footerString = mInjectedFooterString + footerString;
|
if (!TextUtils.isEmpty(mInjectedFooterString)) {
|
||||||
|
footerString = Html.escapeHtml(mInjectedFooterString) + PARAGRAPH_SEPARATOR
|
||||||
|
+ footerString;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
footerString = mContext.getString(R.string.location_settings_footer_location_off)
|
||||||
|
+ PARAGRAPH_SEPARATOR
|
||||||
|
+ footerString;
|
||||||
}
|
}
|
||||||
if (mFooterPreference != null) {
|
if (mFooterPreference != null) {
|
||||||
mFooterPreference.setTitle(Html.fromHtml(footerString));
|
mFooterPreference.setTitle(Html.fromHtml(footerString
|
||||||
|
+ PARAGRAPH_SEPARATOR
|
||||||
|
+ mContext.getString(
|
||||||
|
R.string.location_settings_footer_learn_more)));
|
||||||
|
mFooterPreference.setContentDescription(Html.fromHtml(footerString + mContext.getString(
|
||||||
|
R.string.location_settings_footer_learn_more_content_description)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Location footer preference group should be displayed if there is at least one footer to
|
* Location footer preference group should always be displayed.
|
||||||
* inject.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int getAvailabilityStatus() {
|
public int getAvailabilityStatus() {
|
||||||
return !getFooterData().isEmpty() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
|
return AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,145 +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.network;
|
|
||||||
|
|
||||||
import android.app.settings.SettingsEnums;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.net.NetworkScoreManager;
|
|
||||||
import android.net.NetworkScorerAppData;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
import androidx.preference.Preference;
|
|
||||||
import androidx.preference.PreferenceScreen;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
|
||||||
import com.android.settingslib.widget.RadioButtonPreference;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fragment for choosing default network scorer.
|
|
||||||
*/
|
|
||||||
public class NetworkScorerPicker extends InstrumentedPreferenceFragment implements
|
|
||||||
RadioButtonPreference.OnClickListener {
|
|
||||||
|
|
||||||
private NetworkScoreManager mNetworkScoreManager;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsCategory() {
|
|
||||||
return SettingsEnums.SETTINGS_NETWORK_SCORER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
|
||||||
super.onCreatePreferences(savedInstanceState, rootKey);
|
|
||||||
updateCandidates();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(Context context) {
|
|
||||||
super.onAttach(context);
|
|
||||||
mNetworkScoreManager = createNetworkScorerManager(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
|
||||||
Bundle savedInstanceState) {
|
|
||||||
final View view = super.onCreateView(inflater, container, savedInstanceState);
|
|
||||||
// this is needed so the back button goes back to previous fragment
|
|
||||||
setHasOptionsMenu(true);
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getPreferenceScreenResId() {
|
|
||||||
return R.xml.network_scorer_picker_prefs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public void updateCandidates() {
|
|
||||||
final PreferenceScreen screen = getPreferenceScreen();
|
|
||||||
screen.removeAll();
|
|
||||||
|
|
||||||
final List<NetworkScorerAppData> scorers = mNetworkScoreManager.getAllValidScorers();
|
|
||||||
final String defaultAppKey = getActiveScorerPackage();
|
|
||||||
|
|
||||||
final RadioButtonPreference nonePref = new RadioButtonPreference(getPrefContext());
|
|
||||||
nonePref.setTitle(R.string.network_scorer_picker_none_preference);
|
|
||||||
if (scorers.isEmpty()) {
|
|
||||||
nonePref.setChecked(true);
|
|
||||||
} else {
|
|
||||||
nonePref.setKey(null);
|
|
||||||
nonePref.setChecked(TextUtils.isEmpty(defaultAppKey));
|
|
||||||
nonePref.setOnClickListener(this);
|
|
||||||
}
|
|
||||||
screen.addPreference(nonePref);
|
|
||||||
|
|
||||||
final int numScorers = scorers.size();
|
|
||||||
for (int i = 0; i < numScorers; i++) {
|
|
||||||
final RadioButtonPreference pref = new RadioButtonPreference(getPrefContext());
|
|
||||||
final NetworkScorerAppData appData = scorers.get(i);
|
|
||||||
final String appKey = appData.getRecommendationServicePackageName();
|
|
||||||
pref.setTitle(appData.getRecommendationServiceLabel());
|
|
||||||
pref.setKey(appKey);
|
|
||||||
pref.setChecked(TextUtils.equals(defaultAppKey, appKey));
|
|
||||||
pref.setOnClickListener(this);
|
|
||||||
screen.addPreference(pref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getActiveScorerPackage() {
|
|
||||||
return mNetworkScoreManager.getActiveScorerPackage();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean setActiveScorer(String key) {
|
|
||||||
if (!TextUtils.equals(key, getActiveScorerPackage())) {
|
|
||||||
return mNetworkScoreManager.setActiveScorer(key);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRadioButtonClicked(RadioButtonPreference selected) {
|
|
||||||
final String selectedKey = selected.getKey();
|
|
||||||
final boolean success = setActiveScorer(selectedKey);
|
|
||||||
if (success) {
|
|
||||||
updateCheckedState(selectedKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateCheckedState(String selectedKey) {
|
|
||||||
final PreferenceScreen screen = getPreferenceScreen();
|
|
||||||
final int count = screen.getPreferenceCount();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
final Preference pref = screen.getPreference(i);
|
|
||||||
if (pref instanceof RadioButtonPreference) {
|
|
||||||
final RadioButtonPreference radioPref = (RadioButtonPreference) pref;
|
|
||||||
radioPref.setChecked(TextUtils.equals(pref.getKey(), selectedKey));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
NetworkScoreManager createNetworkScorerManager(Context context) {
|
|
||||||
return (NetworkScoreManager) context.getSystemService(Context.NETWORK_SCORE_SERVICE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,67 +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.network;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.net.NetworkScoreManager;
|
|
||||||
import android.net.NetworkScorerAppData;
|
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.core.BasePreferenceController;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link AbstractPreferenceController} that shows the active network scorer and toggles the
|
|
||||||
* preference based on whether or not there are valid scorers installed.
|
|
||||||
*/
|
|
||||||
public class NetworkScorerPickerPreferenceController extends BasePreferenceController {
|
|
||||||
|
|
||||||
private final NetworkScoreManager mNetworkScoreManager;
|
|
||||||
|
|
||||||
public NetworkScorerPickerPreferenceController(Context context, String key) {
|
|
||||||
super(context, key);
|
|
||||||
mNetworkScoreManager =
|
|
||||||
(NetworkScoreManager) mContext.getSystemService(Context.NETWORK_SCORE_SERVICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getAvailabilityStatus() {
|
|
||||||
return AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateState(Preference preference) {
|
|
||||||
final List<NetworkScorerAppData> allValidScorers =
|
|
||||||
mNetworkScoreManager.getAllValidScorers();
|
|
||||||
boolean enabled = !allValidScorers.isEmpty();
|
|
||||||
preference.setEnabled(enabled);
|
|
||||||
if (!enabled) {
|
|
||||||
preference.setSummary(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworkScorerAppData scorer = mNetworkScoreManager.getActiveScorer();
|
|
||||||
if (scorer == null) {
|
|
||||||
preference.setSummary(mContext.getString(
|
|
||||||
R.string.network_scorer_picker_none_preference));
|
|
||||||
} else {
|
|
||||||
preference.setSummary(scorer.getRecommendationServiceLabel());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -153,7 +153,7 @@ public class RedactionInterstitial extends SettingsActivity {
|
|||||||
}
|
}
|
||||||
final RedactionInterstitial activity = (RedactionInterstitial) getActivity();
|
final RedactionInterstitial activity = (RedactionInterstitial) getActivity();
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
activity.setResult(RESULT_OK, null);
|
activity.setResult(RESULT_CANCELED, null);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,21 +68,10 @@ public class AllConversationsPreferenceController extends ConversationListPrefer
|
|||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
PreferenceCategory pref = (PreferenceCategory) preference;
|
PreferenceCategory pref = (PreferenceCategory) preference;
|
||||||
// Load conversations
|
// Load conversations
|
||||||
new AsyncTask<Void, Void, Void>() {
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground(Void... unused) {
|
|
||||||
mConversations = mBackend.getConversations(false).getList();
|
|
||||||
Collections.sort(mConversations, mConversationComparator);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
mConversations = mBackend.getConversations(false).getList();
|
||||||
protected void onPostExecute(Void unused) {
|
Collections.sort(mConversations, mConversationComparator);
|
||||||
if (mContext == null) {
|
|
||||||
return;
|
populateList(mConversations, pref);
|
||||||
}
|
|
||||||
populateList(mConversations, pref);
|
|
||||||
}
|
|
||||||
}.execute();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public abstract class ConversationListPreferenceController extends AbstractPrefe
|
|||||||
|
|
||||||
protected void populateList(List<ConversationChannelWrapper> conversations,
|
protected void populateList(List<ConversationChannelWrapper> conversations,
|
||||||
PreferenceGroup containerGroup) {
|
PreferenceGroup containerGroup) {
|
||||||
// TODO: if preference has children, compare with newly loaded list
|
containerGroup.setVisible(false);
|
||||||
containerGroup.removeAll();
|
containerGroup.removeAll();
|
||||||
if (conversations != null) {
|
if (conversations != null) {
|
||||||
populateConversations(conversations, containerGroup);
|
populateConversations(conversations, containerGroup);
|
||||||
@@ -72,11 +72,11 @@ public abstract class ConversationListPreferenceController extends AbstractPrefe
|
|||||||
if (containerGroup.getPreferenceCount() == 0) {
|
if (containerGroup.getPreferenceCount() == 0) {
|
||||||
containerGroup.setVisible(false);
|
containerGroup.setVisible(false);
|
||||||
} else {
|
} else {
|
||||||
containerGroup.setVisible(true);
|
|
||||||
Preference summaryPref = getSummaryPreference();
|
Preference summaryPref = getSummaryPreference();
|
||||||
if (summaryPref != null) {
|
if (summaryPref != null) {
|
||||||
containerGroup.addPreference(summaryPref);
|
containerGroup.addPreference(summaryPref);
|
||||||
}
|
}
|
||||||
|
containerGroup.setVisible(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,22 +67,9 @@ public class PriorityConversationsPreferenceController extends
|
|||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
PreferenceCategory pref = (PreferenceCategory) preference;
|
PreferenceCategory pref = (PreferenceCategory) preference;
|
||||||
// Load conversations
|
// Load conversations
|
||||||
new AsyncTask<Void, Void, Void>() {
|
mConversations = mBackend.getConversations(true).getList();
|
||||||
@Override
|
Collections.sort(mConversations, mConversationComparator);
|
||||||
protected Void doInBackground(Void... unused) {
|
|
||||||
mConversations = mBackend.getConversations(true).getList();
|
|
||||||
Collections.sort(mConversations, mConversationComparator);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Void unused) {
|
|
||||||
if (mContext == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
populateList(mConversations, pref);
|
|
||||||
}
|
|
||||||
}.execute();
|
|
||||||
|
|
||||||
|
populateList(mConversations, pref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,26 +104,14 @@ public class RecentConversationsPreferenceController extends AbstractPreferenceC
|
|||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
PreferenceCategory pref = (PreferenceCategory) preference;
|
PreferenceCategory pref = (PreferenceCategory) preference;
|
||||||
// Load conversations
|
// Load conversations
|
||||||
new AsyncTask<Void, Void, Void>() {
|
try {
|
||||||
@Override
|
mConversations = mPs.getRecentConversations().getList();
|
||||||
protected Void doInBackground(Void... unused) {
|
} catch (RemoteException e) {
|
||||||
try {
|
Slog.w(TAG, "Could get recents", e);
|
||||||
mConversations = mPs.getRecentConversations().getList();
|
}
|
||||||
} catch (RemoteException e) {
|
Collections.sort(mConversations, mConversationComparator);
|
||||||
Slog.w(TAG, "Could get recents", e);
|
|
||||||
}
|
|
||||||
Collections.sort(mConversations, mConversationComparator);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
populateList(mConversations, pref);
|
||||||
protected void onPostExecute(Void unused) {
|
|
||||||
if (mContext == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
populateList(mConversations, pref);
|
|
||||||
}
|
|
||||||
}.execute();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
47
src/com/android/settings/utils/LocaleUtils.java
Normal file
47
src/com/android/settings/utils/LocaleUtils.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.utils;
|
||||||
|
|
||||||
|
import android.icu.text.ListFormatter;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements some common methods to process with locales
|
||||||
|
*/
|
||||||
|
public class LocaleUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a character sequence concatenating the items with the localized comma.
|
||||||
|
*
|
||||||
|
* @param items items to be concatenated
|
||||||
|
*/
|
||||||
|
public static CharSequence getConcatenatedString(List<CharSequence> items) {
|
||||||
|
final ListFormatter listFormatter = ListFormatter.getInstance(Locale.getDefault());
|
||||||
|
final CharSequence lastItem = items.get(items.size() - 1);
|
||||||
|
items.add("fake last item");
|
||||||
|
|
||||||
|
// For English with "{0}, {1}, and {2}", the pattern is "{0}, {1}, and {2}".
|
||||||
|
// To get "{0}, {1}, {2}", we add a {fake item}, then the pattern result would be
|
||||||
|
// "{0}, {1}, {2} and {fake item}", then get the substring with the end index of the
|
||||||
|
// last item.
|
||||||
|
final String formatted = listFormatter.format(items);
|
||||||
|
return formatted.subSequence(0, TextUtils.indexOf(formatted, lastItem) + lastItem.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,8 +19,9 @@ package com.android.settings.accessibility;
|
|||||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
|
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
|
||||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR;
|
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR;
|
||||||
|
|
||||||
import static com.android.settings.accessibility.FloatingMenuOpacityPreferenceController.DEFAULT_OPACITY;
|
import static com.android.settings.accessibility.FloatingMenuTransparencyPreferenceController.DEFAULT_TRANSPARENCY;
|
||||||
import static com.android.settings.accessibility.FloatingMenuOpacityPreferenceController.PRECISION;
|
import static com.android.settings.accessibility.FloatingMenuTransparencyPreferenceController.MAXIMUM_TRANSPARENCY;
|
||||||
|
import static com.android.settings.accessibility.FloatingMenuTransparencyPreferenceController.PRECISION;
|
||||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||||
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
|
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
|
||||||
|
|
||||||
@@ -47,9 +48,9 @@ import org.mockito.junit.MockitoJUnit;
|
|||||||
import org.mockito.junit.MockitoRule;
|
import org.mockito.junit.MockitoRule;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
/** Tests for {@link FloatingMenuOpacityPreferenceController}. */
|
/** Tests for {@link FloatingMenuTransparencyPreferenceController}. */
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class FloatingMenuOpacityPreferenceControllerTest {
|
public class FloatingMenuTransparencyPreferenceControllerTest {
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public MockitoRule mocks = MockitoJUnit.rule();
|
public MockitoRule mocks = MockitoJUnit.rule();
|
||||||
@@ -58,12 +59,12 @@ public class FloatingMenuOpacityPreferenceControllerTest {
|
|||||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||||
@Mock
|
@Mock
|
||||||
private ContentResolver mContentResolver;
|
private ContentResolver mContentResolver;
|
||||||
private FloatingMenuOpacityPreferenceController mController;
|
private FloatingMenuTransparencyPreferenceController mController;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
when(mContext.getContentResolver()).thenReturn(mContentResolver);
|
when(mContext.getContentResolver()).thenReturn(mContentResolver);
|
||||||
mController = new FloatingMenuOpacityPreferenceController(mContext, "test_key");
|
mController = new FloatingMenuTransparencyPreferenceController(mContext, "test_key");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -95,10 +96,12 @@ public class FloatingMenuOpacityPreferenceControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getSliderPosition_putNormalOpacityValue_expectedValue() {
|
public void getSliderPosition_putNormalOpacityValue_expectedValue() {
|
||||||
|
final float transparencyValue = 0.65f;
|
||||||
Settings.Secure.putFloat(mContext.getContentResolver(),
|
Settings.Secure.putFloat(mContext.getContentResolver(),
|
||||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, 0.35f);
|
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY,
|
||||||
|
(MAXIMUM_TRANSPARENCY - transparencyValue));
|
||||||
|
|
||||||
assertThat(mController.getSliderPosition()).isEqualTo(35);
|
assertThat(mController.getSliderPosition()).isEqualTo((int) (transparencyValue * 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -106,17 +109,18 @@ public class FloatingMenuOpacityPreferenceControllerTest {
|
|||||||
Settings.Secure.putFloat(mContext.getContentResolver(),
|
Settings.Secure.putFloat(mContext.getContentResolver(),
|
||||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, 0.01f);
|
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, 0.01f);
|
||||||
|
|
||||||
final int defaultValue = Math.round(DEFAULT_OPACITY * PRECISION);
|
final int defaultValue = Math.round(DEFAULT_TRANSPARENCY * PRECISION);
|
||||||
assertThat(mController.getSliderPosition()).isEqualTo(defaultValue);
|
assertThat(mController.getSliderPosition()).isEqualTo(defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setSliderPosition_expectedValue() {
|
public void setSliderPosition_expectedValue() {
|
||||||
mController.setSliderPosition(27);
|
final float transparencyValue = 0.27f;
|
||||||
|
mController.setSliderPosition((int) (transparencyValue * 100));
|
||||||
|
|
||||||
final float value = Settings.Secure.getFloat(mContext.getContentResolver(),
|
final float value = Settings.Secure.getFloat(mContext.getContentResolver(),
|
||||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, -1);
|
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, -1);
|
||||||
assertThat(value).isEqualTo(0.27f);
|
assertThat(value).isEqualTo((MAXIMUM_TRANSPARENCY - transparencyValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -68,6 +68,7 @@ public class AdvancedBluetoothDetailsHeaderControllerTest {
|
|||||||
private static final int BATTERY_LEVEL_50 = 50;
|
private static final int BATTERY_LEVEL_50 = 50;
|
||||||
private static final String ICON_URI = "content://test.provider/icon.png";
|
private static final String ICON_URI = "content://test.provider/icon.png";
|
||||||
private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
|
private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
|
||||||
|
private static final String DEVICE_SUMMARY = "test summary";
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
|
||||||
@@ -133,7 +134,6 @@ public class AdvancedBluetoothDetailsHeaderControllerTest {
|
|||||||
View.GONE);
|
View.GONE);
|
||||||
assertThat(mLayoutPreference.findViewById(R.id.layout_middle).getVisibility()).isEqualTo(
|
assertThat(mLayoutPreference.findViewById(R.id.layout_middle).getVisibility()).isEqualTo(
|
||||||
View.VISIBLE);
|
View.VISIBLE);
|
||||||
assertBatteryLevel(mLayoutPreference.findViewById(R.id.layout_middle), BATTERY_LEVEL_MAIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -232,67 +232,18 @@ public class AdvancedBluetoothDetailsHeaderControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void refresh_underLowBatteryThreshold_showAlertIcon() {
|
public void refresh_connectedWatch_checkSummary() {
|
||||||
when(mBluetoothDevice.getMetadata(
|
when(mBluetoothDevice.getMetadata(
|
||||||
BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
|
BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
|
||||||
BluetoothDevice.DEVICE_TYPE_WATCH.getBytes());
|
BluetoothDevice.DEVICE_TYPE_WATCH.getBytes());
|
||||||
when(mBluetoothDevice.getMetadata(
|
|
||||||
BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn(
|
|
||||||
String.valueOf(BATTERY_LEVEL_5).getBytes());
|
|
||||||
when(mBluetoothDevice.getMetadata(
|
|
||||||
BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD)).thenReturn(
|
|
||||||
String.valueOf(LOW_BATTERY_LEVEL_THRESHOLD).getBytes());
|
|
||||||
when(mBluetoothDevice.getMetadata(
|
|
||||||
BluetoothDevice.METADATA_MAIN_CHARGING)).thenReturn(
|
|
||||||
String.valueOf(false).getBytes());
|
|
||||||
when(mCachedDevice.isConnected()).thenReturn(true);
|
when(mCachedDevice.isConnected()).thenReturn(true);
|
||||||
|
when(mCachedDevice.getConnectionSummary(/* shortSummary= */ true))
|
||||||
|
.thenReturn(DEVICE_SUMMARY);
|
||||||
|
|
||||||
mController.refresh();
|
mController.refresh();
|
||||||
|
|
||||||
assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_middle),
|
assertThat(((TextView) (mLayoutPreference.findViewById(R.id.entity_header_summary)))
|
||||||
R.drawable.ic_battery_alert_24dp);
|
.getText()).isEqualTo(DEVICE_SUMMARY);
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void refresh_underLowBatteryThresholdInCharging_showAlertIcon() {
|
|
||||||
when(mBluetoothDevice.getMetadata(
|
|
||||||
BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
|
|
||||||
BluetoothDevice.DEVICE_TYPE_WATCH.getBytes());
|
|
||||||
when(mBluetoothDevice.getMetadata(
|
|
||||||
BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn(
|
|
||||||
String.valueOf(BATTERY_LEVEL_5).getBytes());
|
|
||||||
when(mBluetoothDevice.getMetadata(
|
|
||||||
BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD)).thenReturn(
|
|
||||||
String.valueOf(LOW_BATTERY_LEVEL_THRESHOLD).getBytes());
|
|
||||||
when(mBluetoothDevice.getMetadata(
|
|
||||||
BluetoothDevice.METADATA_MAIN_CHARGING)).thenReturn(
|
|
||||||
String.valueOf(true).getBytes());
|
|
||||||
when(mCachedDevice.isConnected()).thenReturn(true);
|
|
||||||
|
|
||||||
mController.refresh();
|
|
||||||
|
|
||||||
assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_middle), /* resId= */-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void refresh_aboveLowBatteryThreshold_noAlertIcon() {
|
|
||||||
when(mBluetoothDevice.getMetadata(
|
|
||||||
BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
|
|
||||||
BluetoothDevice.DEVICE_TYPE_WATCH.getBytes());
|
|
||||||
when(mBluetoothDevice.getMetadata(
|
|
||||||
BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn(
|
|
||||||
String.valueOf(BATTERY_LEVEL_50).getBytes());
|
|
||||||
when(mBluetoothDevice.getMetadata(
|
|
||||||
BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD)).thenReturn(
|
|
||||||
String.valueOf(LOW_BATTERY_LEVEL_THRESHOLD).getBytes());
|
|
||||||
when(mBluetoothDevice.getMetadata(
|
|
||||||
BluetoothDevice.METADATA_MAIN_CHARGING)).thenReturn(
|
|
||||||
String.valueOf(false).getBytes());
|
|
||||||
when(mCachedDevice.isConnected()).thenReturn(true);
|
|
||||||
|
|
||||||
mController.refresh();
|
|
||||||
|
|
||||||
assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_middle), /* resId= */-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -1,206 +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.network;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.never;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.net.NetworkScoreManager;
|
|
||||||
import android.net.NetworkScorerAppData;
|
|
||||||
|
|
||||||
import androidx.preference.PreferenceManager;
|
|
||||||
import androidx.preference.PreferenceScreen;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settingslib.widget.RadioButtonPreference;
|
|
||||||
|
|
||||||
import com.google.android.collect.Lists;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.robolectric.RobolectricTestRunner;
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
|
||||||
public class NetworkScorerPickerTest {
|
|
||||||
|
|
||||||
private static final String TEST_SCORER_PACKAGE_1 = "Test Package 1";
|
|
||||||
private static final String TEST_SCORER_CLASS_1 = "Test Class 1";
|
|
||||||
private static final String TEST_SCORER_LABEL_1 = "Test Label 1";
|
|
||||||
private static final String TEST_SCORER_PACKAGE_2 = "Test Package 2";
|
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
@Mock
|
|
||||||
private NetworkScoreManager mNetworkScoreManager;
|
|
||||||
@Mock
|
|
||||||
private PreferenceScreen mPreferenceScreen;
|
|
||||||
|
|
||||||
private TestFragment mFragment;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
mContext = RuntimeEnvironment.application;
|
|
||||||
mFragment = new TestFragment(mContext, mPreferenceScreen, mNetworkScoreManager);
|
|
||||||
mFragment.onAttach(mContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOnRadioButtonClicked_success() {
|
|
||||||
RadioButtonPreference pref = new RadioButtonPreference(mContext);
|
|
||||||
pref.setKey(TEST_SCORER_PACKAGE_1);
|
|
||||||
when(mPreferenceScreen.getPreference(anyInt())).thenReturn(pref);
|
|
||||||
when(mPreferenceScreen.getPreferenceCount()).thenReturn(1);
|
|
||||||
when(mNetworkScoreManager.setActiveScorer(TEST_SCORER_PACKAGE_1)).thenReturn(true);
|
|
||||||
when(mNetworkScoreManager.getActiveScorerPackage()).thenReturn(TEST_SCORER_PACKAGE_2);
|
|
||||||
|
|
||||||
mFragment.onRadioButtonClicked(pref);
|
|
||||||
|
|
||||||
verify(mNetworkScoreManager).setActiveScorer(TEST_SCORER_PACKAGE_1);
|
|
||||||
assertThat(pref.isChecked()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOnRadioButtonClicked_currentScorer_doNothing() {
|
|
||||||
RadioButtonPreference pref = new RadioButtonPreference(mContext);
|
|
||||||
pref.setKey(TEST_SCORER_PACKAGE_1);
|
|
||||||
pref.setChecked(true);
|
|
||||||
when(mPreferenceScreen.getPreference(anyInt())).thenReturn(pref);
|
|
||||||
when(mPreferenceScreen.getPreferenceCount()).thenReturn(1);
|
|
||||||
when(mNetworkScoreManager.setActiveScorer(TEST_SCORER_PACKAGE_1)).thenReturn(true);
|
|
||||||
when(mNetworkScoreManager.getActiveScorerPackage()).thenReturn(TEST_SCORER_PACKAGE_1);
|
|
||||||
|
|
||||||
mFragment.onRadioButtonClicked(pref);
|
|
||||||
|
|
||||||
verify(mNetworkScoreManager, never()).setActiveScorer(any());
|
|
||||||
assertThat(pref.isChecked()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateCandidates_noValidScorers_nonePreference() {
|
|
||||||
when(mNetworkScoreManager.getAllValidScorers()).thenReturn(new ArrayList<>());
|
|
||||||
ArgumentCaptor<RadioButtonPreference> arg =
|
|
||||||
ArgumentCaptor.forClass(RadioButtonPreference.class);
|
|
||||||
|
|
||||||
mFragment.updateCandidates();
|
|
||||||
|
|
||||||
verify(mPreferenceScreen).addPreference(arg.capture());
|
|
||||||
assertThat(arg.getValue().getTitle())
|
|
||||||
.isEqualTo(mContext.getString(R.string.network_scorer_picker_none_preference));
|
|
||||||
assertThat(arg.getValue().isChecked()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateCandidates_validScorers_noActiveScorer() {
|
|
||||||
ComponentName scorer = new ComponentName(TEST_SCORER_PACKAGE_1, TEST_SCORER_CLASS_1);
|
|
||||||
NetworkScorerAppData scorerAppData = new NetworkScorerAppData(
|
|
||||||
0, scorer, TEST_SCORER_LABEL_1, null /* enableUseOpenWifiActivity */,
|
|
||||||
null /* networkAvailableNotificationChannelId */);
|
|
||||||
when(mNetworkScoreManager.getAllValidScorers()).thenReturn(
|
|
||||||
Lists.newArrayList(scorerAppData));
|
|
||||||
when(mNetworkScoreManager.getActiveScorerPackage()).thenReturn(null);
|
|
||||||
|
|
||||||
ArgumentCaptor<RadioButtonPreference> arg =
|
|
||||||
ArgumentCaptor.forClass(RadioButtonPreference.class);
|
|
||||||
|
|
||||||
mFragment.updateCandidates();
|
|
||||||
|
|
||||||
verify(mPreferenceScreen, times(2)).addPreference(arg.capture());
|
|
||||||
|
|
||||||
final RadioButtonPreference nonePref = arg.getAllValues().get(0);
|
|
||||||
assertThat(nonePref.getKey()).isNull();
|
|
||||||
assertThat(nonePref.isChecked()).isTrue();
|
|
||||||
|
|
||||||
final RadioButtonPreference testScorerPref = arg.getAllValues().get(1);
|
|
||||||
assertThat(testScorerPref.getTitle()).isEqualTo(TEST_SCORER_LABEL_1);
|
|
||||||
assertThat(testScorerPref.isChecked()).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateCandidates_validScorer() {
|
|
||||||
ComponentName scorer = new ComponentName(TEST_SCORER_PACKAGE_1, TEST_SCORER_CLASS_1);
|
|
||||||
NetworkScorerAppData scorerAppData = new NetworkScorerAppData(
|
|
||||||
0, scorer, TEST_SCORER_LABEL_1, null /* enableUseOpenWifiActivity */,
|
|
||||||
null /* networkAvailableNotificationChannelId */);
|
|
||||||
when(mNetworkScoreManager.getAllValidScorers()).thenReturn(
|
|
||||||
Lists.newArrayList(scorerAppData));
|
|
||||||
when(mNetworkScoreManager.getActiveScorerPackage()).thenReturn(TEST_SCORER_PACKAGE_1);
|
|
||||||
ArgumentCaptor<RadioButtonPreference> arg =
|
|
||||||
ArgumentCaptor.forClass(RadioButtonPreference.class);
|
|
||||||
|
|
||||||
mFragment.updateCandidates();
|
|
||||||
|
|
||||||
// The first preference added is the "none" preference and the second is the
|
|
||||||
// pref for the test scorer.
|
|
||||||
verify(mPreferenceScreen, times(2)).addPreference(arg.capture());
|
|
||||||
// Returns the last captured value which is expected to be the test scorer pref.
|
|
||||||
RadioButtonPreference pref = arg.getValue();
|
|
||||||
assertThat(pref.getTitle()).isEqualTo(TEST_SCORER_LABEL_1);
|
|
||||||
assertThat(pref.isChecked()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class TestFragment extends NetworkScorerPicker {
|
|
||||||
|
|
||||||
private final Context mContext;
|
|
||||||
private final PreferenceScreen mScreen;
|
|
||||||
private final PreferenceManager mPrefManager;
|
|
||||||
private final NetworkScoreManager mNetworkScoreManager;
|
|
||||||
|
|
||||||
public TestFragment(Context context, PreferenceScreen preferenceScreen,
|
|
||||||
NetworkScoreManager networkScoreManager) {
|
|
||||||
mContext = context;
|
|
||||||
mScreen = preferenceScreen;
|
|
||||||
mNetworkScoreManager = networkScoreManager;
|
|
||||||
mPrefManager = mock(PreferenceManager.class);
|
|
||||||
when(mPrefManager.getContext()).thenReturn(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Context getContext() {
|
|
||||||
return mContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PreferenceManager getPreferenceManager() {
|
|
||||||
return mPrefManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PreferenceScreen getPreferenceScreen() {
|
|
||||||
return mScreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
NetworkScoreManager createNetworkScorerManager(Context context) {
|
|
||||||
return mNetworkScoreManager;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2020 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.network;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.doReturn;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.spy;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.net.NetworkScoreManager;
|
|
||||||
import android.net.NetworkScorerAppData;
|
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
|
||||||
public class NetworkScorerPickerPreferenceControllerTest {
|
|
||||||
|
|
||||||
private static final String TEST_SCORER_PACKAGE = "Test Package";
|
|
||||||
private static final String TEST_SCORER_CLASS = "Test Class";
|
|
||||||
private static final String TEST_SCORER_LABEL = "Test Label";
|
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
@Mock
|
|
||||||
private NetworkScoreManager mNetworkScorer;
|
|
||||||
|
|
||||||
private NetworkScorerPickerPreferenceController mController;
|
|
||||||
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
|
||||||
doReturn(mNetworkScorer).when(mContext).getSystemService(Context.NETWORK_SCORE_SERVICE);
|
|
||||||
|
|
||||||
mController = new NetworkScorerPickerPreferenceController(mContext, "test_key");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIsAvailable_shouldAlwaysReturnTrue() {
|
|
||||||
assertThat(mController.isAvailable()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void updateState_preferenceSetSummaryAsActiveScorerLabel() {
|
|
||||||
|
|
||||||
ComponentName scorer = new ComponentName(TEST_SCORER_PACKAGE, TEST_SCORER_CLASS);
|
|
||||||
|
|
||||||
NetworkScorerAppData scorerAppData = new NetworkScorerAppData(
|
|
||||||
0, scorer, TEST_SCORER_LABEL, null /* enableUseOpenWifiActivity */,
|
|
||||||
null /* networkAvailableNotificationChannelId */);
|
|
||||||
|
|
||||||
when(mNetworkScorer.getAllValidScorers())
|
|
||||||
.thenReturn(Collections.singletonList(scorerAppData));
|
|
||||||
|
|
||||||
when(mNetworkScorer.getActiveScorer()).thenReturn(scorerAppData);
|
|
||||||
|
|
||||||
Preference preference = mock(Preference.class);
|
|
||||||
|
|
||||||
mController.updateState(preference);
|
|
||||||
|
|
||||||
verify(preference).setSummary(TEST_SCORER_LABEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void updateState_scorersAvailable_noActiveScorer_preferenceSetSummaryToNone() {
|
|
||||||
ComponentName scorer = new ComponentName(TEST_SCORER_PACKAGE, TEST_SCORER_CLASS);
|
|
||||||
NetworkScorerAppData scorerAppData = new NetworkScorerAppData(
|
|
||||||
0, scorer, TEST_SCORER_LABEL, null /* enableUseOpenWifiActivity */,
|
|
||||||
null /* networkAvailableNotificationChannelId */);
|
|
||||||
when(mNetworkScorer.getAllValidScorers())
|
|
||||||
.thenReturn(Collections.singletonList(scorerAppData));
|
|
||||||
when(mNetworkScorer.getActiveScorer()).thenReturn(null);
|
|
||||||
|
|
||||||
Preference preference = mock(Preference.class);
|
|
||||||
|
|
||||||
mController.updateState(preference);
|
|
||||||
|
|
||||||
Context context = ApplicationProvider.getApplicationContext();
|
|
||||||
|
|
||||||
verify(preference).setSummary(
|
|
||||||
resourceString("network_scorer_picker_none_preference"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void updateState_scorersAvailable_preferenceEnabled() {
|
|
||||||
ComponentName scorer = new ComponentName(TEST_SCORER_PACKAGE, TEST_SCORER_CLASS);
|
|
||||||
NetworkScorerAppData scorerAppData = new NetworkScorerAppData(
|
|
||||||
0, scorer, TEST_SCORER_LABEL, null /* enableUseOpenWifiActivity */,
|
|
||||||
null /* networkAvailableNotificationChannelId */);
|
|
||||||
when(mNetworkScorer.getAllValidScorers())
|
|
||||||
.thenReturn(Collections.singletonList(scorerAppData));
|
|
||||||
|
|
||||||
Preference preference = mock(Preference.class);
|
|
||||||
|
|
||||||
mController.updateState(preference);
|
|
||||||
|
|
||||||
verify(preference).setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void updateState_noScorersAvailable_preferenceDisabled() {
|
|
||||||
when(mNetworkScorer.getAllValidScorers())
|
|
||||||
.thenReturn(Collections.emptyList());
|
|
||||||
Preference preference = mock(Preference.class);
|
|
||||||
|
|
||||||
mController.updateState(preference);
|
|
||||||
|
|
||||||
verify(preference).setEnabled(false);
|
|
||||||
verify(preference).setSummary(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int resourceId(String type, String name) {
|
|
||||||
return mContext.getResources().getIdentifier(name, type, mContext.getPackageName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String resourceString(String name) {
|
|
||||||
return mContext.getResources().getString(resourceId("string", name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user