Apply SettingsLib SeekBarPreference to Settings

Bug: 176818438
Test: robotest

Change-Id: I219878716457ce4bb7cad251bccf5d50d93030a5
This commit is contained in:
Edgar Wang
2020-11-30 18:07:24 +08:00
parent 4abbe80385
commit d6b5bbb5cb
40 changed files with 149 additions and 1264 deletions

View File

@@ -1,47 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<!-- Layout used by BatterySaverScheduleSeekBarController for the seekbar widget. -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="6dp"
android:gravity="center_vertical"
android:orientation="vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:layout_marginStart="18dp"
android:singleLine="true"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/textColorPrimary" />
<com.android.settings.widget.DefaultIndicatorSeekBar
android:id="@*android:id/seekbar"
style="@android:style/Widget.Material.SeekBar.Discrete"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginStart="18dp"
android:layout_marginEnd="9dp" />
</LinearLayout>

View File

@@ -1,79 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2019 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:gravity="center_vertical"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="56dp"
android:paddingEnd="8dp"
android:paddingTop="16dp"
android:paddingBottom="8dp">
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_alignParentTop="true"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:singleLine="true"
android:textAppearance="@android:style/TextAppearance.Material.Subhead"
android:textColor="?android:attr/textColorPrimary" />
<SeekBar
android:id="@*android:id/seekbar"
android:layout_below="@android:id/title"
android:layout_gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginTop="-20dp"
android:layout_marginBottom="-28dp"
style="@android:style/Widget.Material.SeekBar.Discrete" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@*android:id/seekbar"
android:paddingBottom="8dp"
android:orientation="horizontal">
<TextView
android:id="@android:id/text1"
android:layout_marginStart="16dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="start|top"
android:gravity="start"
android:layout_weight="1"/>
<TextView
android:id="@android:id/text2"
android:layout_marginEnd="16dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="end|top"
android:gravity="end"
android:layout_weight="1"/>
</LinearLayout>
</RelativeLayout>

View File

@@ -25,28 +25,13 @@
android:clickable="false"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/icon_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="44dp"
android:gravity="start|center_vertical"
android:orientation="horizontal"
android:paddingEnd="12dp"
android:paddingTop="4dp"
android:paddingBottom="4dp">
<com.android.internal.widget.PreferenceImageView
android:id="@android:id/icon"
android:layout_width="24dp"
android:layout_height="24dp"/>
</LinearLayout>
<include layout="@layout/settingslib_icon_frame"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
android:paddingTop="16dp">
<LinearLayout
android:layout_width="match_parent"

View File

@@ -1,63 +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.
-->
<!-- Layout used by SeekBarPreference for the seekbar widget style. -->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:paddingStart="56dp"
android:paddingEnd="8dp"
android:singleLine="true"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/textColorPrimary" />
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@android:id/title"
android:layout_below="@android:id/title"
android:maxLines="4"
android:paddingStart="56dp"
android:paddingEnd="8dp"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary" />
<com.android.settings.widget.DefaultIndicatorSeekBar
android:id="@*android:id/seekbar"
style="@android:style/Widget.Material.SeekBar.Discrete"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_alignParentEnd="true"
android:layout_below="@android:id/summary"
android:paddingStart="56dp"
android:paddingEnd="12dp" />
</RelativeLayout>

View File

@@ -157,13 +157,6 @@
<attr name="textOff" format="reference" />
</declare-styleable>
<!-- For LabeledSeekBarPreference -->
<declare-styleable name="LabeledSeekBarPreference">
<attr name="textStart" format="reference" />
<attr name="textEnd" format="reference" />
<attr name="tickMark" format="reference" />
</declare-styleable>
<declare-styleable name="TintDrawable">
<attr name="android:tint" />
<attr name="android:drawable" />

View File

@@ -23,7 +23,6 @@
<item name="apnPreferenceStyle">@style/ApnPreference</item>
<item name="cardPreferenceStyle">@style/CardPreference</item>
<item name="slicePreferenceStyle">@style/SlicePreference</item>
<item name="seekBarPreferenceStyle">@style/SettingsSeekBarPreference</item>
<item name="twoStateButtonPreferenceStyle">@style/TwoStateButtonPreference</item>
<item name="preferenceFragmentCompatStyle">@style/SettingsPreferenceFragmentStyle</item>
</style>
@@ -44,10 +43,6 @@
<item name="android:layout">@layout/slice_preference_layout</item>
</style>
<style name="SettingsSeekBarPreference" parent="@style/Preference.Material">
<item name="android:layout">@layout/preference_widget_seekbar_settings</item>
</style>
<style name="SyncSwitchPreference" parent="@style/SettingsSwitchPreference.SettingsLib">
<item name="android:widgetLayout">@layout/preference_widget_sync_toggle</item>
</style>

View File

@@ -53,7 +53,7 @@
android:persistent="false"
settings:controller="com.android.settings.accessibility.FloatingMenuFadePreferenceController"/>
<com.android.settings.widget.SeekBarPreference
<com.android.settingslib.RestrictedSeekBarPreference
android:key="accessibility_button_opacity"
android:title="@string/accessibility_button_opacity_title"
android:persistent="false"

View File

@@ -42,7 +42,7 @@
android:persistent="false"
android:title="@string/back_sensitivity_dialog_title">
<com.android.settings.widget.LabeledSeekBarPreference
<com.android.settingslib.widget.LabeledSeekBarPreference
android:key="gesture_left_back_sensitivity"
android:title="@string/left_edge"
android:max="2"
@@ -50,7 +50,7 @@
settings:textStart="@string/low_label"
settings:textEnd="@string/high_label"/>
<com.android.settings.widget.LabeledSeekBarPreference
<com.android.settingslib.widget.LabeledSeekBarPreference
android:key="gesture_right_back_sensitivity"
android:title="@string/right_edge"
android:max="2"

View File

@@ -52,7 +52,7 @@
android:title="@string/night_display_end_time_title"
settings:controller="com.android.settings.display.NightDisplayCustomEndTimePreferenceController"/>
<com.android.settings.widget.SeekBarPreference
<com.android.settingslib.RestrictedSeekBarPreference
android:key="night_display_temperature"
android:title="@string/night_display_temperature_title"
settings:keywords="@string/keywords_display_night_display"

View File

@@ -20,7 +20,7 @@
android:persistent="false"
android:title="@string/reduce_bright_colors_preference_title">
<com.android.settings.widget.SeekBarPreference
<com.android.settingslib.RestrictedSeekBarPreference
android:key="rbc_intensity"
android:persistent="false"
android:title="@string/reduce_bright_colors_intensity_preference_title"/>

View File

@@ -34,14 +34,14 @@
<!-- The max value for seek bars here should be kept in sync
with the max value specified in TextToSpeechSettings class. -->
<com.android.settings.widget.SeekBarPreference
<com.android.settingslib.RestrictedSeekBarPreference
android:key="tts_default_rate"
android:title="@string/tts_default_rate_title"
android:summary="@string/tts_default_rate_summary"
android:defaultValue="50"
android:max="600"/>
<com.android.settings.widget.SeekBarPreference
<com.android.settingslib.RestrictedSeekBarPreference
android:key="tts_default_pitch"
android:title="@string/tts_default_pitch_title"
android:summary="@string/tts_default_pitch_summary"

View File

@@ -39,13 +39,17 @@ import androidx.appcompat.app.AlertDialog.Builder;
import androidx.preference.ListPreferenceDialogFragmentCompat;
import androidx.preference.PreferenceViewHolder;
import com.android.settingslib.Restrictable;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreferenceHelper;
import java.util.ArrayList;
import java.util.List;
public class RestrictedListPreference extends CustomListPreference {
/**
* List preference that can be disabled by a device admin using a user restriction.
*/
public class RestrictedListPreference extends CustomListPreference implements Restrictable {
private final RestrictedPreferenceHelper mHelper;
private final List<RestrictedItem> mRestrictedItems = new ArrayList<>();
private boolean mRequiresActiveUnlockedProfile = false;
@@ -63,6 +67,10 @@ public class RestrictedListPreference extends CustomListPreference {
mHelper = new RestrictedPreferenceHelper(context, this, attrs);
}
public RestrictedListPreference(Context context) {
this(context, /* attrs= */ null);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
@@ -107,14 +115,14 @@ public class RestrictedListPreference extends CustomListPreference {
super.setEnabled(enabled);
}
public void setDisabledByAdmin(EnforcedAdmin admin) {
if (mHelper.setDisabledByAdmin(admin)) {
notifyChanged();
}
@Override
public RestrictedPreferenceHelper getHelper() {
return mHelper;
}
public boolean isDisabledByAdmin() {
return mHelper.isDisabledByAdmin();
@Override
public void notifyPreferenceChanged() {
notifyChanged();
}
public void setRequiresActiveUnlockedProfile(boolean reqState) {

View File

@@ -17,23 +17,19 @@
package com.android.settings.accessibility;
import android.content.Context;
import android.media.AudioSystem;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.SeekBar;
import androidx.core.content.res.TypedArrayUtils;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.RestrictedSeekBarPreference;
/** A slider preference that directly controls audio balance **/
public class BalanceSeekBarPreference extends SeekBarPreference {
public class BalanceSeekBarPreference extends RestrictedSeekBarPreference {
private static final int BALANCE_CENTER_VALUE = 100;
private static final int BALANCE_MAX_VALUE = 200;

View File

@@ -28,10 +28,10 @@ import androidx.annotation.VisibleForTesting;
import androidx.preference.PreferenceScreen;
import com.android.settings.core.SliderPreferenceController;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.widget.SeekBarPreference;
/** Preference controller that controls the transparency seekbar in accessibility button page. */
public class FloatingMenuTransparencyPreferenceController extends SliderPreferenceController

View File

@@ -23,7 +23,7 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.core.SliderPreferenceController;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.widget.SeekBarPreference;
/** PreferenceController for feature intensity. */
public class ReduceBrightColorsIntensityPreferenceController extends SliderPreferenceController {

View File

@@ -34,9 +34,9 @@ import androidx.preference.SwitchPreference;
import com.android.internal.accessibility.AccessibilityShortcutController;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.SeekBarPreference;
import com.android.settings.widget.SettingsMainSwitchPreference;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.widget.SeekBarPreference;
import java.util.ArrayList;
import java.util.List;

View File

@@ -27,9 +27,11 @@ import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
import androidx.preference.Preference;
import com.android.settings.AccessiblePreferenceCategory;
import com.android.settingslib.Restrictable;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import java.util.ArrayList;
@@ -42,34 +44,74 @@ public class AccountRestrictionHelper {
}
/**
* Configure the UI of the preference by checking user restriction.
* @param preference The preference we are configuring.
* @param userRestriction The user restriction related to the preference.
* @param userId The user that we retrieve user restriction of.
* Checks if the account should be shown based on the required authorities for the account type
*
* @param authorities given authority that is passed as activity extra
* @param auths list of authorities for particular account type
* @return true if the activity has the required authority to show the account
*/
public void enforceRestrictionOnPreference(RestrictedPreference preference,
String userRestriction, @UserIdInt int userId) {
public static boolean showAccount(String[] authorities, ArrayList<String> auths) {
boolean showAccount = true;
if (authorities != null && auths != null) {
showAccount = false;
for (String requestedAuthority : authorities) {
if (auths.contains(requestedAuthority)) {
return true;
}
}
}
return showAccount;
}
/**
* Configure the UI of the preference by checking user restriction.
*
* @param preference The preference we are configuring.
* @param userRestriction The user restriction related to the preference.
* @param userId The user that we retrieve user restriction of.
*/
public void enforceRestrictionOnPreference(Preference preference,
String userRestriction, @UserIdInt int userId) {
if (preference == null) {
return;
}
if (!(preference instanceof Restrictable)) {
return;
}
final Restrictable restrictedPreference = (Restrictable) preference;
if (hasBaseUserRestriction(userRestriction, userId)) {
if (userRestriction.equals(DISALLOW_REMOVE_MANAGED_PROFILE)
&& isOrganizationOwnedDevice()) {
preference.setDisabledByAdmin(getEnforcedAdmin(userRestriction, userId));
restrictedPreference.setDisabledByAdmin(getEnforcedAdmin(userRestriction, userId));
} else {
preference.setEnabled(false);
}
} else {
preference.checkRestrictionAndSetDisabled(userRestriction, userId);
restrictedPreference.checkRestrictionAndSetDisabled(userRestriction, userId);
}
}
/**
* Check if the system has set the user restriction.
* @param userRestriction The user restriction.
* @param userId The user that we retrieve user restriction of.
* @return {@code true} if set restriction.
*/
public boolean hasBaseUserRestriction(String userRestriction, @UserIdInt int userId) {
return RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext, userRestriction,
userId);
}
private boolean isOrganizationOwnedDevice() {
/**
* Apps can use this method to find out if the device was provisioned as
* organization-owend device.
*
* @return {@code true} if the device was provisioned as organization-owned device,
* {@code false} otherwise.
*/
public boolean isOrganizationOwnedDevice() {
final DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
Context.DEVICE_POLICY_SERVICE);
if (dpm == null) {
@@ -78,7 +120,13 @@ public class AccountRestrictionHelper {
return dpm.isOrganizationOwnedDeviceWithManagedProfile();
}
private EnforcedAdmin getEnforcedAdmin(String userRestriction, int userId) {
/**
* Get the restriction enforced by admin
* @param userRestriction The user restriction.
* @param userId The user that we retrieve user restriction of.
* @return {EnforcedAdmin}
*/
public EnforcedAdmin getEnforcedAdmin(String userRestriction, int userId) {
final DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
Context.DEVICE_POLICY_SERVICE);
if (dpm == null) {
@@ -107,23 +155,4 @@ public class AccountRestrictionHelper {
public AccessiblePreferenceCategory createAccessiblePreferenceCategory(Context context) {
return new AccessiblePreferenceCategory(context);
}
/**
* Checks if the account should be shown based on the required authorities for the account type
* @param authorities given authority that is passed as activity extra
* @param auths list of authorities for particular account type
* @return true if the activity has the required authority to show the account
*/
public static boolean showAccount(String[] authorities, ArrayList<String> auths) {
boolean showAccount = true;
if (authorities != null && auths != null) {
showAccount = false;
for (String requestedAuthority : authorities) {
if (auths.contains(requestedAuthority)) {
return true;
}
}
}
return showAccount;
}
}

View File

@@ -19,6 +19,7 @@ import android.content.Context;
import androidx.preference.Preference;
import com.android.settings.slices.SliceData;
import com.android.settingslib.widget.SeekBarPreference;
public abstract class SliderPreferenceController extends BasePreferenceController implements
Preference.OnPreferenceChangeListener {
@@ -34,12 +35,10 @@ public abstract class SliderPreferenceController extends BasePreferenceControlle
@Override
public void updateState(Preference preference) {
if (preference instanceof com.android.settings.widget.SeekBarPreference) {
((com.android.settings.widget.SeekBarPreference) preference)
.setProgress(getSliderPosition());
if (preference instanceof SeekBarPreference) {
((SeekBarPreference) preference).setProgress(getSliderPosition());
} else if (preference instanceof androidx.preference.SeekBarPreference) {
((androidx.preference.SeekBarPreference) preference)
.setValue(getSliderPosition());
((androidx.preference.SeekBarPreference) preference).setValue(getSliderPosition());
}
}

View File

@@ -24,14 +24,14 @@ import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.Restrictable;
import com.android.settingslib.RestrictedPreferenceHelper;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.widget.AppSwitchPreference;
public class UnrestrictedDataAccessPreference extends AppSwitchPreference implements
DataSaverBackend.Listener {
DataSaverBackend.Listener, Restrictable {
private final ApplicationsState mApplicationsState;
private final AppEntry mEntry;
@@ -159,12 +159,14 @@ public class UnrestrictedDataAccessPreference extends AppSwitchPreference implem
return mEntry;
}
public boolean isDisabledByAdmin() {
return mHelper.isDisabledByAdmin();
@Override
public RestrictedPreferenceHelper getHelper() {
return mHelper;
}
public void setDisabledByAdmin(EnforcedAdmin admin) {
mHelper.setDisabledByAdmin(admin);
@Override
public void notifyPreferenceChanged() {
notifyChanged();
}
// Sets UI state based on allowlist/denylist status.

View File

@@ -24,7 +24,7 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.core.SliderPreferenceController;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.widget.SeekBarPreference;
public class NightDisplayIntensityPreferenceController extends SliderPreferenceController {

View File

@@ -28,7 +28,7 @@ import androidx.preference.PreferenceScreen;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.widget.SeekBarPreference;
/**
* Responds to user actions in the Settings > Battery > Set a Schedule Screen for the seekbar.
@@ -55,7 +55,6 @@ public class BatterySaverScheduleSeekBarController implements
public BatterySaverScheduleSeekBarController(Context context) {
mContext = context;
mSeekBarPreference = new SeekBarPreference(context);
mSeekBarPreference.setLayoutResource(R.layout.battery_saver_schedule_percentage_seekbar);
mSeekBarPreference.setOnPreferenceChangeListener(this);
mSeekBarPreference.setContinuousUpdates(true);
mSeekBarPreference.setMax(MAX_SEEKBAR_VALUE);

View File

@@ -27,9 +27,9 @@ import android.view.WindowManager;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.LabeledSeekBarPreference;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.widget.LabeledSeekBarPreference;
import com.android.settingslib.widget.SeekBarPreference;
/**
* A fragment to include all the settings related to Gesture Navigation mode.

View File

@@ -27,7 +27,7 @@ import androidx.preference.Preference;
import com.android.settings.accounts.AccountRestrictionHelper;
import com.android.settings.core.SliderPreferenceController;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.Restrictable;
/**
* Base class for preference controller that handles preference that enforce adjust volume
@@ -51,10 +51,10 @@ public abstract class AdjustVolumeRestrictedPreferenceController extends
@Override
public void updateState(Preference preference) {
if (!(preference instanceof RestrictedPreference)) {
if (!(preference instanceof Restrictable)) {
return;
}
mHelper.enforceRestrictionOnPreference((RestrictedPreference) preference,
mHelper.enforceRestrictionOnPreference(preference,
UserManager.DISALLOW_ADJUST_VOLUME, UserHandle.myUserId());
}

View File

@@ -32,12 +32,12 @@ import androidx.annotation.VisibleForTesting;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.RestrictedSeekBarPreference;
import java.util.Objects;
/** A slider preference that directly controls an audio stream volume (no dialog) **/
public class VolumeSeekBarPreference extends SeekBarPreference {
public class VolumeSeekBarPreference extends RestrictedSeekBarPreference {
private static final String TAG = "VolumeSeekBarPreference";
protected SeekBar mSeekBar;

View File

@@ -22,7 +22,6 @@ import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
@@ -33,13 +32,13 @@ import androidx.preference.PreferenceViewHolder;
import com.android.settings.Utils;
import com.android.settingslib.R;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.Restrictable;
import com.android.settingslib.RestrictedPreferenceHelper;
/**
* A tri-state preference allowing a user to specify what gets to bubble.
*/
public class BubblePreference extends Preference implements View.OnClickListener {
public class BubblePreference extends Preference implements View.OnClickListener, Restrictable {
RestrictedPreferenceHelper mHelper;
private int mSelectedPreference;
@@ -81,12 +80,6 @@ public class BubblePreference extends Preference implements View.OnClickListener
return mSelectedPreference;
}
public void setDisabledByAdmin(RestrictedLockUtils.EnforcedAdmin admin) {
if (mHelper.setDisabledByAdmin(admin)) {
notifyChanged();
}
}
public void setSelectedVisibility(boolean visible) {
mSelectedVisible = visible;
notifyChanged();
@@ -149,6 +142,16 @@ public class BubblePreference extends Preference implements View.OnClickListener
mBubbleNoneButton.setSelected(mContext, selected == BUBBLE_PREFERENCE_NONE);
}
@Override
public RestrictedPreferenceHelper getHelper() {
return mHelper;
}
@Override
public void notifyPreferenceChanged() {
notifyChanged();
}
private class ButtonViewHolder {
private View mView;
private ImageView mImageView;

View File

@@ -49,9 +49,9 @@ import com.android.settings.Utils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.GearPreference;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.widget.ActionButtonsPreference;
import com.android.settingslib.widget.SeekBarPreference;
import java.text.Collator;
import java.util.ArrayList;

View File

@@ -1,89 +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.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.SeekBar;
public class DefaultIndicatorSeekBar extends SeekBar {
private int mDefaultProgress = -1;
public DefaultIndicatorSeekBar(Context context) {
super(context);
}
public DefaultIndicatorSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DefaultIndicatorSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public DefaultIndicatorSeekBar(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
/**
* N.B. Only draws the default indicator tick mark, NOT equally spaced tick marks.
*/
@Override
protected void drawTickMarks(Canvas canvas) {
if (isEnabled() && mDefaultProgress <= getMax() && mDefaultProgress >= getMin()) {
final Drawable defaultIndicator = getTickMark();
// Adjust the drawable's bounds to center it at the point where it's drawn.
final int w = defaultIndicator.getIntrinsicWidth();
final int h = defaultIndicator.getIntrinsicHeight();
final int halfW = w >= 0 ? w / 2 : 1;
final int halfH = h >= 0 ? h / 2 : 1;
defaultIndicator.setBounds(-halfW, -halfH, halfW, halfH);
// This mimics the computation of the thumb position, to get the true "default."
final int availableWidth = getWidth() - mPaddingLeft - mPaddingRight;
final int range = getMax() - getMin();
final float scale = range > 0f ? mDefaultProgress / (float) range : 0f;
final int offset = (int) ((scale * availableWidth) + 0.5f);
final int indicatorPosition = isLayoutRtl() && getMirrorForRtl()
? availableWidth - offset + mPaddingRight : offset + mPaddingLeft;
final int saveCount = canvas.save();
canvas.translate(indicatorPosition, getHeight() / 2);
defaultIndicator.draw(canvas);
canvas.restoreToCount(saveCount);
}
}
/**
* N.B. This sets the default *unadjusted* progress, i.e. in the SeekBar's [0 - max] terms.
*/
public void setDefaultProgress(int defaultProgress) {
if (mDefaultProgress != defaultProgress) {
mDefaultProgress = defaultProgress;
invalidate();
}
}
public int getDefaultProgress() {
return mDefaultProgress;
}
}

View File

@@ -1,94 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.core.content.res.TypedArrayUtils;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
/** A slider preference with left and right labels **/
public class LabeledSeekBarPreference extends SeekBarPreference {
private final int mTextStartId;
private final int mTextEndId;
private final int mTickMarkId;
private OnPreferenceChangeListener mStopListener;
public LabeledSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setLayoutResource(R.layout.preference_labeled_slider);
final TypedArray styledAttrs = context.obtainStyledAttributes(attrs,
R.styleable.LabeledSeekBarPreference);
mTextStartId = styledAttrs.getResourceId(
R.styleable.LabeledSeekBarPreference_textStart,
R.string.summary_placeholder);
mTextEndId = styledAttrs.getResourceId(
R.styleable.LabeledSeekBarPreference_textEnd,
R.string.summary_placeholder);
mTickMarkId = styledAttrs.getResourceId(
R.styleable.LabeledSeekBarPreference_tickMark, /* defValue= */ 0);
styledAttrs.recycle();
}
public LabeledSeekBarPreference(Context context, AttributeSet attrs) {
this(context, attrs, TypedArrayUtils.getAttr(context,
androidx.preference.R.attr.seekBarPreferenceStyle,
com.android.internal.R.attr.seekBarPreferenceStyle), 0);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
final TextView startText = (TextView) holder.findViewById(android.R.id.text1);
final TextView endText = (TextView) holder.findViewById(android.R.id.text2);
startText.setText(mTextStartId);
endText.setText(mTextEndId);
if (mTickMarkId != 0) {
final Drawable tickMark = getContext().getDrawable(mTickMarkId);
final SeekBar seekBar = (SeekBar) holder.findViewById(
com.android.internal.R.id.seekbar);
seekBar.setTickMark(tickMark);
}
}
public void setOnPreferenceChangeStopListener(OnPreferenceChangeListener listener) {
mStopListener = listener;
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
super.onStopTrackingTouch(seekBar);
if (mStopListener != null) {
mStopListener.onPreferenceChange(this, seekBar.getProgress());
}
}
}

View File

@@ -26,7 +26,7 @@ import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.Restrictable;
import com.android.settingslib.RestrictedPreferenceHelper;
import com.android.settingslib.widget.AppPreference;
@@ -35,7 +35,7 @@ import com.android.settingslib.widget.AppPreference;
* {@link com.android.settingslib.RestrictedPreferenceHelper}.
* Used to show policy transparency on {@link AppPreference}.
*/
public class RestrictedAppPreference extends AppPreference {
public class RestrictedAppPreference extends AppPreference implements Restrictable {
private RestrictedPreferenceHelper mHelper;
private String userRestriction;
@@ -85,14 +85,14 @@ public class RestrictedAppPreference extends AppPreference {
super.setEnabled(enabled);
}
public void setDisabledByAdmin(RestrictedLockUtils.EnforcedAdmin admin) {
if (mHelper.setDisabledByAdmin(admin)) {
notifyChanged();
}
@Override
public RestrictedPreferenceHelper getHelper() {
return mHelper;
}
public boolean isDisabledByAdmin() {
return mHelper.isDisabledByAdmin();
@Override
public void notifyPreferenceChanged() {
notifyChanged();
}
public void useAdminDisabledSummary(boolean useSummary) {
@@ -111,12 +111,4 @@ public class RestrictedAppPreference extends AppPreference {
}
mHelper.checkRestrictionAndSetDisabled(userRestriction, UserHandle.myUserId());
}
public void checkRestrictionAndSetDisabled(String userRestriction) {
mHelper.checkRestrictionAndSetDisabled(userRestriction, UserHandle.myUserId());
}
public void checkRestrictionAndSetDisabled(String userRestriction, int userId) {
mHelper.checkRestrictionAndSetDisabled(userRestriction, userId);
}
}

View File

@@ -1,436 +0,0 @@
/*
* Copyright (C) 2011 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.widget;
import static android.view.HapticFeedbackConstants.CLOCK_TICK;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import androidx.core.content.res.TypedArrayUtils;
import androidx.preference.PreferenceViewHolder;
import com.android.settingslib.RestrictedPreference;
/**
* Based on android.preference.SeekBarPreference, but uses support preference as base.
*/
public class SeekBarPreference extends RestrictedPreference
implements OnSeekBarChangeListener, View.OnKeyListener {
public static final int HAPTIC_FEEDBACK_MODE_NONE = 0;
public static final int HAPTIC_FEEDBACK_MODE_ON_TICKS = 1;
public static final int HAPTIC_FEEDBACK_MODE_ON_ENDS = 2;
private int mProgress;
private int mMax;
private int mMin;
private boolean mTrackingTouch;
private boolean mContinuousUpdates;
private int mHapticFeedbackMode = HAPTIC_FEEDBACK_MODE_NONE;
private int mDefaultProgress = -1;
private SeekBar mSeekBar;
private boolean mShouldBlink;
private int mAccessibilityRangeInfoType = AccessibilityNodeInfo.RangeInfo.RANGE_TYPE_INT;
private CharSequence mSeekBarContentDescription;
private CharSequence mSeekBarStateDescription;
public SeekBarPreference(
Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.ProgressBar, defStyleAttr, defStyleRes);
setMax(a.getInt(com.android.internal.R.styleable.ProgressBar_max, mMax));
setMin(a.getInt(com.android.internal.R.styleable.ProgressBar_min, mMin));
a.recycle();
a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.SeekBarPreference, defStyleAttr, defStyleRes);
final int layoutResId = a.getResourceId(
com.android.internal.R.styleable.SeekBarPreference_layout,
com.android.internal.R.layout.preference_widget_seekbar);
a.recycle();
a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.Preference, defStyleAttr, defStyleRes);
final boolean isSelectable = a.getBoolean(
com.android.settings.R.styleable.Preference_android_selectable, false);
setSelectable(isSelectable);
a.recycle();
setLayoutResource(layoutResId);
}
public SeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public SeekBarPreference(Context context, AttributeSet attrs) {
this(context, attrs, TypedArrayUtils.getAttr(context,
androidx.preference.R.attr.seekBarPreferenceStyle,
com.android.internal.R.attr.seekBarPreferenceStyle));
}
public SeekBarPreference(Context context) {
this(context, null);
}
public void setShouldBlink(boolean shouldBlink) {
mShouldBlink = shouldBlink;
notifyChanged();
}
@Override
public boolean isSelectable() {
if(isDisabledByAdmin()) {
return true;
} else {
return super.isSelectable();
}
}
@Override
public void onBindViewHolder(PreferenceViewHolder view) {
super.onBindViewHolder(view);
view.itemView.setOnKeyListener(this);
mSeekBar = (SeekBar) view.findViewById(
com.android.internal.R.id.seekbar);
mSeekBar.setOnSeekBarChangeListener(this);
mSeekBar.setMax(mMax);
mSeekBar.setMin(mMin);
mSeekBar.setProgress(mProgress);
mSeekBar.setEnabled(isEnabled());
final CharSequence title = getTitle();
if (!TextUtils.isEmpty(mSeekBarContentDescription)) {
mSeekBar.setContentDescription(mSeekBarContentDescription);
} else if (!TextUtils.isEmpty(title)) {
mSeekBar.setContentDescription(title);
}
if (!TextUtils.isEmpty(mSeekBarStateDescription)) {
mSeekBar.setStateDescription(mSeekBarStateDescription);
}
if (mSeekBar instanceof DefaultIndicatorSeekBar) {
((DefaultIndicatorSeekBar) mSeekBar).setDefaultProgress(mDefaultProgress);
}
if (mShouldBlink) {
View v = view.itemView;
v.post(() -> {
if (v.getBackground() != null) {
final int centerX = v.getWidth() / 2;
final int centerY = v.getHeight() / 2;
v.getBackground().setHotspot(centerX, centerY);
}
v.setPressed(true);
v.setPressed(false);
mShouldBlink = false;
});
}
mSeekBar.setAccessibilityDelegate(new View.AccessibilityDelegate() {
@Override
public void onInitializeAccessibilityNodeInfo(View view, AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(view, info);
// Update the range info with the correct type
AccessibilityNodeInfo.RangeInfo rangeInfo = info.getRangeInfo();
if (rangeInfo != null) {
info.setRangeInfo(AccessibilityNodeInfo.RangeInfo.obtain(
mAccessibilityRangeInfoType, rangeInfo.getMin(),
rangeInfo.getMax(), rangeInfo.getCurrent()));
}
}
});
}
@Override
public CharSequence getSummary() {
return null;
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
setProgress(restoreValue ? getPersistedInt(mProgress)
: (Integer) defaultValue);
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getInt(index, 0);
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() != KeyEvent.ACTION_DOWN) {
return false;
}
SeekBar seekBar = (SeekBar) v.findViewById(com.android.internal.R.id.seekbar);
if (seekBar == null) {
return false;
}
return seekBar.onKeyDown(keyCode, event);
}
public void setMax(int max) {
if (max != mMax) {
mMax = max;
notifyChanged();
}
}
public void setMin(int min) {
if (min != mMin) {
mMin = min;
notifyChanged();
}
}
public int getMax() {
return mMax;
}
public int getMin() {
return mMin;
}
public void setProgress(int progress) {
setProgress(progress, true);
}
/**
* Sets the progress point to draw a single tick mark representing a default value.
*/
public void setDefaultProgress(int defaultProgress) {
if (mDefaultProgress != defaultProgress) {
mDefaultProgress = defaultProgress;
if (mSeekBar instanceof DefaultIndicatorSeekBar) {
((DefaultIndicatorSeekBar) mSeekBar).setDefaultProgress(mDefaultProgress);
}
}
}
/**
* When {@code continuousUpdates} is true, update the persisted setting immediately as the thumb
* is dragged along the SeekBar. Otherwise, only update the value of the setting when the thumb
* is dropped.
*/
public void setContinuousUpdates(boolean continuousUpdates) {
mContinuousUpdates = continuousUpdates;
}
/**
* Sets the haptic feedback mode. HAPTIC_FEEDBACK_MODE_ON_TICKS means to perform haptic feedback
* as the SeekBar's progress is updated; HAPTIC_FEEDBACK_MODE_ON_ENDS means to perform haptic
* feedback as the SeekBar's progress value is equal to the min/max value.
*
* @param hapticFeedbackMode the haptic feedback mode.
*/
public void setHapticFeedbackMode(int hapticFeedbackMode) {
mHapticFeedbackMode = hapticFeedbackMode;
}
private void setProgress(int progress, boolean notifyChanged) {
if (progress > mMax) {
progress = mMax;
}
if (progress < mMin) {
progress = mMin;
}
if (progress != mProgress) {
mProgress = progress;
persistInt(progress);
if (notifyChanged) {
notifyChanged();
}
}
}
public int getProgress() {
return mProgress;
}
/**
* Persist the seekBar's progress value if callChangeListener
* returns true, otherwise set the seekBar's progress to the stored value
*/
void syncProgress(SeekBar seekBar) {
int progress = seekBar.getProgress();
if (progress != mProgress) {
if (callChangeListener(progress)) {
setProgress(progress, false);
switch (mHapticFeedbackMode) {
case HAPTIC_FEEDBACK_MODE_ON_TICKS:
seekBar.performHapticFeedback(CLOCK_TICK);
break;
case HAPTIC_FEEDBACK_MODE_ON_ENDS:
if (progress == mMax || progress == mMin) {
seekBar.performHapticFeedback(CLOCK_TICK);
}
break;
}
} else {
seekBar.setProgress(mProgress);
}
}
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser && (mContinuousUpdates || !mTrackingTouch)) {
syncProgress(seekBar);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
mTrackingTouch = true;
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
mTrackingTouch = false;
if (seekBar.getProgress() != mProgress) {
syncProgress(seekBar);
}
}
/**
* Specify the type of range this seek bar represents.
*
* @param rangeInfoType The type of range to be shared with accessibility
*
* @see android.view.accessibility.AccessibilityNodeInfo.RangeInfo
*/
public void setAccessibilityRangeInfoType(int rangeInfoType) {
mAccessibilityRangeInfoType = rangeInfoType;
}
public void setSeekBarContentDescription(CharSequence contentDescription) {
mSeekBarContentDescription = contentDescription;
if (mSeekBar != null) {
mSeekBar.setContentDescription(contentDescription);
}
}
/**
* Specify the state description for this seek bar represents.
*
* @param stateDescription the state description of seek bar
*/
public void setSeekBarStateDescription(CharSequence stateDescription) {
mSeekBarStateDescription = stateDescription;
if (mSeekBar != null) {
mSeekBar.setStateDescription(stateDescription);
}
}
@Override
protected Parcelable onSaveInstanceState() {
/*
* Suppose a client uses this preference type without persisting. We
* must save the instance state so it is able to, for example, survive
* orientation changes.
*/
final Parcelable superState = super.onSaveInstanceState();
if (isPersistent()) {
// No need to save instance state since it's persistent
return superState;
}
// Save the instance state
final SavedState myState = new SavedState(superState);
myState.progress = mProgress;
myState.max = mMax;
myState.min = mMin;
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (!state.getClass().equals(SavedState.class)) {
// Didn't save state for us in onSaveInstanceState
super.onRestoreInstanceState(state);
return;
}
// Restore the instance state
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
mProgress = myState.progress;
mMax = myState.max;
mMin = myState.min;
notifyChanged();
}
/**
* SavedState, a subclass of {@link BaseSavedState}, will store the state
* of MyPreference, a subclass of Preference.
* <p>
* It is important to always call through to super methods.
*/
private static class SavedState extends BaseSavedState {
int progress;
int max;
int min;
public SavedState(Parcel source) {
super(source);
// Restore the click counter
progress = source.readInt();
max = source.readInt();
min = source.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
// Save the click counter
dest.writeInt(progress);
dest.writeInt(max);
dest.writeInt(min);
}
public SavedState(Parcelable superState) {
super(superState);
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}

View File

@@ -17,7 +17,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<com.android.settings.widget.SeekBarPreference
<com.android.settingslib.widget.SeekBarPreference
android:key="seek_bar"
android:title="seek_bar_title"/>
</PreferenceScreen >

View File

@@ -17,7 +17,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<com.android.settings.widget.SeekBarPreference
<com.android.settingslib.widget.SeekBarPreference
android:key="seek_bar"
android:selectable="true"
android:title="seek_bar_title"/>

View File

@@ -36,7 +36,7 @@ import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.widget.SeekBarPreference;
import org.junit.Before;
import org.junit.Rule;

View File

@@ -1,72 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.gestures;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import androidx.preference.Preference;
import com.android.settings.widget.LabeledSeekBarPreference;
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;
@RunWith(RobolectricTestRunner.class)
public class LabeledSeekBarPreferenceTest {
private Context mContext;
private SeekBar mSeekBar;
private LabeledSeekBarPreference mSeekBarPreference;
@Mock
private Preference.OnPreferenceChangeListener mListener;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mSeekBarPreference = new LabeledSeekBarPreference(mContext, null);
LayoutInflater inflater = LayoutInflater.from(mContext);
final View view =
inflater.inflate(mSeekBarPreference.getLayoutResource(),
new LinearLayout(mContext), false);
mSeekBar = view.findViewById(com.android.internal.R.id.seekbar);
}
@Test
public void seekBarPreferenceOnStopTrackingTouch_callsListener() {
mSeekBar.setProgress(2);
mSeekBarPreference.setOnPreferenceChangeStopListener(mListener);
mSeekBarPreference.onStopTrackingTouch(mSeekBar);
verify(mListener, times(1)).onPreferenceChange(mSeekBarPreference, 2);
}
}

View File

@@ -20,19 +20,20 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doCallRealMethod;
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.Context;
import android.os.UserHandle;
import android.os.UserManager;
import androidx.preference.Preference;
import com.android.settings.accounts.AccountRestrictionHelper;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedSeekBarPreference;
import org.junit.Before;
import org.junit.Test;
@@ -46,9 +47,11 @@ import org.robolectric.RuntimeEnvironment;
public class AdjustVolumeRestrictedPreferenceControllerTest {
private static final String KEY = "key";
@Mock
private AccountRestrictionHelper mAccountHelper;
@Mock
UserManager mUserManager;
private Context mContext;
private AdjustVolumeRestrictedPreferenceControllerTestable mController;
@@ -56,15 +59,17 @@ public class AdjustVolumeRestrictedPreferenceControllerTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
mAccountHelper = new AccountRestrictionHelper(mContext);
mController =
new AdjustVolumeRestrictedPreferenceControllerTestable(mContext, mAccountHelper, KEY);
}
@Test
public void updateState_hasBaseRestriction_shouldDisable() {
RestrictedPreference preference = mock(RestrictedPreference.class);
when(mAccountHelper.hasBaseUserRestriction(
eq(UserManager.DISALLOW_ADJUST_VOLUME), anyInt())).thenReturn(true);
RestrictedSeekBarPreference preference = mock(RestrictedSeekBarPreference.class);
when(RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
UserManager.DISALLOW_ADJUST_VOLUME, UserHandle.myUserId())).thenReturn(true);
mController.updateState(preference);
@@ -73,13 +78,11 @@ public class AdjustVolumeRestrictedPreferenceControllerTest {
@Test
public void updateState_NoBaseRestriction_shouldCheckRestriction() {
RestrictedPreference preference = spy(new RestrictedPreference(mContext));
RestrictedSeekBarPreference preference = spy(new RestrictedSeekBarPreference(mContext));
when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(null);
when(mAccountHelper.hasBaseUserRestriction(
eq(UserManager.DISALLOW_ADJUST_VOLUME), anyInt())).thenReturn(false);
doCallRealMethod().when(mAccountHelper).enforceRestrictionOnPreference(
eq(preference), eq(UserManager.DISALLOW_ADJUST_VOLUME), anyInt());
when(RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
UserManager.DISALLOW_ADJUST_VOLUME, UserHandle.myUserId())).thenReturn(false);
mController.updateState(preference);

View File

@@ -43,8 +43,8 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.media.LocalMediaManager;
import com.android.settingslib.widget.SeekBarPreference;
import org.junit.Before;
import org.junit.Test;

View File

@@ -28,7 +28,6 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.service.trust.TrustAgentService;
import android.text.TextUtils;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;

View File

@@ -1,187 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.widget;
import static android.view.HapticFeedbackConstants.CLOCK_TICK;
import static android.view.HapticFeedbackConstants.CONTEXT_CLICK;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.widget.SeekBar;
import androidx.preference.PreferenceFragmentCompat;
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.androidx.fragment.FragmentController;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowRestrictedLockUtilsInternal.class)
public class SeekBarPreferenceTest {
private static final int MAX = 75;
private static final int MIN = 5;
private static final int PROGRESS = 16;
private static final int NEW_PROGRESS = 17;
private Context mContext;
private SeekBarPreference mSeekBarPreference;
private SeekBar mSeekBar;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mSeekBarPreference = spy(new SeekBarPreference(mContext));
mSeekBarPreference.setMax(MAX);
mSeekBarPreference.setMin(MIN);
mSeekBarPreference.setProgress(PROGRESS);
mSeekBarPreference.setPersistent(false);
mSeekBarPreference.setHapticFeedbackMode(SeekBarPreference.HAPTIC_FEEDBACK_MODE_NONE);
mSeekBar = new SeekBar(mContext);
mSeekBar.setMax(MAX);
mSeekBar.setMin(MIN);
}
@Test
public void testSaveAndRestoreInstanceState() {
final Parcelable parcelable = mSeekBarPreference.onSaveInstanceState();
final SeekBarPreference preference = new SeekBarPreference(mContext);
preference.onRestoreInstanceState(parcelable);
assertThat(preference.getMax()).isEqualTo(MAX);
assertThat(preference.getMin()).isEqualTo(MIN);
assertThat(preference.getProgress()).isEqualTo(PROGRESS);
}
@Test
public void isSelectable_disabledByAdmin_returnTrue() {
when(mSeekBarPreference.isDisabledByAdmin()).thenReturn(true);
assertThat(mSeekBarPreference.isSelectable()).isTrue();
}
@Test
@Config(qualifiers = "mcc998")
public void isSelectable_default_returnFalse() {
final PreferenceFragmentCompat fragment = FragmentController.of(new TestFragment(),
new Bundle())
.create()
.start()
.resume()
.get();
final SeekBarPreference seekBarPreference = fragment.findPreference("seek_bar");
assertThat(seekBarPreference.isSelectable()).isFalse();
}
@Test
@Config(qualifiers = "mcc999")
public void isSelectable_selectableInXml_returnTrue() {
final PreferenceFragmentCompat fragment = FragmentController.of(new TestFragment(),
new Bundle())
.create()
.start()
.resume()
.get();
final SeekBarPreference seekBarPreference = fragment.findPreference("seek_bar");
assertThat(seekBarPreference.isSelectable()).isTrue();
}
@Test
public void testSetSeekBarStateDescription() {
mSeekBarPreference.setSeekBarStateDescription("test");
verify(mSeekBarPreference).setSeekBarStateDescription("test");
}
@Test
public void onProgressChanged_hapticFeedbackModeNone_clockTickFeedbackNotPerformed() {
mSeekBar.setProgress(NEW_PROGRESS);
when(mSeekBarPreference.callChangeListener(anyInt())).thenReturn(true);
mSeekBar.performHapticFeedback(CONTEXT_CLICK);
mSeekBarPreference.onProgressChanged(mSeekBar, NEW_PROGRESS, true);
assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isNotEqualTo(CLOCK_TICK);
}
@Test
public void onProgressChanged_hapticFeedbackModeOnTicks_clockTickFeedbackPerformed() {
mSeekBarPreference.setHapticFeedbackMode(SeekBarPreference.HAPTIC_FEEDBACK_MODE_ON_TICKS);
mSeekBar.setProgress(NEW_PROGRESS);
when(mSeekBarPreference.callChangeListener(anyInt())).thenReturn(true);
mSeekBar.performHapticFeedback(CONTEXT_CLICK);
mSeekBarPreference.onProgressChanged(mSeekBar, NEW_PROGRESS, true);
assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK);
}
@Test
public void onProgressChanged_hapticFeedbackModeOnEnds_clockTickFeedbackNotPerformed() {
mSeekBarPreference.setHapticFeedbackMode(SeekBarPreference.HAPTIC_FEEDBACK_MODE_ON_ENDS);
mSeekBar.setProgress(NEW_PROGRESS);
when(mSeekBarPreference.callChangeListener(anyInt())).thenReturn(true);
mSeekBar.performHapticFeedback(CONTEXT_CLICK);
mSeekBarPreference.onProgressChanged(mSeekBar, NEW_PROGRESS, true);
assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isNotEqualTo(CLOCK_TICK);
}
@Test
public void onProgressChanged_hapticFeedbackModeOnEndsAndMinValue_clockTickFeedbackPerformed() {
mSeekBarPreference.setHapticFeedbackMode(SeekBarPreference.HAPTIC_FEEDBACK_MODE_ON_ENDS);
mSeekBar.setProgress(MIN);
when(mSeekBarPreference.callChangeListener(anyInt())).thenReturn(true);
mSeekBar.performHapticFeedback(CONTEXT_CLICK);
mSeekBarPreference.onProgressChanged(mSeekBar, MIN, true);
assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK);
}
public static class TestFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(com.android.settings.R.xml.seekbar_preference);
}
}
}

View File

@@ -23,7 +23,7 @@ import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.slices.SliceData;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.widget.SeekBarPreference;
import org.junit.Before;
import org.junit.Test;

View File

@@ -1,51 +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.widget;
import static org.junit.Assert.assertEquals;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class DefaultIndicatorSeekBarTest {
private DefaultIndicatorSeekBar mDefaultIndicatorSeekBar;
@Before
public void setUp() {
mDefaultIndicatorSeekBar = new DefaultIndicatorSeekBar(
ApplicationProvider.getApplicationContext());
mDefaultIndicatorSeekBar.setMax(100);
}
@After
public void tearDown() {
mDefaultIndicatorSeekBar = null;
}
@Test
public void defaultProgress_setSucceeds() {
mDefaultIndicatorSeekBar.setDefaultProgress(40);
assertEquals(40, mDefaultIndicatorSeekBar.getDefaultProgress());
}
}