Snap for 5160973 from 3645640904 to qt-release

Change-Id: Id171cbf8b3093d725758d20f84ec29d414b095fe
This commit is contained in:
android-build-team Robot
2018-12-04 04:09:27 +00:00
53 changed files with 898 additions and 986 deletions

View File

@@ -1,52 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:orientation="horizontal">
<Button
android:id="@+id/button1"
style="@style/SettingsActionButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:id="@+id/button2"
style="@style/SettingsActionButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:id="@+id/button3"
style="@style/SettingsActionButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:id="@+id/button4"
style="@style/SettingsActionButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>

View File

@@ -20,13 +20,13 @@
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/delete_zen_rule"
android:id="@+id/zen_automatic_rule_widget"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:paddingStart="16dip"
android:paddingEnd="16dip"
android:src="@drawable/ic_delete"
android:contentDescription="@string/zen_mode_delete_rule"
android:src="@drawable/ic_settings"
android:contentDescription="zen_mode_rule_settings"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground" />
</LinearLayout>

View File

@@ -7117,6 +7117,12 @@
<!-- Do not disturb: Title for the zen mode automation option in Settings. [CHAR LIMIT=40] -->
<string name="zen_mode_automation_settings_title">Schedules</string>
<!-- Do not disturb: Title for dialog that allows users to delete DND rules/schedules[CHAR LIMIT=40] -->
<string name="zen_mode_delete_automatic_rules">Delete schedules</string>
<!-- Do not disturb: Delete text button presented in a dialog to confirm the user would like to delete the selected DND rules. [CHAR LIMIT=30] -->
<string name="zen_mode_schedule_delete">Delete</string>
<!-- Do not disturb: Title for the zen mode automatic rules page in settings. [CHAR LIMIT=30] -->
<string name="zen_mode_automation_settings_page_title">Do Not Disturb</string>
@@ -7253,6 +7259,9 @@
<!-- [CHAR LIMIT=110] Zen mode settings footer: Footer how DND was triggered by an app -->
<string name="zen_mode_settings_dnd_automatic_rule_app">Do Not Disturb was automatically turned on by an app (<xliff:g id="app_name" example="Android Services">%s</xliff:g>)</string>
<!-- [CHAR LIMIT=120] Zen mode settings footer: Footer informing user DND has custom settings. -->
<string name="zen_mode_settings_dnd_custom_settings_footer">Do Not Disturb is on for <xliff:g id="rule_names" example="Sleeping and Work">%s</xliff:g> with custom settings.</string>
<!--[CHAR LIMIT=40] Zen Interruption level: Priority. -->
<string name="zen_interruption_level_priority">Priority only</string>
@@ -7848,6 +7857,15 @@
<!-- [CHAR LIMIT=NONE] Zen mode settings: Downtime rule setting -->
<string name="zen_mode_schedule_alarm_summary">Stop at the end time or next alarm, whichever comes first</string>
<!-- [CHAR LIMIT=80] Zen mode settings: Title for preference to allow custom behavior for the dnd schedule -->
<string name="zen_mode_custom_behavior_title">Do Not Disturb behavior</string>
<!-- [CHAR LIMIT=120] Zen mode settings: Summay text indicating the currenty dnd schedule is using the default dnd settings -->
<string name="zen_mode_custom_behavior_summary_default">Use default settings</string>
<!-- [CHAR LIMIT=120] Zen mode settings: Summay text indicating the currenty dnd schedule is using custom behavior -->
<string name="zen_mode_custom_behavior_summary">Create custom settings for this schedule</string>
<!-- [CHAR LIMIT=40] General divider text when concatenating multiple items in a text summary -->
<string name="summary_divider_text">,\u0020</string>
@@ -10224,6 +10242,8 @@
<item quantity="one"><xliff:g id="number_device_count">%1$d</xliff:g> device connected</item>
<item quantity="other"><xliff:g id="number_device_count">%1$d</xliff:g> devices connected</item>
</plurals>
<!-- Title for bluetooth connected devices in connected device slice. [CHAR LIMIT=NONE] -->
<string name="bluetooth_connected_devices">Bluetooth Devices</string>
<!-- Title for no connected devices in connected device slice. [CHAR LIMIT=NONE] -->
<string name="no_connected_devices">No connected devices</string>
@@ -10233,6 +10253,9 @@
<!-- Title for the Internet Connectivity dialog (settings panel) with Internet related settings [CHAR LIMIT=50] -->
<string name="internet_connectivity_panel_title">Internet Connectivity</string>
<!-- Title for the Volume dialog (settings panel) with all volume streams[CHAR LIMIT=50] -->
<string name="volume_connectivity_panel_title">Volume</string>
<!-- UI debug setting: force desktop mode [CHAR LIMIT=50] -->
<string name="force_desktop_mode">Force desktop mode</string>
<!-- UI debug setting: force desktop mode summary [CHAR LIMIT=NONE] -->

View File

@@ -401,16 +401,6 @@
<style name="ActionSecondaryButton" parent="android:Widget.DeviceDefault.Button"/>
<style name="SettingsActionButton"
parent="android:Widget.DeviceDefault.Button.Borderless.Colored">
<item name="android:drawablePadding">4dp</item>
<item name="android:drawableTint">@*android:color/btn_colored_borderless_text_material
</item>
<item name="android:layout_marginEnd">8dp</item>
<item name="android:paddingTop">20dp</item>
<item name="android:paddingBottom">20dp</item>
</style>
<style name="LockPatternContainerStyle">
<item name="android:maxHeight">400dp</item>
<item name="android:maxWidth">420dp</item>

View File

@@ -36,7 +36,7 @@
settings:allowDividerAbove="true"
settings:allowDividerBelow="true"/>
<com.android.settings.widget.ActionButtonPreference
<com.android.settingslib.widget.ActionButtonsPreference
android:key="action_buttons"
android:order="-9998" />

View File

@@ -19,7 +19,7 @@
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/storage_label">
<com.android.settings.widget.ActionButtonPreference
<com.android.settingslib.widget.ActionButtonsPreference
android:key="header_view" />
<com.android.settings.applications.SpacePreference

View File

@@ -25,7 +25,7 @@
android:selectable="false"
settings:allowDividerBelow="true"/>
<com.android.settings.widget.ActionButtonPreference
<com.android.settingslib.widget.ActionButtonsPreference
android:key="action_buttons" />
<PreferenceCategory

View File

@@ -21,82 +21,107 @@
<!-- Header -->
<Preference android:key="enterprise_privacy_header"
android:order="100"
android:icon="@drawable/ic_info_outline_24dp"
android:summary="@string/enterprise_privacy_header"
android:selectable="false"/>
<PreferenceCategory android:key="exposure_category"
android:order="200"
android:title="@string/enterprise_privacy_exposure_category"
android:contentDescription="@string/enterprise_privacy_exposure_category">
<Preference android:key="enterprise_privacy_enterprise_data"
android:order="210"
android:layout_height="wrap_content"
android:title="@string/enterprise_privacy_enterprise_data"
android:selectable="false"/>
<Preference android:key="enterprise_privacy_installed_packages"
android:order="220"
android:title="@string/enterprise_privacy_installed_packages"
android:selectable="false"/>
<Preference android:key="enterprise_privacy_usage_stats"
android:order="230"
android:title="@string/enterprise_privacy_usage_stats"
android:selectable="false"/>
<Preference android:key="network_logs"
android:order="240"
android:title="@string/enterprise_privacy_network_logs"
android:selectable="false"/>
<Preference android:key="bug_reports"
android:order="250"
android:title="@string/enterprise_privacy_bug_reports"
android:selectable="false"/>
<Preference android:key="security_logs"
android:order="260"
android:title="@string/enterprise_privacy_security_logs"
android:selectable="false"/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/enterprise_privacy_exposure_changes_category"
android:order="300"
android:key="exposure_changes_category">
<Preference android:fragment="com.android.settings.enterprise.ApplicationListFragment$EnterpriseInstalledPackages"
android:order="310"
android:key="number_enterprise_installed_packages"
android:title="@string/enterprise_privacy_enterprise_installed_packages"/>
<Preference android:fragment="com.android.settings.enterprise.ApplicationListFragment$AdminGrantedPermissionLocation"
android:order="320"
android:key="enterprise_privacy_number_location_access_packages"
android:title="@string/enterprise_privacy_location_access"/>
<Preference android:fragment="com.android.settings.enterprise.ApplicationListFragment$AdminGrantedPermissionMicrophone"
android:order="330"
android:key="enterprise_privacy_number_microphone_access_packages"
android:title="@string/enterprise_privacy_microphone_access"/>
<Preference android:fragment="com.android.settings.enterprise.ApplicationListFragment$AdminGrantedPermissionCamera"
android:order="340"
android:key="enterprise_privacy_number_camera_access_packages"
android:title="@string/enterprise_privacy_camera_access"/>
<Preference android:fragment="com.android.settings.enterprise.EnterpriseSetDefaultAppsListFragment"
android:order="350"
android:key="number_enterprise_set_default_apps"
android:title="@string/enterprise_privacy_enterprise_set_default_apps"/>
<Preference android:key="always_on_vpn_primary_user"
android:order="360"
android:selectable="false"/>
<Preference android:key="always_on_vpn_managed_profile"
android:order="370"
android:title="@string/enterprise_privacy_always_on_vpn_work"
android:selectable="false"/>
<Preference android:key="input_method"
android:order="380"
android:title="@string/enterprise_privacy_input_method"
android:selectable="false"/>
<Preference android:key="global_http_proxy"
android:order="390"
android:title="@string/enterprise_privacy_global_http_proxy"
android:selectable="false"/>
<Preference android:key="ca_certs_current_user"
android:order="400"
android:title="@string/enterprise_privacy_ca_certs_personal"
android:selectable="false"/>
<Preference android:key="ca_certs_managed_profile"
android:order="410"
android:title="@string/enterprise_privacy_ca_certs_work"
android:selectable="false"/>
</PreferenceCategory>
<PreferenceCategory android:key="device_access_category"
android:order="500"
android:title="@string/enterprise_privacy_device_access_category">
<Preference android:key="enterprise_privacy_lock_device"
android:order="510"
android:title="@string/enterprise_privacy_lock_device"
android:selectable="false"/>
<Preference android:key="enterprise_privacy_wipe_device"
android:order="520"
android:title="@string/enterprise_privacy_wipe_device"
android:selectable="false"/>
<Preference android:key="failed_password_wipe_current_user"
android:order="530"
android:title="@string/enterprise_privacy_failed_password_wipe_device"
android:selectable="false"/>
<Preference android:key="failed_password_wipe_managed_profile"
android:order="540"
android:title="@string/enterprise_privacy_failed_password_wipe_work"
android:selectable="false"/>
</PreferenceCategory>

View File

@@ -26,7 +26,7 @@
android:order="-10000"
settings:allowDividerBelow="true"/>
<com.android.settings.widget.ActionButtonPreference
<com.android.settingslib.widget.ActionButtonsPreference
android:key="action_buttons"
android:order="-9999"/>

View File

@@ -28,6 +28,7 @@
android:icon="@drawable/ic_media_stream"
android:title="@string/media_volume_option_title"
android:order="-180"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.notification.MediaVolumePreferenceController"/>
<!-- Media output switcher -->
@@ -44,6 +45,7 @@
android:icon="@drawable/ic_local_phone_24_lib"
android:title="@string/call_volume_option_title"
android:order="-170"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.notification.CallVolumePreferenceController"/>
<!-- Hands free profile output switcher -->
@@ -60,6 +62,7 @@
android:icon="@drawable/ic_notifications"
android:title="@string/ring_volume_option_title"
android:order="-160"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.notification.RingVolumePreferenceController"/>
@@ -69,6 +72,7 @@
android:icon="@*android:drawable/ic_audio_alarm"
android:title="@string/alarm_volume_option_title"
android:order="-150"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.notification.AlarmVolumePreferenceController"/>
<!-- Notification volume -->

View File

@@ -50,7 +50,7 @@
android:defaultValue="100"
android:max="400"/>
<com.android.settings.widget.ActionButtonPreference
<com.android.settingslib.widget.ActionButtonsPreference
android:key="action_buttons" />
</PreferenceCategory>

View File

@@ -27,7 +27,7 @@
settings:allowDividerBelow="true"/>
<!-- Buttons -->
<com.android.settings.widget.ActionButtonPreference
<com.android.settingslib.widget.ActionButtonsPreference
android:key="buttons"
android:selectable="false" />

View File

@@ -43,4 +43,10 @@
android:summary="@string/zen_mode_schedule_alarm_summary"
android:order="99" />
<!-- Custom Do Not Disturb Setting-->
<Preference
android:key="zen_schedule_custom_setting"
android:title="@string/zen_mode_custom_behavior_title"
android:order="100" />
</PreferenceScreen>

View File

@@ -53,11 +53,11 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.deviceinfo.StorageWizardMoveConfirm;
import com.android.settings.widget.ActionButtonPreference;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.applications.ApplicationsState.Callbacks;
import com.android.settingslib.applications.StorageStatsSource;
import com.android.settingslib.applications.StorageStatsSource.AppStorageStats;
import com.android.settingslib.widget.ActionButtonsPreference;
import com.android.settingslib.widget.LayoutPreference;
import java.util.Collections;
@@ -107,7 +107,7 @@ public class AppStorageSettings extends AppInfoWithHeader
// Views related to cache info
@VisibleForTesting
ActionButtonPreference mButtonsPref;
ActionButtonsPreference mButtonsPref;
private Preference mStorageUsed;
private Button mChangeStorageButton;
@@ -168,7 +168,7 @@ public class AppStorageSettings extends AppInfoWithHeader
.setComputingString(R.string.computing_size)
.setErrorString(R.string.invalid_size_value)
.build();
mButtonsPref = ((ActionButtonPreference) findPreference(KEY_HEADER_BUTTONS));
mButtonsPref = ((ActionButtonsPreference) findPreference(KEY_HEADER_BUTTONS));
mStorageUsed = findPreference(KEY_STORAGE_USED);
mChangeStorageButton = (Button) ((LayoutPreference) findPreference(KEY_CHANGE_STORAGE))
.findViewById(R.id.button);

View File

@@ -54,7 +54,6 @@ import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.ActionButtonPreference;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.applications.AppUtils;
@@ -64,6 +63,7 @@ import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnDestroy;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.widget.ActionButtonsPreference;
import java.util.ArrayList;
import java.util.HashSet;
@@ -99,7 +99,7 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
@VisibleForTesting
boolean mDisableAfterUninstall = false;
@VisibleForTesting
ActionButtonPreference mButtonsPref;
ActionButtonsPreference mButtonsPref;
private final int mRequestUninstall;
private final int mRequestRemoveDeviceAdmin;
@@ -158,14 +158,15 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
public int getAvailabilityStatus() {
// TODO(b/37313605): Re-enable once this controller supports instant apps
return mAppEntry != null && !AppUtils.isInstant(mAppEntry.info)
? AVAILABLE : DISABLED_FOR_USER ;
? AVAILABLE : DISABLED_FOR_USER;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
if (isAvailable()) {
mButtonsPref = ((ActionButtonPreference) screen.findPreference(KEY_ACTION_BUTTONS))
mButtonsPref = ((ActionButtonsPreference) screen.findPreference(
KEY_ACTION_BUTTONS))
.setButton1Text(R.string.uninstall_text)
.setButton1Icon(R.drawable.ic_settings_delete)
.setButton2Text(R.string.force_stop)
@@ -484,7 +485,7 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
} else {
Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
Uri.fromParts("package", mAppEntry.info.packageName, null));
intent.putExtra(Intent.EXTRA_PACKAGES, new String[] {mAppEntry.info.packageName});
intent.putExtra(Intent.EXTRA_PACKAGES, new String[]{mAppEntry.info.packageName});
intent.putExtra(Intent.EXTRA_UID, mAppEntry.info.uid);
intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mAppEntry.info.uid));
Log.d(TAG, "Sending broadcast to query restart status for "

View File

@@ -22,9 +22,9 @@ import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.widget.ActionButtonPreference;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.widget.ActionButtonsPreference;
/**
* This class adds two buttons: one to connect/disconnect from a device (depending on the current
@@ -35,7 +35,7 @@ public class BluetoothDetailsButtonsController extends BluetoothDetailsControlle
private boolean mIsConnected;
private boolean mConnectButtonInitialized;
private ActionButtonPreference mActionButtons;
private ActionButtonsPreference mActionButtons;
public BluetoothDetailsButtonsController(Context context, PreferenceFragmentCompat fragment,
CachedBluetoothDevice device, Lifecycle lifecycle) {
@@ -51,7 +51,8 @@ public class BluetoothDetailsButtonsController extends BluetoothDetailsControlle
@Override
protected void init(PreferenceScreen screen) {
mActionButtons = ((ActionButtonPreference) screen.findPreference(getPreferenceKey()))
mActionButtons = ((ActionButtonsPreference) screen.findPreference(
getPreferenceKey()))
.setButton1Text(R.string.forget)
.setButton1Icon(R.drawable.ic_settings_delete)
.setButton1OnClickListener((view) -> onForgetButtonPressed())

View File

@@ -28,6 +28,7 @@ import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
import com.android.settings.development.DevelopmentSettingsDashboardFragment;
import com.android.settings.deviceinfo.StorageDashboardFragment;
import com.android.settings.display.NightDisplaySettings;
import com.android.settings.enterprise.EnterprisePrivacySettings;
import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.gestures.GestureSettings;
import com.android.settings.homepage.TopLevelSettings;
@@ -107,6 +108,8 @@ public class DashboardFragmentRegistry {
CategoryKey.CATEGORY_NIGHT_DISPLAY);
PARENT_TO_CATEGORY_KEY_MAP.put(PrivacyDashboardFragment.class.getName(),
CategoryKey.CATEGORY_PRIVACY);
PARENT_TO_CATEGORY_KEY_MAP.put(EnterprisePrivacySettings.class.getName(),
CategoryKey.CATEGORY_ENTERPRISE_PRIVACY);
CATEGORY_KEY_TO_PARENT_MAP = new ArrayMap<>(PARENT_TO_CATEGORY_KEY_MAP.size());

View File

@@ -101,7 +101,7 @@ public class ConnectedDeviceSlice implements CustomSliceable {
public Slice getSlice() {
final IconCompat icon = IconCompat.createWithResource(mContext,
R.drawable.ic_homepage_connected_device);
final CharSequence title = mContext.getText(R.string.connected_devices_dashboard_title);
final CharSequence title = mContext.getText(R.string.bluetooth_connected_devices);
final CharSequence titleNoConnectedDevices = mContext.getText(
R.string.no_connected_devices);
final PendingIntent primaryActionIntent = PendingIntent.getActivity(mContext, 0,

View File

@@ -25,7 +25,6 @@ import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.provider.Settings;
import android.service.notification.ConditionProviderService;
import android.service.notification.ZenModeConfig;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
@@ -34,20 +33,15 @@ import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
abstract public class AbstractZenModeAutomaticRulePreferenceController extends
AbstractZenModePreferenceController implements PreferenceControllerMixin {
protected ZenModeBackend mBackend;
protected Fragment mParent;
protected Set<Map.Entry<String, AutomaticZenRule>> mRules;
protected Map.Entry<String, AutomaticZenRule>[] mRules;
protected PackageManager mPm;
private static List<String> mDefaultRuleIds;
public AbstractZenModeAutomaticRulePreferenceController(Context context, String key, Fragment
parent, Lifecycle lifecycle) {
@@ -60,20 +54,14 @@ abstract public class AbstractZenModeAutomaticRulePreferenceController extends
@Override
public void updateState(Preference preference) {
super.updateState(preference);
mRules = getZenModeRules();
mRules = mBackend.getAutomaticZenRules();
}
private static List<String> getDefaultRuleIds() {
if (mDefaultRuleIds == null) {
mDefaultRuleIds = ZenModeConfig.DEFAULT_RULE_IDS;
protected Map.Entry<String, AutomaticZenRule>[] getRules() {
if (mRules == null) {
mRules = mBackend.getAutomaticZenRules();
}
return mDefaultRuleIds;
}
private Set<Map.Entry<String, AutomaticZenRule>> getZenModeRules() {
Map<String, AutomaticZenRule> ruleMap =
NotificationManager.from(mContext).getAutomaticZenRules();
return ruleMap.entrySet();
return mRules;
}
protected void showNameRuleDialog(final ZenRuleInfo ri, Fragment parent) {
@@ -81,16 +69,6 @@ abstract public class AbstractZenModeAutomaticRulePreferenceController extends
RuleNameChangeListener(ri));
}
protected Map.Entry<String, AutomaticZenRule>[] sortedRules() {
if (mRules == null) {
mRules = getZenModeRules();
}
final Map.Entry<String, AutomaticZenRule>[] rt =
mRules.toArray(new Map.Entry[mRules.size()]);
Arrays.sort(rt, RULE_COMPARATOR);
return rt;
}
protected static Intent getRuleIntent(String settingsAction,
ComponentName configurationActivity, String ruleId) {
final Intent intent = new Intent()
@@ -104,35 +82,6 @@ abstract public class AbstractZenModeAutomaticRulePreferenceController extends
return intent;
}
private static final Comparator<Map.Entry<String, AutomaticZenRule>> RULE_COMPARATOR =
new Comparator<Map.Entry<String, AutomaticZenRule>>() {
@Override
public int compare(Map.Entry<String, AutomaticZenRule> lhs,
Map.Entry<String, AutomaticZenRule> rhs) {
// if it's a default rule, should be at the top of automatic rules
boolean lhsIsDefaultRule = getDefaultRuleIds().contains(lhs.getKey());
boolean rhsIsDefaultRule = getDefaultRuleIds().contains(rhs.getKey());
if (lhsIsDefaultRule != rhsIsDefaultRule) {
return lhsIsDefaultRule ? -1 : 1;
}
int byDate = Long.compare(lhs.getValue().getCreationTime(),
rhs.getValue().getCreationTime());
if (byDate != 0) {
return byDate;
} else {
return key(lhs.getValue()).compareTo(key(rhs.getValue()));
}
}
private String key(AutomaticZenRule rule) {
final int type = ZenModeConfig.isValidScheduleConditionId(rule.getConditionId())
? 1 : ZenModeConfig.isValidEventConditionId(rule.getConditionId())
? 2 : 3;
return type + rule.getName().toString();
}
};
public static ZenRuleInfo getRuleInfo(PackageManager pm, ServiceInfo si) {
if (si == null || si.metaData == null) {
return null;

View File

@@ -136,7 +136,7 @@ public class ZenAutomaticRuleHeaderPreferenceController extends AbstractZenModeP
MetricsProto.MetricsEvent.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
mRule.setName(ruleName);
mRule.setModified(true);
mBackend.setZenRule(mId, mRule);
mBackend.updateZenRule(mId, mRule);
}
}
}

View File

@@ -88,6 +88,6 @@ public class ZenAutomaticRuleSwitchPreferenceController extends
final boolean enabled = isChecked;
if (enabled == mRule.isEnabled()) return;
mRule.setEnabled(enabled);
mBackend.setZenRule(mId, mRule);
mBackend.updateZenRule(mId, mRule);
}
}

View File

@@ -21,12 +21,12 @@ import android.content.Context;
import android.provider.Settings;
import android.util.Log;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.core.lifecycle.Lifecycle;
import androidx.preference.Preference;
import androidx.preference.SwitchPreference;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenModeAlarmsPreferenceController extends
AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener {
@@ -78,6 +78,7 @@ public class ZenModeAlarmsPreferenceController extends
mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_ALARMS,
allowAlarms);
mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_ALARMS, allowAlarms);
return true;
}
}

View File

@@ -28,6 +28,7 @@ import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.Map;
import java.util.Objects;
public class ZenModeAutomaticRulesPreferenceController extends
AbstractZenModeAutomaticRulePreferenceController {
@@ -62,16 +63,40 @@ public class ZenModeAutomaticRulesPreferenceController extends
@Override
public void updateState(Preference preference) {
super.updateState(preference);
Map.Entry<String, AutomaticZenRule>[] sortedRules = getRules();
final int currNumPreferences = mPreferenceCategory.getPreferenceCount();
if (currNumPreferences == sortedRules.length) {
for (int i = 0; i < sortedRules.length; i++) {
ZenRulePreference pref = (ZenRulePreference) mPreferenceCategory.getPreference(i);
// we are either:
// 1. updating the enabled state or name of the rule
// 2. rule was added or deleted, so reload the entire list
if (Objects.equals(pref.mId, sortedRules[i].getKey())) {
AutomaticZenRule rule = sortedRules[i].getValue();
pref.setName(rule.getName());
pref.setChecked(rule.isEnabled());
} else {
reloadAllRules(sortedRules);
break;
}
}
} else {
reloadAllRules(sortedRules);
}
}
@VisibleForTesting
void reloadAllRules(Map.Entry<String, AutomaticZenRule>[] rules) {
mPreferenceCategory.removeAll();
Map.Entry<String, AutomaticZenRule>[] sortedRules = sortedRules();
for (Map.Entry<String, AutomaticZenRule> sortedRule : sortedRules) {
ZenRulePreference pref = new ZenRulePreference(mPreferenceCategory.getContext(),
sortedRule, mParent, mMetricsFeatureProvider);
for (Map.Entry<String, AutomaticZenRule> rule : rules) {
ZenRulePreference pref = createZenRulePreference(rule);
mPreferenceCategory.addPreference(pref);
}
}
@VisibleForTesting
ZenRulePreference createZenRulePreference(Map.Entry<String, AutomaticZenRule> rule) {
return new ZenRulePreference(mPreferenceCategory.getContext(),
rule, mParent, mMetricsFeatureProvider);
}
}

View File

@@ -16,9 +16,15 @@
package com.android.settings.notification;
import android.app.AlertDialog;
import android.app.AutomaticZenRule;
import android.content.Context;
import android.content.DialogInterface;
import android.provider.SearchIndexableResource;
import android.service.notification.ConditionProviderService;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import androidx.fragment.app.Fragment;
@@ -34,10 +40,14 @@ import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@SearchIndexable
public class ZenModeAutomationSettings extends ZenModeSettingsBase {
protected final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
private CharSequence[] mDeleteDialogRuleNames;
private String[] mDeleteDialogRuleIds;
private boolean[] mDeleteDialogChecked;
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
@@ -74,6 +84,52 @@ public class ZenModeAutomationSettings extends ZenModeSettingsBase {
.setNoun("condition provider")
.build();
}
private final int DELETE_RULES = 1;
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.add(Menu.NONE, DELETE_RULES, Menu.NONE, R.string.zen_mode_delete_automatic_rules);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case DELETE_RULES:
Map.Entry<String, AutomaticZenRule>[] rules = mBackend.getAutomaticZenRules();
mDeleteDialogRuleNames = new CharSequence[rules.length];
mDeleteDialogRuleIds = new String[rules.length];
mDeleteDialogChecked = new boolean[rules.length];
for (int i = 0; i < rules.length; i++) {
mDeleteDialogRuleNames[i] = rules[i].getValue().getName();
mDeleteDialogRuleIds[i] = rules[i].getKey();
}
new AlertDialog.Builder(mContext)
.setTitle(R.string.zen_mode_delete_automatic_rules)
.setMultiChoiceItems(mDeleteDialogRuleNames, null,
new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which,
boolean isChecked) {
mDeleteDialogChecked[which] = isChecked;
}
})
.setPositiveButton(R.string.zen_mode_schedule_delete,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
for (int i = 0; i < rules.length; i++) {
if (mDeleteDialogChecked[i]) {
mBackend.removeZenRule(mDeleteDialogRuleIds[i]);
}
}
}
}).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* For Search.

View File

@@ -32,6 +32,11 @@ import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
public class ZenModeBackend {
@VisibleForTesting
protected static final String ZEN_MODE_FROM_ANYONE = "zen_mode_from_anyone";
@@ -42,6 +47,7 @@ public class ZenModeBackend {
@VisibleForTesting
protected static final String ZEN_MODE_FROM_NONE = "zen_mode_from_none";
protected static final int SOURCE_NONE = -1;
private static List<String> mDefaultRuleIds;
private static ZenModeBackend sInstance;
@@ -79,7 +85,7 @@ public class ZenModeBackend {
Settings.Global.ZEN_MODE, mZenMode);
}
protected boolean setZenRule(String id, AutomaticZenRule rule) {
protected boolean updateZenRule(String id, AutomaticZenRule rule) {
return NotificationManager.from(mContext).updateAutomaticZenRule(id, rule);
}
@@ -294,13 +300,65 @@ public class ZenModeBackend {
return NotificationManager.from(mContext).removeAutomaticZenRule(ruleId);
}
public NotificationManager.Policy getConsolidatedPolicy() {
return NotificationManager.from(mContext).getConsolidatedNotificationPolicy();
}
protected String addZenRule(AutomaticZenRule rule) {
try {
String id = NotificationManager.from(mContext).addAutomaticZenRule(rule);
NotificationManager.from(mContext).getAutomaticZenRule(id);
return id;
return NotificationManager.from(mContext).addAutomaticZenRule(rule);
} catch (Exception e) {
return null;
}
}
protected Map.Entry<String, AutomaticZenRule>[] getAutomaticZenRules() {
Map<String, AutomaticZenRule> ruleMap =
NotificationManager.from(mContext).getAutomaticZenRules();
final Map.Entry<String, AutomaticZenRule>[] rt = ruleMap.entrySet().toArray(
new Map.Entry[ruleMap.size()]);
Arrays.sort(rt, RULE_COMPARATOR);
return rt;
}
protected AutomaticZenRule getAutomaticZenRule(String id) {
return NotificationManager.from(mContext).getAutomaticZenRule(id);
}
private static List<String> getDefaultRuleIds() {
if (mDefaultRuleIds == null) {
mDefaultRuleIds = ZenModeConfig.DEFAULT_RULE_IDS;
}
return mDefaultRuleIds;
}
@VisibleForTesting
public static final Comparator<Map.Entry<String, AutomaticZenRule>> RULE_COMPARATOR =
new Comparator<Map.Entry<String, AutomaticZenRule>>() {
@Override
public int compare(Map.Entry<String, AutomaticZenRule> lhs,
Map.Entry<String, AutomaticZenRule> rhs) {
// if it's a default rule, should be at the top of automatic rules
boolean lhsIsDefaultRule = getDefaultRuleIds().contains(lhs.getKey());
boolean rhsIsDefaultRule = getDefaultRuleIds().contains(rhs.getKey());
if (lhsIsDefaultRule != rhsIsDefaultRule) {
return lhsIsDefaultRule ? -1 : 1;
}
int byDate = Long.compare(lhs.getValue().getCreationTime(),
rhs.getValue().getCreationTime());
if (byDate != 0) {
return byDate;
} else {
return key(lhs.getValue()).compareTo(key(rhs.getValue()));
}
}
private String key(AutomaticZenRule rule) {
final int type = ZenModeConfig.isValidScheduleConditionId(rule.getConditionId())
? 1 : ZenModeConfig.isValidEventConditionId(rule.getConditionId())
? 2 : 3;
return type + rule.getName().toString();
}
};
}

View File

@@ -124,7 +124,7 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
protected void updateRule(Uri newConditionId) {
mRule.setConditionId(newConditionId);
mBackend.setZenRule(mId, mRule);
mBackend.updateZenRule(mId, mRule);
}
@Override

View File

@@ -64,7 +64,6 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
private TimePickerPreference mEnd;
private SwitchPreference mExitAtAlarm;
private AlertDialog mDayDialog;
private ScheduleInfo mSchedule;
@Override
@@ -186,7 +185,6 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
final int summaryFormat = nextDay ? R.string.zen_mode_end_time_next_day_summary_format : 0;
mEnd.setSummaryFormat(summaryFormat);
}
@Override
protected void updateControlsInternal() {
updateDays();

View File

@@ -16,16 +16,23 @@
package com.android.settings.notification;
import android.app.NotificationManager;
import android.content.Context;
import android.icu.text.ListFormatter;
import android.net.Uri;
import android.provider.Settings;
import android.service.notification.ZenModeConfig;
import android.util.Log;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class ZenModeSettingsFooterPreferenceController extends AbstractZenModePreferenceController {
protected static final String KEY = "footer_preference";
@@ -65,6 +72,31 @@ public class ZenModeSettingsFooterPreferenceController extends AbstractZenModePr
protected String getFooterText() {
ZenModeConfig config = getZenModeConfig();
NotificationManager.Policy appliedPolicy = mBackend.getConsolidatedPolicy();
NotificationManager.Policy defaultPolicy = config.toNotificationPolicy();
final boolean usingCustomPolicy = !Objects.equals(appliedPolicy, defaultPolicy);
if (usingCustomPolicy) {
final List<ZenModeConfig.ZenRule> activeRules = getActiveRules(config);
final List<String> rulesNames = new ArrayList<>();
for (ZenModeConfig.ZenRule rule : activeRules) {
if (rule.name != null) {
rulesNames.add(rule.name);
}
}
if (rulesNames.size() > 0) {
String rules = ListFormatter.getInstance().format(rulesNames);
if (!rules.isEmpty()) {
return mContext.getString(R.string.zen_mode_settings_dnd_custom_settings_footer,
rules);
}
}
}
return getFooterUsingDefaultPolicy(config);
}
private String getFooterUsingDefaultPolicy(ZenModeConfig config) {
String footerText = "";
long latestEndTime = -1;
@@ -116,4 +148,18 @@ public class ZenModeSettingsFooterPreferenceController extends AbstractZenModePr
}
return footerText;
}
private List<ZenModeConfig.ZenRule> getActiveRules(ZenModeConfig config) {
List<ZenModeConfig.ZenRule> zenRules = new ArrayList<>();
if (config.manualRule != null) {
zenRules.add(config.manualRule);
}
for (ZenModeConfig.ZenRule automaticRule : config.automaticRules.values()) {
if (automaticRule.isAutomaticActive()) {
zenRules.add(automaticRule);
}
}
return zenRules;
}
}

View File

@@ -19,17 +19,18 @@ package com.android.settings.notification;
import android.app.AutomaticZenRule;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.service.notification.ZenModeConfig;
import android.view.View;
import android.widget.CheckBox;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.utils.ManagedServiceSettings;
import com.android.settings.utils.ZenServiceListing;
@@ -37,11 +38,11 @@ import com.android.settingslib.TwoTargetPreference;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import java.util.Map;
import java.util.Objects;
public class ZenRulePreference extends TwoTargetPreference {
private static final ManagedServiceSettings.Config CONFIG =
ZenModeAutomationSettings.getConditionProviderConfig();
final CharSequence mName;
final String mId;
boolean appExists;
final Fragment mParent;
@@ -51,16 +52,23 @@ public class ZenRulePreference extends TwoTargetPreference {
final ZenServiceListing mServiceListing;
final PackageManager mPm;
final MetricsFeatureProvider mMetricsFeatureProvider;
final AutomaticZenRule mRule;
CharSequence mName;
private boolean mIsSystemRule;
private Intent mIntent;
private boolean mChecked;
private CheckBox mCheckBox;
public ZenRulePreference(Context context,
final Map.Entry<String, AutomaticZenRule> ruleEntry,
Fragment parent, MetricsFeatureProvider metricsProvider) {
super(context);
setLayoutResource(R.layout.preference_checkable_two_target);
mBackend = ZenModeBackend.getInstance(context);
mContext = context;
final AutomaticZenRule rule = ruleEntry.getValue();
mName = rule.getName();
mRule = ruleEntry.getValue();
mName = mRule.getName();
mId = ruleEntry.getKey();
mParent = parent;
mPm = mContext.getPackageManager();
@@ -68,65 +76,97 @@ public class ZenRulePreference extends TwoTargetPreference {
mServiceListing.reloadApprovedServices();
mPref = this;
mMetricsFeatureProvider = metricsProvider;
setAttributes(rule);
mChecked = mRule.isEnabled();
setAttributes(mRule);
setWidgetLayoutResource(getSecondTargetResId());
}
@Override
protected int getSecondTargetResId() {
if (mId != null && ZenModeConfig.DEFAULT_RULE_IDS.contains(mId)) {
return 0;
if (mIntent != null) {
return R.layout.zen_rule_widget;
}
return R.layout.zen_rule_widget;
return 0;
}
@Override
public void onBindViewHolder(PreferenceViewHolder view) {
super.onBindViewHolder(view);
View settingsWidget = view.findViewById(android.R.id.widget_frame);
View divider = view.findViewById(R.id.two_target_divider);
if (mIntent != null) {
divider.setVisibility(View.VISIBLE);
settingsWidget.setVisibility(View.VISIBLE);
settingsWidget.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mContext.startActivity(mIntent);
}
});
} else {
divider.setVisibility(View.GONE);
settingsWidget.setVisibility(View.GONE);
settingsWidget.setOnClickListener(null);
}
View v = view.findViewById(R.id.delete_zen_rule);
if (v != null) {
v.setOnClickListener(mDeleteListener);
View checkboxContainer = view.findViewById(R.id.checkbox_container);
if (checkboxContainer != null) {
checkboxContainer.setOnClickListener(mOnCheckBoxClickListener);
}
mCheckBox = (CheckBox) view.findViewById(com.android.internal.R.id.checkbox);
if (mCheckBox != null) {
mCheckBox.setChecked(mChecked);
}
}
private final View.OnClickListener mDeleteListener = new View.OnClickListener() {
public boolean isChecked() {
return mChecked;
}
public void setChecked(boolean checked) {
mChecked = checked;
if (mCheckBox != null) {
mCheckBox.setChecked(checked);
}
}
public void setName(String name) {
if (!Objects.equals(mName, name)) {
mName = name;
setTitle(mName);
}
}
@Override
public void onClick() {
mOnCheckBoxClickListener.onClick(null);
}
private View.OnClickListener mOnCheckBoxClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
showDeleteRuleDialog(mParent, mId, mName.toString());
mRule.setEnabled(!mChecked);
mBackend.updateZenRule(mId, mRule);
setChecked(mRule.isEnabled());
setAttributes(mRule);
}
};
private void showDeleteRuleDialog(final Fragment parent, final String ruleId,
final String ruleName) {
ZenDeleteRuleDialog.show(parent, ruleName, ruleId,
new ZenDeleteRuleDialog.PositiveClickListener() {
@Override
public void onOk(String id) {
mMetricsFeatureProvider.action(mContext,
MetricsProto.MetricsEvent.ACTION_ZEN_DELETE_RULE_OK);
mBackend.removeZenRule(id);
}
});
}
protected void setAttributes(AutomaticZenRule rule) {
final boolean isSchedule = ZenModeConfig.isValidScheduleConditionId(
rule.getConditionId(), true);
final boolean isEvent = ZenModeConfig.isValidEventConditionId(rule.getConditionId());
final boolean isSystemRule = isSchedule || isEvent;
mIsSystemRule = isSchedule || isEvent;
try {
ApplicationInfo info = mPm.getApplicationInfo(rule.getOwner().getPackageName(), 0);
setSummary(computeRuleSummary(rule, isSystemRule, info.loadLabel(mPm)));
setSummary(computeRuleSummary(rule, mIsSystemRule, info.loadLabel(mPm)));
} catch (PackageManager.NameNotFoundException e) {
appExists = false;
return;
}
appExists = true;
setTitle(rule.getName());
setTitle(mName);
setPersistent(false);
final String action = isSchedule ? ZenModeScheduleRuleSettings.ACTION
@@ -134,9 +174,8 @@ public class ZenRulePreference extends TwoTargetPreference {
ServiceInfo si = mServiceListing.findService(rule.getOwner());
ComponentName settingsActivity = AbstractZenModeAutomaticRulePreferenceController.
getSettingsActivity(si);
setIntent(AbstractZenModeAutomaticRulePreferenceController.getRuleIntent(action,
settingsActivity, mId));
setSelectable(settingsActivity != null || isSystemRule);
mIntent = AbstractZenModeAutomaticRulePreferenceController.getRuleIntent(action,
settingsActivity, mId);
setKey(mId);
}

View File

@@ -47,8 +47,8 @@ public class InternetConnectivityPanel implements PanelContent {
}
@Override
public String getTitle() {
return (String) mContext.getText(R.string.internet_connectivity_panel_title);
public CharSequence getTitle() {
return mContext.getText(R.string.internet_connectivity_panel_title);
}
@Override

View File

@@ -25,6 +25,8 @@ public class PanelFeatureProviderImpl implements PanelFeatureProvider {
switch (panelType) {
case SettingsPanelActivity.PANEL_TYPE_WIFI:
return InternetConnectivityPanel.create(context);
case SettingsPanelActivity.PANEL_TYPE_VOLUME:
return VolumePanel.create(context);
}
throw new IllegalStateException("No matching panel for: " + panelType);

View File

@@ -54,6 +54,9 @@ public class SettingsPanelActivity extends FragmentActivity {
// TODO (b/117804442) move to framework
public static final String PANEL_TYPE_WIFI = "wifi_panel";
// TODO (b/117804442) move to framework
public static final String PANEL_TYPE_VOLUME = "volume_panel";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

View File

@@ -0,0 +1,64 @@
/*
* 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.panel;
import static com.android.settings.slices.CustomSliceRegistry.VOLUME_ALARM_URI;
import static com.android.settings.slices.CustomSliceRegistry.VOLUME_CALL_URI;
import static com.android.settings.slices.CustomSliceRegistry.VOLUME_MEDIA_URI;
import static com.android.settings.slices.CustomSliceRegistry.VOLUME_RINGER_URI;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.provider.Settings;
import com.android.settings.R;
import java.util.ArrayList;
import java.util.List;
public class VolumePanel implements PanelContent {
private final Context mContext;
public static VolumePanel create(Context context) {
return new VolumePanel(context);
}
private VolumePanel(Context context) {
mContext = context.getApplicationContext();
}
@Override
public CharSequence getTitle() {
return mContext.getText(R.string.volume_connectivity_panel_title);
}
@Override
public List<Uri> getSlices() {
final List<Uri> uris = new ArrayList<>();
uris.add(VOLUME_MEDIA_URI);
uris.add(VOLUME_CALL_URI);
uris.add(VOLUME_RINGER_URI);
uris.add(VOLUME_ALARM_URI);
return uris;
}
@Override
public Intent getSeeMoreIntent() {
return new Intent(Settings.ACTION_SOUND_SETTINGS);
}
}

View File

@@ -25,6 +25,7 @@ import android.content.ContentResolver;
import android.net.Uri;
import android.provider.SettingsSlicesContract;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
import com.android.settings.wifi.calling.WifiCallingSliceHelper;
@@ -147,6 +148,43 @@ public class CustomSliceRegistry {
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
.appendPath("storage_card")
.build();
/**
* Full {@link Uri} for the Alarm volume Slice.
*/
public static final Uri VOLUME_ALARM_URI = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
.appendPath("alarm_volume")
.build();
/**
* Full {@link Uri} for the Call Volume Slice.
*/
public static final Uri VOLUME_CALL_URI = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
.appendPath("call_volume")
.build();
/**
* Full {@link Uri} for the Media Volume Slice.
*/
public static final Uri VOLUME_MEDIA_URI = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
.appendPath("media_volume")
.build();
/**
* Full {@link Uri} for the Ringer volume Slice.
*/
public static final Uri VOLUME_RINGER_URI = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
.appendPath("ring_volume")
.build();
/**
* Full {@link Uri} for the Wifi Calling Slice.
*/

View File

@@ -193,8 +193,9 @@ public class SliceBuilderUtils {
CharSequence summaryText = controller.getSummary();
// Priority 1 : User prefers showing the dynamic summary in slice view rather than static
// summary.
if (isDynamicSummaryAllowed && isValidSummary(context, summaryText)) {
// summary. Note it doesn't require a valid summary - so we can force some slices to have
// empty summaries (ex: volume).
if (isDynamicSummaryAllowed) {
return summaryText;
}

View File

@@ -44,15 +44,14 @@ import com.android.settings.SettingsActivity;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.widget.ActionButtonPreference;
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 java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -113,7 +112,7 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment
private SeekBarPreference mDefaultPitchPref;
private SeekBarPreference mDefaultRatePref;
private ActionButtonPreference mActionButtons;
private ActionButtonsPreference mActionButtons;
private int mDefaultPitch = TextToSpeech.Engine.DEFAULT_PITCH;
private int mDefaultRate = TextToSpeech.Engine.DEFAULT_RATE;
@@ -169,7 +168,7 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment
mDefaultPitchPref = (SeekBarPreference) findPreference(KEY_DEFAULT_PITCH);
mDefaultRatePref = (SeekBarPreference) findPreference(KEY_DEFAULT_RATE);
mActionButtons = ((ActionButtonPreference) findPreference(KEY_ACTION_BUTTONS))
mActionButtons = ((ActionButtonsPreference) findPreference(KEY_ACTION_BUTTONS))
.setButton1Text(R.string.tts_play)
.setButton1OnClickListener(v -> speakSampleText())
.setButton1Enabled(false)

View File

@@ -1,333 +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.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import androidx.annotation.DrawableRes;
import androidx.annotation.StringRes;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
/**
* This preference provides a four buttons layout with Settings style.
* It looks like below
*
* --------------------------------------------------
* button1 | button2 | button3 | button4 |
* --------------------------------------------------
*
* User can set title / icon / click listener for each button.
*
* By default, four buttons are visible.
* However, there are two cases which button should be invisible(View.GONE).
*
* 1. User sets invisible for button. ex: ActionButtonPreference.setButton1Visible(false)
* 2. User doesn't set any title or icon for button.
*
*/
public class ActionButtonPreference extends Preference {
private final String TAG = "ActionButtonPreference";
private final ButtonInfo mButton1Info = new ButtonInfo();
private final ButtonInfo mButton2Info = new ButtonInfo();
private final ButtonInfo mButton3Info = new ButtonInfo();
private final ButtonInfo mButton4Info = new ButtonInfo();
public ActionButtonPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
public ActionButtonPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public ActionButtonPreference(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ActionButtonPreference(Context context) {
super(context);
init();
}
private void init() {
setLayoutResource(R.layout.settings_action_buttons);
setSelectable(false);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
holder.setDividerAllowedAbove(true);
holder.setDividerAllowedBelow(true);
mButton1Info.mButton = (Button) holder.findViewById(R.id.button1);
mButton2Info.mButton = (Button) holder.findViewById(R.id.button2);
mButton3Info.mButton = (Button) holder.findViewById(R.id.button3);
mButton4Info.mButton = (Button) holder.findViewById(R.id.button4);
mButton1Info.setUpButton();
mButton2Info.setUpButton();
mButton3Info.setUpButton();
mButton4Info.setUpButton();
}
public ActionButtonPreference setButton1Visible(boolean isVisible) {
if (isVisible != mButton1Info.mIsVisible) {
mButton1Info.mIsVisible = isVisible;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton1Text(@StringRes int textResId) {
final String newText = getContext().getString(textResId);
if (!TextUtils.equals(newText, mButton1Info.mText)) {
mButton1Info.mText = newText;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton1Icon(@DrawableRes int iconResId) {
if (iconResId == 0) {
return this;
}
final Drawable icon;
try {
icon = getContext().getDrawable(iconResId);
mButton1Info.mIcon = icon;
notifyChanged();
} catch (Resources.NotFoundException exception) {
Log.e(TAG, "Resource does not exist: " + iconResId);
}
return this;
}
public ActionButtonPreference setButton1Enabled(boolean isEnabled) {
if (isEnabled != mButton1Info.mIsEnabled) {
mButton1Info.mIsEnabled = isEnabled;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton1OnClickListener(View.OnClickListener listener) {
if (listener != mButton1Info.mListener) {
mButton1Info.mListener = listener;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton2Visible(boolean isVisible) {
if (isVisible != mButton2Info.mIsVisible) {
mButton2Info.mIsVisible = isVisible;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton2Text(@StringRes int textResId) {
final String newText = getContext().getString(textResId);
if (!TextUtils.equals(newText, mButton2Info.mText)) {
mButton2Info.mText = newText;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton2Icon(@DrawableRes int iconResId) {
if (iconResId == 0) {
return this;
}
final Drawable icon;
try {
icon = getContext().getDrawable(iconResId);
mButton2Info.mIcon = icon;
notifyChanged();
} catch (Resources.NotFoundException exception) {
Log.e(TAG, "Resource does not exist: " + iconResId);
}
return this;
}
public ActionButtonPreference setButton2Enabled(boolean isEnabled) {
if (isEnabled != mButton2Info.mIsEnabled) {
mButton2Info.mIsEnabled = isEnabled;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton2OnClickListener(View.OnClickListener listener) {
if (listener != mButton2Info.mListener) {
mButton2Info.mListener = listener;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton3Visible(boolean isVisible) {
if (isVisible != mButton3Info.mIsVisible) {
mButton3Info.mIsVisible = isVisible;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton3Text(@StringRes int textResId) {
final String newText = getContext().getString(textResId);
if (!TextUtils.equals(newText, mButton3Info.mText)) {
mButton3Info.mText = newText;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton3Icon(@DrawableRes int iconResId) {
if (iconResId == 0) {
return this;
}
final Drawable icon;
try {
icon = getContext().getDrawable(iconResId);
mButton3Info.mIcon = icon;
notifyChanged();
} catch (Resources.NotFoundException exception) {
Log.e(TAG, "Resource does not exist: " + iconResId);
}
return this;
}
public ActionButtonPreference setButton3Enabled(boolean isEnabled) {
if (isEnabled != mButton3Info.mIsEnabled) {
mButton3Info.mIsEnabled = isEnabled;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton3OnClickListener(View.OnClickListener listener) {
if (listener != mButton3Info.mListener) {
mButton3Info.mListener = listener;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton4Visible(boolean isVisible) {
if (isVisible != mButton4Info.mIsVisible) {
mButton4Info.mIsVisible = isVisible;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton4Text(@StringRes int textResId) {
final String newText = getContext().getString(textResId);
if (!TextUtils.equals(newText, mButton4Info.mText)) {
mButton4Info.mText = newText;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton4Icon(@DrawableRes int iconResId) {
if (iconResId == 0) {
return this;
}
final Drawable icon;
try {
icon = getContext().getDrawable(iconResId);
mButton4Info.mIcon = icon;
notifyChanged();
} catch (Resources.NotFoundException exception) {
Log.e(TAG, "Resource does not exist: " + iconResId);
}
return this;
}
public ActionButtonPreference setButton4Enabled(boolean isEnabled) {
if (isEnabled != mButton4Info.mIsEnabled) {
mButton4Info.mIsEnabled = isEnabled;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton4OnClickListener(View.OnClickListener listener) {
if (listener != mButton4Info.mListener) {
mButton4Info.mListener = listener;
notifyChanged();
}
return this;
}
static class ButtonInfo {
private Button mButton;
private CharSequence mText;
private Drawable mIcon;
private View.OnClickListener mListener;
private boolean mIsEnabled = true;
private boolean mIsVisible = true;
void setUpButton() {
mButton.setText(mText);
mButton.setOnClickListener(mListener);
mButton.setEnabled(mIsEnabled);
mButton.setCompoundDrawablesWithIntrinsicBounds(
null /* left */, mIcon /* top */, null /* right */, null /* bottom */);
if (shouldBeVisible()) {
mButton.setVisibility(View.VISIBLE);
} else {
mButton.setVisibility(View.GONE);
}
}
/**
* By default, four buttons are visible.
* However, there are two cases which button should be invisible.
*
* 1. User set invisible for this button. ex: mIsVisible = false.
* 2. User didn't set any title or icon.
*
*/
private boolean shouldBeVisible() {
return mIsVisible && (!TextUtils.isEmpty(mText) || mIcon != null);
}
}
}

View File

@@ -55,7 +55,6 @@ import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.widget.ActionButtonPreference;
import com.android.settings.widget.EntityHeaderController;
import com.android.settings.wifi.WifiDialog;
import com.android.settings.wifi.WifiDialog.WifiDialogListener;
@@ -66,6 +65,7 @@ import com.android.settingslib.core.lifecycle.Lifecycle;
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.ActionButtonsPreference;
import com.android.settingslib.widget.LayoutPreference;
import com.android.settingslib.wifi.AccessPoint;
@@ -130,7 +130,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
private final MetricsFeatureProvider mMetricsFeatureProvider;
// UI elements - in order of appearance
private ActionButtonPreference mButtonsPref;
private ActionButtonsPreference mButtonsPref;
private EntityHeaderController mEntityHeaderController;
private Preference mSignalStrengthPref;
private Preference mLinkSpeedPref;
@@ -275,7 +275,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
setupEntityHeader(screen);
mButtonsPref = ((ActionButtonPreference) screen.findPreference(KEY_BUTTONS_PREF))
mButtonsPref = ((ActionButtonsPreference) screen.findPreference(KEY_BUTTONS_PREF))
.setButton1Text(R.string.forget)
.setButton1Icon(R.drawable.ic_settings_delete)
.setButton1OnClickListener(view -> forgetNetwork())

View File

@@ -16,6 +16,8 @@
package com.android.settings.applications;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doNothing;
@@ -30,9 +32,8 @@ import android.view.View;
import android.widget.Button;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.widget.ActionButtonPreference;
import com.android.settings.widget.ActionButtonPreferenceTest;
import com.android.settingslib.applications.StorageStatsSource.AppStorageStats;
import com.android.settingslib.widget.ActionButtonsPreference;
import org.junit.Before;
import org.junit.Test;
@@ -46,7 +47,7 @@ public class AppStorageSettingsTest {
@Mock
private AppStorageSizesController mSizesController;
private ActionButtonPreference mButtonsPref;
private ActionButtonsPreference mButtonsPref;
private AppStorageSettings mSettings;
private Button mLeftButton;
private Button mRightButton;
@@ -58,7 +59,7 @@ public class AppStorageSettingsTest {
mRightButton = new Button(RuntimeEnvironment.application);
mSettings = spy(new AppStorageSettings());
mSettings.mSizeController = mSizesController;
mButtonsPref = ActionButtonPreferenceTest.createMock();
mButtonsPref = createMock();
mSettings.mButtonsPref = mButtonsPref;
when(mButtonsPref.setButton1OnClickListener(any(View.OnClickListener.class)))
@@ -103,5 +104,22 @@ public class AppStorageSettingsTest {
verify(mSettings).handleClearDataClick();
verify(mSettings).handleClearCacheClick();
}
private ActionButtonsPreference createMock() {
final ActionButtonsPreference pref = mock(ActionButtonsPreference.class);
when(pref.setButton1Text(anyInt())).thenReturn(pref);
when(pref.setButton1Icon(anyInt())).thenReturn(pref);
when(pref.setButton1Enabled(anyBoolean())).thenReturn(pref);
when(pref.setButton1Visible(anyBoolean())).thenReturn(pref);
when(pref.setButton1OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
when(pref.setButton2Text(anyInt())).thenReturn(pref);
when(pref.setButton2Icon(anyInt())).thenReturn(pref);
when(pref.setButton2Enabled(anyBoolean())).thenReturn(pref);
when(pref.setButton2Visible(anyBoolean())).thenReturn(pref);
when(pref.setButton2OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
return pref;
}
}

View File

@@ -18,6 +18,7 @@ package com.android.settings.applications.appinfo;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
@@ -42,18 +43,18 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.UserManager;
import android.view.View;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.widget.ActionButtonPreference;
import com.android.settings.widget.ActionButtonPreferenceTest;
import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.widget.ActionButtonsPreference;
import org.junit.Before;
import org.junit.Test;
@@ -99,7 +100,7 @@ public class AppButtonsPreferenceControllerTest {
@Mock
private PackageInfo mPackageInfo;
private ActionButtonPreference mButtonPrefs;
private ActionButtonsPreference mButtonPrefs;
private Intent mUninstallIntent;
private AppButtonsPreferenceController mController;
@@ -127,7 +128,7 @@ public class AppButtonsPreferenceControllerTest {
mPackageInfo.packageName = PACKAGE_NAME;
mPackageInfo.applicationInfo = mAppInfo;
mButtonPrefs = ActionButtonPreferenceTest.createMock();
mButtonPrefs = createMock();
mController.mButtonsPref = mButtonPrefs;
mController.mPackageInfo = mPackageInfo;
@@ -390,4 +391,15 @@ public class AppButtonsPreferenceControllerTest {
return SettingsEnums.PAGE_UNKNOWN;
}
}
private ActionButtonsPreference createMock() {
final ActionButtonsPreference pref = mock(ActionButtonsPreference.class);
when(pref.setButton1Text(anyInt())).thenReturn(pref);
when(pref.setButton1Icon(anyInt())).thenReturn(pref);
when(pref.setButton1Enabled(anyBoolean())).thenReturn(pref);
when(pref.setButton1Visible(anyBoolean())).thenReturn(pref);
when(pref.setButton1OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
return pref;
}
}

View File

@@ -18,6 +18,8 @@ package com.android.settings.bluetooth;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
@@ -34,8 +36,7 @@ import androidx.fragment.app.FragmentTransaction;
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowBluetoothDevice;
import com.android.settings.widget.ActionButtonPreference;
import com.android.settings.widget.ActionButtonPreferenceTest;
import com.android.settingslib.widget.ActionButtonsPreference;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -47,7 +48,7 @@ import org.robolectric.annotation.Config;
@Config(shadows = SettingsShadowBluetoothDevice.class)
public class BluetoothDetailsButtonsControllerTest extends BluetoothDetailsControllerTestBase {
private BluetoothDetailsButtonsController mController;
private ActionButtonPreference mButtonsPref;
private ActionButtonsPreference mButtonsPref;
private Button mConnectButton;
private Button mForgetButton;
@@ -60,8 +61,9 @@ public class BluetoothDetailsButtonsControllerTest extends BluetoothDetailsContr
mConnectButton = buttons.findViewById(R.id.button2);
mForgetButton = buttons.findViewById(R.id.button1);
mController =
new BluetoothDetailsButtonsController(mContext, mFragment, mCachedDevice, mLifecycle);
mButtonsPref = ActionButtonPreferenceTest.createMock();
new BluetoothDetailsButtonsController(mContext, mFragment, mCachedDevice,
mLifecycle);
mButtonsPref = createMock();
when(mButtonsPref.getKey()).thenReturn(mController.getPreferenceKey());
when(mButtonsPref.setButton2OnClickListener(any(View.OnClickListener.class)))
.thenAnswer(invocation -> {
@@ -186,4 +188,21 @@ public class BluetoothDetailsButtonsControllerTest extends BluetoothDetailsContr
verify(mButtonsPref).setButton2Enabled(false);
}
private ActionButtonsPreference createMock() {
final ActionButtonsPreference pref = mock(ActionButtonsPreference.class);
when(pref.setButton1Text(anyInt())).thenReturn(pref);
when(pref.setButton1Icon(anyInt())).thenReturn(pref);
when(pref.setButton1Enabled(anyBoolean())).thenReturn(pref);
when(pref.setButton1Visible(anyBoolean())).thenReturn(pref);
when(pref.setButton1OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
when(pref.setButton2Text(anyInt())).thenReturn(pref);
when(pref.setButton2Icon(anyInt())).thenReturn(pref);
when(pref.setButton2Enabled(anyBoolean())).thenReturn(pref);
when(pref.setButton2Visible(anyBoolean())).thenReturn(pref);
when(pref.setButton2OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
return pref;
}
}

View File

@@ -28,6 +28,7 @@ import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.drawer.CategoryKey;
import org.junit.Before;
import org.junit.Test;
@@ -59,7 +60,7 @@ public class EnterprisePrivacySettingsTest {
assertThat(mSettings.getMetricsCategory())
.isEqualTo(MetricsEvent.ENTERPRISE_PRIVACY_SETTINGS);
assertThat(mSettings.getLogTag()).isEqualTo("EnterprisePrivacySettings");
assertThat(mSettings.getCategoryKey()).isNull();
assertThat(mSettings.getCategoryKey()).isEqualTo(CategoryKey.CATEGORY_ENTERPRISE_PRIVACY);
assertThat(mSettings.getPreferenceScreenResId())
.isEqualTo(R.xml.enterprise_privacy_settings);
}

View File

@@ -36,6 +36,7 @@ import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.SliceTester;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -49,12 +50,17 @@ import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
public class ConnectedDeviceSliceTest {
private static final String BLUETOOTH_SUMMARY = "BluetoothSummary";
private static final String BLUETOOTH_TITLE = "BluetoothTitle";
@Mock
private CachedBluetoothDevice mCachedBluetoothDevice;
private List<CachedBluetoothDevice> mCachedDevices = new ArrayList<CachedBluetoothDevice>();
private Context mContext;
private List<CachedBluetoothDevice> mBluetoothConnectedDeviceList;
private ConnectedDeviceSlice mConnectedDeviceSlice;
private Context mContext;
private IconCompat mIcon;
private PendingIntent mDetailIntent;
@Before
public void setUp() {
@@ -65,35 +71,63 @@ public class ConnectedDeviceSliceTest {
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
mConnectedDeviceSlice = spy(new ConnectedDeviceSlice(mContext));
// Mock the icon and detail intent of Bluetooth.
mIcon = IconCompat.createWithResource(mContext, R.drawable.ic_homepage_connected_device);
mDetailIntent = PendingIntent.getActivity(mContext, 0, new Intent("test action"), 0);
doReturn(mIcon).when(mConnectedDeviceSlice).getConnectedDeviceIcon(any());
doReturn(mDetailIntent).when(mConnectedDeviceSlice).getBluetoothDetailIntent(any());
// Initial Bluetooth connected device list.
mBluetoothConnectedDeviceList = new ArrayList<>();
}
@After
public void tearDown() {
if (!mBluetoothConnectedDeviceList.isEmpty()) {
mBluetoothConnectedDeviceList.clear();
}
}
@Test
public void getSlice_hasConnectedDevices_shouldBeCorrectSliceContent() {
final String title = "BluetoothTitle";
final String summary = "BluetoothSummary";
final IconCompat icon = IconCompat.createWithResource(mContext,
R.drawable.ic_homepage_connected_device);
final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0,
new Intent("test action"), 0);
doReturn(title).when(mCachedBluetoothDevice).getName();
doReturn(summary).when(mCachedBluetoothDevice).getConnectionSummary();
mCachedDevices.add(mCachedBluetoothDevice);
doReturn(mCachedDevices).when(mConnectedDeviceSlice).getBluetoothConnectedDevices();
doReturn(icon).when(mConnectedDeviceSlice).getConnectedDeviceIcon(any());
doReturn(pendingIntent).when(mConnectedDeviceSlice).getBluetoothDetailIntent(any());
public void getSlice_hasConnectedDevices_shouldHaveCorrectTitle() {
mockBluetoothDeviceList();
doReturn(mBluetoothConnectedDeviceList).when(
mConnectedDeviceSlice).getBluetoothConnectedDevices();
final Slice slice = mConnectedDeviceSlice.getSlice();
final List<SliceItem> sliceItems = slice.getItems();
SliceTester.assertTitle(sliceItems, title);
SliceTester.assertTitle(sliceItems,
mContext.getString(R.string.bluetooth_connected_devices));
}
@Test
public void getSlice_hasNoConnectedDevices_shouldReturnCorrectHeader() {
final List<CachedBluetoothDevice> connectedBluetoothList = new ArrayList<>();
doReturn(connectedBluetoothList).when(mConnectedDeviceSlice).getBluetoothConnectedDevices();
public void getSlice_hasConnectedDevices_shouldHaveCorrectContent() {
mockBluetoothDeviceList();
doReturn(mBluetoothConnectedDeviceList).when(
mConnectedDeviceSlice).getBluetoothConnectedDevices();
final Slice slice = mConnectedDeviceSlice.getSlice();
final List<SliceItem> sliceItems = slice.getItems();
SliceTester.assertTitle(sliceItems, BLUETOOTH_TITLE);
}
@Test
public void getSlice_noConnectedDevices_shouldHaveCorrectTitle() {
doReturn(mBluetoothConnectedDeviceList).when(
mConnectedDeviceSlice).getBluetoothConnectedDevices();
final Slice slice = mConnectedDeviceSlice.getSlice();
final List<SliceItem> sliceItems = slice.getItems();
SliceTester.assertTitle(sliceItems, mContext.getString(R.string.no_connected_devices));
}
private void mockBluetoothDeviceList() {
doReturn(BLUETOOTH_TITLE).when(mCachedBluetoothDevice).getName();
doReturn(BLUETOOTH_SUMMARY).when(mCachedBluetoothDevice).getConnectionSummary();
mBluetoothConnectedDeviceList.add(mCachedBluetoothDevice);
}
}

View File

@@ -16,13 +16,17 @@
package com.android.settings.notification;
import static junit.framework.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.AutomaticZenRule;
import android.app.NotificationManager;
import android.content.Context;
import android.provider.Settings;
@@ -31,161 +35,122 @@ import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.internal.util.reflection.FieldSetter;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RunWith(SettingsRobolectricTestRunner.class)
public class ZenModeAutomaticRulesPreferenceControllerTest {
private static final String GENERIC_RULE_NAME = "test";
private static final String DEFAULT_ID_1 = "DEFAULT_1";
private static final String DEFAULT_ID_2 = "DEFAULT_2";
private ZenModeAutomaticRulesPreferenceController mController;
private final List<String> mDefaultIds = Arrays.asList(DEFAULT_ID_1, DEFAULT_ID_2);
@Mock
private ZenModeBackend mBackend;
@Mock
private NotificationManager mNotificationManager;
@Mock
private PreferenceCategory mockPref;
@Mock
private NotificationManager.Policy mPolicy;
@Mock
private PreferenceScreen mPreferenceScreen;
@Mock
private ZenRulePreference mZenRulePreference;
private Context mContext;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
mContext = RuntimeEnvironment.application;
when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
mController = new ZenModeAutomaticRulesPreferenceController(mContext, mock(Fragment.class),
mock(Lifecycle.class));
mController = spy(new ZenModeAutomaticRulesPreferenceController(mContext, mock(Fragment.class),
null));
ReflectionHelpers.setField(mController, "mBackend", mBackend);
ReflectionHelpers.setField(mController, "mDefaultRuleIds", mDefaultIds);
when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
mockPref);
mController.displayPreference(mPreferenceScreen);
doReturn(mZenRulePreference).when(mController).createZenRulePreference(any());
}
@Test
public void updateState_checkRuleOrderingDescending() {
final int NUM_RULES = 4;
when(mNotificationManager.getAutomaticZenRules()).thenReturn(
mockAutoZenRulesDecreasingCreationTime(NUM_RULES));
public void testUpdateState_clearsPreferencesWhenAddingNewPreferences() {
final int NUM_RULES = 3;
Map<String, AutomaticZenRule> rMap = new HashMap<>();
Map.Entry<String, AutomaticZenRule>[] rules = mController.sortedRules();
assertEquals(NUM_RULES, rules.length);
String ruleId1 = "test1_id";
String ruleId2 = "test2_id";
String ruleId3 = "test3_id";
// check ordering, most recent should be at the bottom/end (ie higher creation time)
for (int i = 0; i < NUM_RULES; i++) {
assertEquals(GENERIC_RULE_NAME + (NUM_RULES - 1 - i), rules[i].getKey());
}
AutomaticZenRule autoRule1 = new AutomaticZenRule("test_rule_1", null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10);
AutomaticZenRule autoRule2 = new AutomaticZenRule("test_rule_2", null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 20);
AutomaticZenRule autoRule3 = new AutomaticZenRule("test_rule_3", null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 30);
rMap.put(ruleId1, autoRule1);
rMap.put(ruleId2, autoRule2);
rMap.put(ruleId3, autoRule3);
// should add 3 new preferences to mockPref
mockGetAutomaticZenRules(NUM_RULES, rMap);
mController.updateState(mockPref);
verify(mockPref, times(1)).removeAll();
verify(mockPref, times(NUM_RULES)).addPreference(any());
}
@Test
public void updateState_checkRuleOrderingAscending() {
final int NUM_RULES = 4;
when(mNotificationManager.getAutomaticZenRules()).thenReturn(
mockAutoZenRulesAscendingCreationTime(NUM_RULES));
public void testUpdateState_clearsPreferencesWhenRemovingPreferences(){
final int NUM_RULES = 2;
Map<String, AutomaticZenRule> rMap = new HashMap<>();
Map.Entry<String, AutomaticZenRule>[] rules = mController.sortedRules();
assertEquals(NUM_RULES, rules.length);
String ruleId1 = "test1_id";
String ruleId2 = "test2_id";
// check ordering, most recent should be at the bottom/end (ie higher creation time)
for (int i = 0; i < NUM_RULES; i++) {
assertEquals(GENERIC_RULE_NAME + i, rules[i].getKey());
}
AutomaticZenRule autoRule1 = new AutomaticZenRule("test_rule_1", null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10);
AutomaticZenRule autoRule2 = new AutomaticZenRule("test_rule_2", null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 20);
rMap.put(ruleId1, autoRule1);
rMap.put(ruleId2, autoRule2);
// update state should re-add all preferences since a preference was deleted
when(mockPref.getPreferenceCount()).thenReturn(NUM_RULES + 2);
mockGetAutomaticZenRules(NUM_RULES, rMap);
mController.updateState(mockPref);
verify(mockPref, times(1)).removeAll();
verify(mockPref, times(NUM_RULES)).addPreference(any());
}
@Test
public void updateState_checkRuleOrderingDescending_withDefaultRules() {
final int NUM_RULES = 4;
public void testUpdateState_updateEnableState() throws NoSuchFieldException {
final int NUM_RULES = 1;
Map<String, AutomaticZenRule> rMap = new HashMap<>();
String testId = "test1_id";
AutomaticZenRule rule = new AutomaticZenRule("rule_name", null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10);
rMap.put(testId, rule);
Map<String, AutomaticZenRule> ruleMap = mockAutoZenRulesDecreasingCreationTime(NUM_RULES);
ruleMap.put(DEFAULT_ID_2, new AutomaticZenRule("DEFAULT_1_NAME", null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 20));
ruleMap.put(DEFAULT_ID_1, new AutomaticZenRule("DEFAULT_1_NAME", null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10));
when(mNotificationManager.getAutomaticZenRules()).thenReturn(ruleMap);
when(mockPref.getPreferenceCount()).thenReturn(NUM_RULES);
when(mockPref.getPreference(anyInt())).thenReturn(mZenRulePreference);
Map.Entry<String, AutomaticZenRule>[] rules = mController.sortedRules();
assertEquals(NUM_RULES + 2, rules.length);
assertEquals(rules[0].getKey(), DEFAULT_ID_1);
assertEquals(rules[1].getKey(), DEFAULT_ID_2);
// NON-DEFAULT RULES check ordering, most recent at the bottom/end
for (int i = 0; i < NUM_RULES; i++) {
assertEquals(GENERIC_RULE_NAME + (NUM_RULES - 1 - i), rules[i + 2].getKey());
}
// update state should NOT re-add all the preferences, should only update enable state
rule.setEnabled(false);
rMap.put(testId, rule);
mockGetAutomaticZenRules(NUM_RULES, rMap);
FieldSetter.setField(mZenRulePreference, ZenRulePreference.class.getDeclaredField("mId"), testId);
mController.updateState(mockPref);
verify(mZenRulePreference, times(1)).setChecked(false);
verify(mController, never()).reloadAllRules(any());
}
@Test
public void updateState_checkRuleOrderingMix() {
final int NUM_RULES = 4;
// map with creation times: 0, 2, 4, 6
Map<String,AutomaticZenRule> rMap = mockAutoZenRulesAscendingCreationTime(NUM_RULES);
final String insertedRule1 = "insertedRule1";
rMap.put(insertedRule1, new AutomaticZenRule(insertedRule1, null, null,
Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 5));
final String insertedRule2 = "insertedRule2";
rMap.put(insertedRule2, new AutomaticZenRule(insertedRule2, null, null,
Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 3));
// rule map with rule creation times, 0, 2, 4, 6, 5, 3
// sort should create ordering based on creation times: 0, 2, 3, 4, 5, 6
when(mNotificationManager.getAutomaticZenRules()).thenReturn(rMap);
Map.Entry<String, AutomaticZenRule>[] rules = mController.sortedRules();
assertEquals(NUM_RULES + 2, rules.length); // inserted 2 rules
// check ordering of inserted rules
assertEquals(insertedRule1, rules[4].getKey());
assertEquals(insertedRule2, rules[2].getKey());
}
private Map<String, AutomaticZenRule> mockAutoZenRulesAscendingCreationTime(int numRules) {
Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
for (int i = 0; i < numRules; i++) {
ruleMap.put(GENERIC_RULE_NAME + i, new AutomaticZenRule(GENERIC_RULE_NAME + i, null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, i * 2));
}
return ruleMap;
}
private Map<String, AutomaticZenRule> mockAutoZenRulesDecreasingCreationTime(int numRules) {
Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
for (int i = 0; i < numRules; i++) {
ruleMap.put(GENERIC_RULE_NAME + i, new AutomaticZenRule(GENERIC_RULE_NAME + i, null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, numRules - i));
}
return ruleMap;
private void mockGetAutomaticZenRules(int numRules, Map<String, AutomaticZenRule> rules) {
Map.Entry<String, AutomaticZenRule>[] arr = new Map.Entry[numRules];
rules.entrySet().toArray(arr);
when(mBackend.getAutomaticZenRules()).thenReturn(arr);
}
}

View File

@@ -0,0 +1,108 @@
package com.android.settings.notification;
import static junit.framework.Assert.assertEquals;
import android.app.AutomaticZenRule;
import android.provider.Settings;
import android.service.notification.ZenModeConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@RunWith(SettingsRobolectricTestRunner.class)
public class ZenModeBackendTest {
private static final String GENERIC_RULE_NAME = "test";
private static final String DEFAULT_ID_1 = ZenModeConfig.EVENTS_DEFAULT_RULE_ID;
private static final String DEFAULT_ID_2 = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
@Test
public void updateState_checkRuleOrderingDescending() {
final int NUM_RULES = 4;
Map.Entry<String, AutomaticZenRule>[] rules = populateAutoZenRulesDescendingCreationTime(
NUM_RULES, false);
Arrays.sort(rules, ZenModeBackend.RULE_COMPARATOR);
// check ordering, most recent should be at the end
for (int i = 0; i < NUM_RULES; i++) {
assertEquals(GENERIC_RULE_NAME + (NUM_RULES - 1 - i), rules[i].getKey());
}
}
@Test
public void updateState_checkRuleOrderingAscending() {
final int NUM_RULES = 4;
Map.Entry<String, AutomaticZenRule>[] rules = populateAutoZenRulesAscendingCreationTime(
NUM_RULES, false);
Arrays.sort(rules, ZenModeBackend.RULE_COMPARATOR);
// check ordering, most recent should be at the end
for (int i = 0; i < NUM_RULES; i++) {
assertEquals(GENERIC_RULE_NAME + i, rules[i].getKey());
}
}
@Test
public void updateState_checkRuleOrderingDescending_withDefaultRules() {
final int NUM_RULES = 4;
Map.Entry<String, AutomaticZenRule>[] rules = populateAutoZenRulesDescendingCreationTime(NUM_RULES,
true);
Arrays.sort(rules, ZenModeBackend.RULE_COMPARATOR);
assertEquals(rules[0].getKey(), DEFAULT_ID_1);
assertEquals(rules[1].getKey(), DEFAULT_ID_2);
// NON-DEFAULT RULES check ordering, most recent at the bottom/end
for (int i = 0; i < NUM_RULES; i++) {
assertEquals(GENERIC_RULE_NAME + (NUM_RULES - 1 - i), rules[i + 2].getKey());
}
}
private Map.Entry<String, AutomaticZenRule>[] populateAutoZenRulesAscendingCreationTime(
int numRules, boolean addDefaultRules) {
Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
for (int i = 0; i < numRules; i++) {
ruleMap.put(GENERIC_RULE_NAME + i, new AutomaticZenRule(GENERIC_RULE_NAME + i, null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, i * 2));
}
if (addDefaultRules) {
ruleMap.put(DEFAULT_ID_1, new AutomaticZenRule("DEFAULT_1_NAME", null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 20));
ruleMap.put(DEFAULT_ID_2, new AutomaticZenRule("DEFAULT_2_NAME", null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10));
}
Map.Entry<String, AutomaticZenRule>[] toReturn = new Map.Entry[ruleMap.size()];
ruleMap.entrySet().toArray(toReturn);
return toReturn;
}
private Map.Entry<String, AutomaticZenRule>[] populateAutoZenRulesDescendingCreationTime(
int numRules, boolean addDefaultRules) {
Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
for (int i = 0; i < numRules; i++) {
ruleMap.put(GENERIC_RULE_NAME + i, new AutomaticZenRule(GENERIC_RULE_NAME + i, null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, numRules - i));
}
if (addDefaultRules) {
ruleMap.put(DEFAULT_ID_1, new AutomaticZenRule("DEFAULT_1_NAME", null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10));
ruleMap.put(DEFAULT_ID_2, new AutomaticZenRule("DEFAULT_2_NAME", null,
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 20));
}
Map.Entry<String, AutomaticZenRule>[] toReturn = new Map.Entry[ruleMap.size()];
ruleMap.entrySet().toArray(toReturn);
return toReturn;
}
}

View File

@@ -126,7 +126,7 @@ public class ZenModeSettingsFooterPreferenceControllerTest {
}
@Test
public void app_manualRule_setFooterTitle() {
public void testDefaultNotifPolicy_app_manualRule_setFooterTitle() {
Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
injectManualRuleFromApp();
mController.updateState(mockPref);
@@ -137,7 +137,7 @@ public class ZenModeSettingsFooterPreferenceControllerTest {
}
@Test
public void time_manualRule_setFooterTitle() {
public void testDefaultNotifPolicy_time_manualRule_setFooterTitle() {
Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
String placeholder = "placeholder";
injectManualRuleWithTimeCountdown(1000, placeholder);
@@ -148,7 +148,7 @@ public class ZenModeSettingsFooterPreferenceControllerTest {
}
@Test
public void forever_manualRule_setFooterTitle() {
public void testDefaultNotifPolicy_forever_manualRule_setFooterTitle() {
Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
injectManualRuleWithIndefiniteEnd();
mController.updateState(mockPref);
@@ -158,7 +158,7 @@ public class ZenModeSettingsFooterPreferenceControllerTest {
}
@Test
public void automaticRule_noManualRule_setFooterTitle() {
public void testDefaultNotifPolicy_automaticRule_noManualRule_setFooterTitle() {
Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
// no manual rule
ReflectionHelpers.setField(mZenModeConfig, MANUAL_RULE_FIELD, null);
@@ -174,7 +174,7 @@ public class ZenModeSettingsFooterPreferenceControllerTest {
}
@Test
public void manualRuleEndsLast_hasAutomaticRule_setFooterTitle() {
public void testDefaultNotifPolicy_manualRuleEndsLast_hasAutomaticRule_setFooterTitle() {
Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
// manual rule that ends after automatic rule ends
injectManualRuleWithIndefiniteEnd();
@@ -190,7 +190,7 @@ public class ZenModeSettingsFooterPreferenceControllerTest {
}
@Test
public void automaticRuleEndsLast_hasManualRule_setFooterTitle() {
public void testDefaultNotifPolicy_automaticRuleEndsLast_hasManualRule_setFooterTitle() {
Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
// manual rule that ends before automatic rule ends
injectManualRuleWithTimeCountdown(1000, "");
@@ -208,14 +208,15 @@ public class ZenModeSettingsFooterPreferenceControllerTest {
}
@Test
public void multipleAutomaticRules_appAutoRuleautomaticRuleApp_setFooterTitle() {
public void testDefaultNotifPolicy_multipleAutomaticRules_autoRuleApp_setFooterTitle() {
Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
// automatic rule that ends after manual rule ends
ZenRule rule1 = injectNewAutomaticRule(TEST_RULE_NAME + "1", false, false);
when(mConfigWrapper.parseAutomaticRuleEndTime(rule1.conditionId)).thenReturn(10000L);
ZenRule rule2 = injectNewAutomaticRule(TEST_RULE_NAME + "2", true, true);
// automatic rule that is an app
injectNewAutomaticRule(TEST_RULE_NAME + "2", true, true);
ZenRule rule3 = injectNewAutomaticRule(TEST_RULE_NAME + "3", true, false);
when(mConfigWrapper.parseAutomaticRuleEndTime(rule3.conditionId)).thenReturn(9000L);
@@ -229,7 +230,7 @@ public class ZenModeSettingsFooterPreferenceControllerTest {
}
@Test
public void multipleAutomaticRules_setFooterTitle() {
public void testDefaultNotifPolicy_multipleAutomaticRules_setFooterTitle() {
Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
// automatic rule that ends after manual rule ends

View File

@@ -61,7 +61,6 @@ public class PanelFragmentTest {
mFakePanelContent = new FakePanelContent();
doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any());
ActivityController<FakeSettingsPanelActivity> activityController =
Robolectric.buildActivity(FakeSettingsPanelActivity.class);
activityController.setup();

View File

@@ -54,7 +54,13 @@ public class PanelSlicesAdapterTest {
public void setUp() {
mContext = RuntimeEnvironment.application;
final ActivityController<FakeSettingsPanelActivity> activityController =
mPanelFeatureProvider = spy(new PanelFeatureProviderImpl());
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
mFakeFeatureFactory.panelFeatureProvider = mPanelFeatureProvider;
mFakePanelContent = new FakePanelContent();
doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any());
ActivityController<FakeSettingsPanelActivity> activityController =
Robolectric.buildActivity(FakeSettingsPanelActivity.class);
activityController.setup();
@@ -65,12 +71,6 @@ public class PanelSlicesAdapterTest {
.getSupportFragmentManager()
.findFragmentById(R.id.main_content));
mPanelFeatureProvider = spy(new PanelFeatureProviderImpl());
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
mFakeFeatureFactory.panelFeatureProvider = mPanelFeatureProvider;
mFakePanelContent = new FakePanelContent();
doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any());
mAdapter = new PanelSlicesAdapter(mPanelFragment, mFakePanelContent.getSlices());
}

View File

@@ -0,0 +1,58 @@
/*
* 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.panel;
import static com.google.common.truth.Truth.assertThat;
import android.net.Uri;
import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
public class VolumePanelTest {
private VolumePanel mPanel;
@Before
public void setUp() {
mPanel = VolumePanel.create(RuntimeEnvironment.application);
}
@Test
public void getSlices_containsNecessarySlices() {
final List<Uri> uris = mPanel.getSlices();
assertThat(uris).containsExactly(
CustomSliceRegistry.VOLUME_CALL_URI,
CustomSliceRegistry.VOLUME_MEDIA_URI,
CustomSliceRegistry.VOLUME_RINGER_URI,
CustomSliceRegistry.VOLUME_ALARM_URI);
}
@Test
public void getSeeMoreIntent_notNull() {
assertThat(mPanel.getSeeMoreIntent()).isNotNull();
}
}

View File

@@ -217,6 +217,19 @@ public class SliceBuilderUtilsTest {
assertThat(summary).isEqualTo(controllerSummary);
}
@Test
public void getDynamicSummary_allowDynamicSummary_nullSummary_returnsNull() {
final SliceData data = getDummyData(true /*isDynamicSummaryAllowed*/);
final FakePreferenceController controller = spy(
new FakePreferenceController(mContext, KEY));
final String controllerSummary = null;
doReturn(controllerSummary).when(controller).getSummary();
final CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
assertThat(summary).isNull();
}
@Test
public void getDynamicSummary_returnsScreenTitle() {
final SliceData data = getDummyData();

View File

@@ -83,6 +83,8 @@ public class SettingsRobolectricTestRunner extends RobolectricTestRunner {
Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/RestrictedLockUtils/res/")), null));
paths.add(new ResourcePath(null,
Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/SearchWidget/res/")), null));
paths.add(new ResourcePath(null,
Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/ActionButtonsPreference/res")), null));
paths.add(new ResourcePath(null,
Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/SettingsLayoutPreference/res")), null));
paths.add(new ResourcePath(null,

View File

@@ -1,283 +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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.Button;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
@RunWith(SettingsRobolectricTestRunner.class)
public class ActionButtonPreferenceTest {
private Context mContext;
private View mRootView;
private ActionButtonPreference mPref;
private PreferenceViewHolder mHolder;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mRootView = View.inflate(mContext, R.layout.settings_action_buttons, null /* parent */);
mHolder = PreferenceViewHolder.createInstanceForTests(mRootView);
mPref = new ActionButtonPreference(mContext);
}
@Test
public void onBindViewHolder_setTitle_shouldShowButtonByDefault() {
mPref.setButton1Text(R.string.settings_label);
mPref.setButton2Text(R.string.settings_label);
mPref.setButton3Text(R.string.settings_label);
mPref.setButton4Text(R.string.settings_label);
mPref.onBindViewHolder(mHolder);
assertThat(mRootView.findViewById(R.id.button1).getVisibility())
.isEqualTo(View.VISIBLE);
assertThat(mRootView.findViewById(R.id.button2).getVisibility())
.isEqualTo(View.VISIBLE);
assertThat(mRootView.findViewById(R.id.button3).getVisibility())
.isEqualTo(View.VISIBLE);
assertThat(mRootView.findViewById(R.id.button4).getVisibility())
.isEqualTo(View.VISIBLE);
}
@Test
public void onBindViewHolder_setIcon_shouldShowButtonByDefault() {
mPref.setButton1Icon(R.drawable.ic_settings);
mPref.setButton2Icon(R.drawable.ic_settings);
mPref.setButton3Icon(R.drawable.ic_settings);
mPref.setButton4Icon(R.drawable.ic_settings);
mPref.onBindViewHolder(mHolder);
assertThat(mRootView.findViewById(R.id.button1).getVisibility())
.isEqualTo(View.VISIBLE);
assertThat(mRootView.findViewById(R.id.button2).getVisibility())
.isEqualTo(View.VISIBLE);
assertThat(mRootView.findViewById(R.id.button3).getVisibility())
.isEqualTo(View.VISIBLE);
assertThat(mRootView.findViewById(R.id.button4).getVisibility())
.isEqualTo(View.VISIBLE);
}
@Test
public void onBindViewHolder_notSetTitleOrIcon_shouldNotShowButtonByDefault() {
mPref.onBindViewHolder(mHolder);
assertThat(mRootView.findViewById(R.id.button1).getVisibility())
.isEqualTo(View.GONE);
assertThat(mRootView.findViewById(R.id.button2).getVisibility())
.isEqualTo(View.GONE);
assertThat(mRootView.findViewById(R.id.button3).getVisibility())
.isEqualTo(View.GONE);
assertThat(mRootView.findViewById(R.id.button4).getVisibility())
.isEqualTo(View.GONE);
}
@Test
public void onBindViewHolder_setVisibleIsGoneAndSetTitle_shouldNotShowButton() {
mPref.setButton1Text(R.string.settings_label).setButton1Visible(false);
mPref.setButton2Text(R.string.settings_label).setButton2Visible(false);
mPref.setButton3Text(R.string.settings_label).setButton3Visible(false);
mPref.setButton4Text(R.string.settings_label).setButton4Visible(false);
mPref.onBindViewHolder(mHolder);
assertThat(mRootView.findViewById(R.id.button1).getVisibility())
.isEqualTo(View.GONE);
assertThat(mRootView.findViewById(R.id.button2).getVisibility())
.isEqualTo(View.GONE);
assertThat(mRootView.findViewById(R.id.button3).getVisibility())
.isEqualTo(View.GONE);
assertThat(mRootView.findViewById(R.id.button4).getVisibility())
.isEqualTo(View.GONE);
}
@Test
public void onBindViewHolder_setVisibleIsGoneAndSetIcon_shouldNotShowButton() {
mPref.setButton1Icon(R.drawable.ic_settings).setButton1Visible(false);
mPref.setButton2Icon(R.drawable.ic_settings).setButton2Visible(false);
mPref.setButton3Icon(R.drawable.ic_settings).setButton3Visible(false);
mPref.setButton4Icon(R.drawable.ic_settings).setButton4Visible(false);
mPref.onBindViewHolder(mHolder);
assertThat(mRootView.findViewById(R.id.button1).getVisibility())
.isEqualTo(View.GONE);
assertThat(mRootView.findViewById(R.id.button2).getVisibility())
.isEqualTo(View.GONE);
assertThat(mRootView.findViewById(R.id.button3).getVisibility())
.isEqualTo(View.GONE);
assertThat(mRootView.findViewById(R.id.button4).getVisibility())
.isEqualTo(View.GONE);
}
@Test
public void onBindViewHolder_setVisibility_shouldUpdateButtonVisibility() {
mPref.setButton1Text(R.string.settings_label).setButton1Visible(false);
mPref.setButton2Text(R.string.settings_label).setButton2Visible(false);
mPref.setButton3Text(R.string.settings_label).setButton3Visible(false);
mPref.setButton4Text(R.string.settings_label).setButton4Visible(false);
mPref.onBindViewHolder(mHolder);
assertThat(mRootView.findViewById(R.id.button1).getVisibility())
.isEqualTo(View.GONE);
assertThat(mRootView.findViewById(R.id.button2).getVisibility())
.isEqualTo(View.GONE);
assertThat(mRootView.findViewById(R.id.button3).getVisibility())
.isEqualTo(View.GONE);
assertThat(mRootView.findViewById(R.id.button4).getVisibility())
.isEqualTo(View.GONE);
mPref.setButton1Visible(true);
mPref.setButton2Visible(true);
mPref.setButton3Visible(true);
mPref.setButton4Visible(true);
mPref.onBindViewHolder(mHolder);
assertThat(mRootView.findViewById(R.id.button1).getVisibility())
.isEqualTo(View.VISIBLE);
assertThat(mRootView.findViewById(R.id.button2).getVisibility())
.isEqualTo(View.VISIBLE);
assertThat(mRootView.findViewById(R.id.button3).getVisibility())
.isEqualTo(View.VISIBLE);
assertThat(mRootView.findViewById(R.id.button4).getVisibility())
.isEqualTo(View.VISIBLE);
}
@Test
public void onBindViewHolder_setEnabled_shouldEnableButton() {
mPref.setButton1Enabled(true);
mPref.setButton2Enabled(false);
mPref.setButton3Enabled(true);
mPref.setButton4Enabled(false);
mPref.onBindViewHolder(mHolder);
assertThat(mRootView.findViewById(R.id.button1).isEnabled()).isTrue();
assertThat(mRootView.findViewById(R.id.button2).isEnabled()).isFalse();
assertThat(mRootView.findViewById(R.id.button3).isEnabled()).isTrue();
assertThat(mRootView.findViewById(R.id.button4).isEnabled()).isFalse();
}
@Test
public void onBindViewHolder_setText_shouldShowSameText() {
mPref.setButton1Text(R.string.settings_label);
mPref.setButton2Text(R.string.settings_label);
mPref.setButton3Text(R.string.settings_label);
mPref.setButton4Text(R.string.settings_label);
mPref.onBindViewHolder(mHolder);
assertThat(((Button) mRootView.findViewById(R.id.button1)).getText())
.isEqualTo(mContext.getText(R.string.settings_label));
assertThat(((Button) mRootView.findViewById(R.id.button2)).getText())
.isEqualTo(mContext.getText(R.string.settings_label));
assertThat(((Button) mRootView.findViewById(R.id.button3)).getText())
.isEqualTo(mContext.getText(R.string.settings_label));
assertThat(((Button) mRootView.findViewById(R.id.button4)).getText())
.isEqualTo(mContext.getText(R.string.settings_label));
}
@Test
public void onBindViewHolder_setButtonIcon_iconMustDisplayAboveText() {
mPref.setButton1Text(R.string.settings_label);
mPref.setButton1Icon(R.drawable.ic_settings);
mPref.onBindViewHolder(mHolder);
final Drawable[] drawablesAroundText =
((Button) mRootView.findViewById(R.id.button1))
.getCompoundDrawables();
assertThat(drawablesAroundText[1 /* top */]).isNotNull();
}
@Test
public void setButtonIcon_iconResourceIdIsZero_shouldNotDisplayIcon() {
mPref.setButton1Text(R.string.settings_label);
mPref.setButton1Icon(0);
mPref.onBindViewHolder(mHolder);
final Drawable[] drawablesAroundText =
((Button) mRootView.findViewById(R.id.button1))
.getCompoundDrawables();
assertThat(drawablesAroundText[1 /* top */]).isNull();
}
@Test
public void setButtonIcon_iconResourceIdNotExisting_shouldNotDisplayIconAndCrash() {
mPref.setButton1Text(R.string.settings_label);
mPref.setButton1Icon(999999999 /* not existing id */);
// Should not crash here
mPref.onBindViewHolder(mHolder);
final Drawable[] drawablesAroundText =
((Button) mRootView.findViewById(R.id.button1))
.getCompoundDrawables();
assertThat(drawablesAroundText[1 /* top */]).isNull();
}
public static ActionButtonPreference createMock() {
final ActionButtonPreference pref = mock(ActionButtonPreference.class);
when(pref.setButton1Text(anyInt())).thenReturn(pref);
when(pref.setButton1Icon(anyInt())).thenReturn(pref);
when(pref.setButton1Enabled(anyBoolean())).thenReturn(pref);
when(pref.setButton1Visible(anyBoolean())).thenReturn(pref);
when(pref.setButton1OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
when(pref.setButton2Text(anyInt())).thenReturn(pref);
when(pref.setButton2Icon(anyInt())).thenReturn(pref);
when(pref.setButton2Enabled(anyBoolean())).thenReturn(pref);
when(pref.setButton2Visible(anyBoolean())).thenReturn(pref);
when(pref.setButton2OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
when(pref.setButton3Text(anyInt())).thenReturn(pref);
when(pref.setButton3Icon(anyInt())).thenReturn(pref);
when(pref.setButton3Enabled(anyBoolean())).thenReturn(pref);
when(pref.setButton3Visible(anyBoolean())).thenReturn(pref);
when(pref.setButton3OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
when(pref.setButton4Text(anyInt())).thenReturn(pref);
when(pref.setButton4Icon(anyInt())).thenReturn(pref);
when(pref.setButton4Enabled(anyBoolean())).thenReturn(pref);
when(pref.setButton4Visible(anyBoolean())).thenReturn(pref);
when(pref.setButton4OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
return pref;
}
}

View File

@@ -17,12 +17,14 @@ package com.android.settings.wifi.details;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
@@ -67,11 +69,10 @@ import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowBidiFormatter;
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
import com.android.settings.widget.ActionButtonPreference;
import com.android.settings.widget.ActionButtonPreferenceTest;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.widget.ActionButtonsPreference;
import com.android.settingslib.widget.LayoutPreference;
import com.android.settingslib.wifi.AccessPoint;
@@ -142,7 +143,7 @@ public class WifiDetailPreferenceControllerTest {
private ImageView mockHeaderIcon;
@Mock
private ActionButtonPreference mockButtonsPref;
private ActionButtonsPreference mockButtonsPref;
@Mock
private Preference mockSignalStrengthPref;
@Mock
@@ -247,7 +248,7 @@ public class WifiDetailPreferenceControllerTest {
.thenReturn(mockNetworkInfo);
doNothing().when(mockConnectivityManager).registerNetworkCallback(
nullable(NetworkRequest.class), mCallbackCaptor.capture(), nullable(Handler.class));
mockButtonsPref = ActionButtonPreferenceTest.createMock();
mockButtonsPref = createMock();
when(mockButtonsPref.setButton1OnClickListener(mForgetClickListener.capture()))
.thenReturn(mockButtonsPref);
@@ -849,4 +850,21 @@ public class WifiDetailPreferenceControllerTest {
verify(mockAccessPoint, times(2)).getLevel();
verify(mockIconInjector, times(2)).getIcon(anyInt());
}
private ActionButtonsPreference createMock() {
final ActionButtonsPreference pref = mock(ActionButtonsPreference.class);
when(pref.setButton1Text(anyInt())).thenReturn(pref);
when(pref.setButton1Icon(anyInt())).thenReturn(pref);
when(pref.setButton1Enabled(anyBoolean())).thenReturn(pref);
when(pref.setButton1Visible(anyBoolean())).thenReturn(pref);
when(pref.setButton1OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
when(pref.setButton2Text(anyInt())).thenReturn(pref);
when(pref.setButton2Icon(anyInt())).thenReturn(pref);
when(pref.setButton2Enabled(anyBoolean())).thenReturn(pref);
when(pref.setButton2Visible(anyBoolean())).thenReturn(pref);
when(pref.setButton2OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
return pref;
}
}