diff --git a/res/drawable/ic_event.xml b/res/drawable/ic_event.xml
new file mode 100644
index 00000000000..a82d7544985
--- /dev/null
+++ b/res/drawable/ic_event.xml
@@ -0,0 +1,34 @@
+
+
+
+ -
+
+
+
+
+
+
+
+
diff --git a/res/drawable/ic_event_white.xml b/res/drawable/ic_event_white.xml
new file mode 100644
index 00000000000..d80429b7ec0
--- /dev/null
+++ b/res/drawable/ic_event_white.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/res/drawable/ic_timelapse.xml b/res/drawable/ic_timelapse.xml
new file mode 100644
index 00000000000..ba97bae8c90
--- /dev/null
+++ b/res/drawable/ic_timelapse.xml
@@ -0,0 +1,34 @@
+
+
+
+ -
+
+
+
+
+
+
+
+
diff --git a/res/drawable/ic_timelapse_white.xml b/res/drawable/ic_timelapse_white.xml
new file mode 100644
index 00000000000..f287747d2bc
--- /dev/null
+++ b/res/drawable/ic_timelapse_white.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/res/layout/battery_saver_settings_button.xml b/res/layout/battery_saver_settings_button.xml
new file mode 100644
index 00000000000..015d4d88f86
--- /dev/null
+++ b/res/layout/battery_saver_settings_button.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/search_feedback.xml b/res/layout/preference_widget_gear_no_bg.xml
similarity index 64%
rename from res/layout/search_feedback.xml
rename to res/layout/preference_widget_gear_no_bg.xml
index cdb0545d8a4..89d34d4adda 100644
--- a/res/layout/search_feedback.xml
+++ b/res/layout/preference_widget_gear_no_bg.xml
@@ -1,5 +1,5 @@
-
-
+
-
+ android:id="@+id/settings_button"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:scaleType="center"
+ android:src="@drawable/ic_settings"
+ android:contentDescription="@string/settings_button" />
+
diff --git a/res/layout/search_inline_switch_item.xml b/res/layout/search_inline_switch_item.xml
deleted file mode 100644
index 8f050a35d84..00000000000
--- a/res/layout/search_inline_switch_item.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/res/layout/search_intent_item.xml b/res/layout/search_intent_item.xml
deleted file mode 100644
index 6bc00ad06b9..00000000000
--- a/res/layout/search_intent_item.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/res/layout/search_panel.xml b/res/layout/search_panel.xml
deleted file mode 100644
index 10c2a00ee8e..00000000000
--- a/res/layout/search_panel.xml
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/res/layout/settings_main_dashboard.xml b/res/layout/settings_main_dashboard.xml
index 4f8c3089759..10ff2eeff30 100644
--- a/res/layout/settings_main_dashboard.xml
+++ b/res/layout/settings_main_dashboard.xml
@@ -43,7 +43,6 @@
android:background="?android:attr/selectableItemBackground"
android:contentInsetStartWithNavigation="64dp"
android:navigationIcon="@drawable/ic_search_24dp"
- android:navigationContentDescription="@string/search_menu"
android:theme="?android:attr/actionBarTheme">
+ android:layout_height="wrap_content">
+ android:text="@string/zen_mode_button_turn_on"/>
+ android:text="@string/zen_mode_button_turn_off" />
\ No newline at end of file
diff --git a/res/layout/zen_rule_type.xml b/res/layout/zen_rule_type.xml
index a6675c9ac12..dea39edcc88 100644
--- a/res/layout/zen_rule_type.xml
+++ b/res/layout/zen_rule_type.xml
@@ -23,10 +23,9 @@
+ android:layout_width="@dimen/app_icon_size"
+ android:layout_height="@dimen/app_icon_size"
+ android:layout_gravity="center"/>
56dp
- 384dp
- 188dp
180dp
22dp
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index fbc7490957a..6ede7c644af 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -304,8 +304,6 @@
24dp
- 332dp
- 162dp
156dp
14dp
12dp
diff --git a/res/values/strings.xml b/res/values/strings.xml
index cae56078d8f..5fbbf4da961 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2423,13 +2423,6 @@
Search
-
- Manage search settings and history
-
- No results
-
-
- Clear history
@@ -4431,6 +4424,12 @@
Click after pointer stops moving
Delay before click
+
+ Vibration
+
+ Ring & notification vibration
+
+ Touch vibration
Use service
@@ -4474,6 +4473,30 @@
- Very long delay (%1$d ms)
+
+ Ring & notification set to off
+
+
+ Ring & notification set to low
+
+
+ Ring & notification set to medium
+
+
+ Ring & notification set to high
+
+
+ Off
+
+
+ Low
+
+
+ Medium
+
+
+ High
+
Settings
@@ -5136,8 +5159,17 @@
App optimization
-
- Battery Saver
+
+ Reduced power mode
+
+
+ Schedule
+
+
+ Turn on Reduced power mode automatically when battery is low
+
+
+ Turn on automatically at %1$s
Use Battery Saver
@@ -6972,6 +7004,21 @@
%1$s. %2$s
+
+ On / %1$s
+
+
+ Off / %1$s
+
+
+ Off
+
+
+
+ - 1 rule can turn on automatically
+ - %d rules can turn on automatically
+
+
Work profile sounds
@@ -7106,10 +7153,10 @@
summary on the channel page-->
- No sound or visual interruption
+ Show silently and minimize
- No sound
+ Show silently
Make sound
@@ -8695,6 +8742,12 @@
Turn on automatically at %1$s battery
+
+ Turn on now
+
+
+ Turn off now
+
Not using battery optimization
@@ -9249,6 +9302,9 @@
+
+
+
What\'s new and exciting?
diff --git a/res/layout/search_breadcrumb_view.xml b/res/xml/accessibility_notification_vibration_settings.xml
similarity index 63%
rename from res/layout/search_breadcrumb_view.xml
rename to res/xml/accessibility_notification_vibration_settings.xml
index 08a2651c4d8..b37d3636db1 100644
--- a/res/layout/search_breadcrumb_view.xml
+++ b/res/xml/accessibility_notification_vibration_settings.xml
@@ -1,6 +1,6 @@
-
+ android:title="@string/accessibility_notification_vibration_title" />
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index b5da848eb30..060868e37fc 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -93,6 +93,12 @@
android:entries="@array/long_press_timeout_selector_titles"
android:entryValues="@array/long_press_timeout_selector_values"
android:persistent="false"/>
+
+
+
+
+
+
diff --git a/res/xml/accessibility_vibration_settings.xml b/res/xml/accessibility_vibration_settings.xml
new file mode 100644
index 00000000000..d61454d0b46
--- /dev/null
+++ b/res/xml/accessibility_vibration_settings.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
diff --git a/res/xml/battery_saver_settings.xml b/res/xml/battery_saver_settings.xml
index 1720c73749e..47199c2d66e 100644
--- a/res/xml/battery_saver_settings.xml
+++ b/res/xml/battery_saver_settings.xml
@@ -14,14 +14,32 @@
limitations under the License.
-->
-
+
-
+
+
+
+
+
+
+
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index d7c3c3916da..fbe4e0d32ca 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -23,7 +23,7 @@
diff --git a/res/xml/power_usage_summary_legacy.xml b/res/xml/power_usage_summary_legacy.xml
index 0038cc0fb2f..059c737f6c5 100644
--- a/res/xml/power_usage_summary_legacy.xml
+++ b/res/xml/power_usage_summary_legacy.xml
@@ -51,7 +51,7 @@
android:title="@string/battery_power_management">
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 3c18efb5f6b..01818e99313 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -16,6 +16,8 @@
package com.android.settings;
+import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO;
+
import android.app.ActionBar;
import android.app.ActivityManager;
import android.app.Fragment;
@@ -329,6 +331,7 @@ public class SettingsActivity extends SettingsDrawerActivity
// and goes to the search UI. Also set the background to null so there's no ripple.
View navView = toolbar.getNavigationView();
navView.setClickable(false);
+ navView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
navView.setBackground(null);
}
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index df8d4c8b4b3..7335baec401 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -16,6 +16,8 @@
package com.android.settings.accessibility;
+import static android.os.Vibrator.VibrationIntensity;
+
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
@@ -28,6 +30,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
+import android.os.Vibrator;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
@@ -111,6 +114,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
"tts_settings_preference";
private static final String AUTOCLICK_PREFERENCE_SCREEN =
"autoclick_preference_screen";
+ private static final String VIBRATION_PREFERENCE_SCREEN =
+ "vibration_preference_screen";
@VisibleForTesting static final String TOGGLE_INVERSION_PREFERENCE =
"toggle_inversion_preference";
@@ -215,6 +220,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
private Preference mAutoclickPreferenceScreen;
private Preference mAccessibilityShortcutPreferenceScreen;
private Preference mDisplayDaltonizerPreferenceScreen;
+ private Preference mVibrationPreferenceScreen;
private SwitchPreference mToggleInversionPreference;
private int mLongPressTimeoutDefault;
@@ -452,9 +458,11 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
// Display color adjustments.
mDisplayDaltonizerPreferenceScreen = findPreference(DISPLAY_DALTONIZER_PREFERENCE_SCREEN);
- // Accessibility shortcut
+ // Accessibility shortcut.
mAccessibilityShortcutPreferenceScreen = findPreference(ACCESSIBILITY_SHORTCUT_PREFERENCE);
+ // Vibrations.
+ mVibrationPreferenceScreen = findPreference(VIBRATION_PREFERENCE_SCREEN);
}
private void updateAllPreferences() {
@@ -661,6 +669,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
mSelectLongPressTimeoutPreference.setValue(value);
mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValueToTitleMap.get(value));
+ updateVibrationSummary(mVibrationPreferenceScreen);
+
updateFeatureSummary(Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED,
mCaptioningPreferenceScreen);
updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
@@ -726,6 +736,29 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
pref.setSummary(entries[index]);
}
+ private void updateVibrationSummary(Preference pref) {
+ Vibrator vibrator = getContext().getSystemService(Vibrator.class);
+ final int intensity = Settings.System.getInt(getContext().getContentResolver(),
+ Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ vibrator.getDefaultNotificationVibrationIntensity());
+ mVibrationPreferenceScreen.setSummary(getVibrationSummary(getContext(), intensity));
+ }
+
+ private String getVibrationSummary(Context context, @VibrationIntensity int intensity) {
+ switch (intensity) {
+ case Vibrator.VIBRATION_INTENSITY_OFF:
+ return context.getString(R.string.accessibility_vibration_summary_off);
+ case Vibrator.VIBRATION_INTENSITY_LOW:
+ return context.getString(R.string.accessibility_vibration_summary_low);
+ case Vibrator.VIBRATION_INTENSITY_MEDIUM:
+ return context.getString(R.string.accessibility_vibration_summary_medium);
+ case Vibrator.VIBRATION_INTENSITY_HIGH:
+ return context.getString(R.string.accessibility_vibration_summary_high);
+ default:
+ return "";
+ }
+ }
+
private void updateLockScreenRotationCheckbox() {
Context context = getActivity();
if (context != null) {
diff --git a/src/com/android/settings/accessibility/NotificationVibrationPreferenceFragment.java b/src/com/android/settings/accessibility/NotificationVibrationPreferenceFragment.java
new file mode 100644
index 00000000000..6340bb1417e
--- /dev/null
+++ b/src/com/android/settings/accessibility/NotificationVibrationPreferenceFragment.java
@@ -0,0 +1,51 @@
+/*
+ * 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.accessibility;
+
+import android.os.Vibrator;
+import android.provider.Settings;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+
+/**
+ * Fragment for picking accessibility shortcut service
+ */
+public class NotificationVibrationPreferenceFragment extends VibrationPreferenceFragment {
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.ACCESSIBILITY_VIBRATION_NOTIFICATION;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.accessibility_notification_vibration_settings;
+ }
+
+ /**
+ * Get the setting string of the vibration intensity setting this preference is dealing with.
+ */
+ @Override
+ protected String getVibrationIntensitySetting() {
+ return Settings.System.NOTIFICATION_VIBRATION_INTENSITY;
+ }
+
+ @Override
+ protected int getDefaultVibrationIntensity() {
+ Vibrator vibrator = getContext().getSystemService(Vibrator.class);
+ return vibrator.getDefaultNotificationVibrationIntensity();
+ }
+}
diff --git a/src/com/android/settings/accessibility/TouchVibrationPreferenceFragment.java b/src/com/android/settings/accessibility/TouchVibrationPreferenceFragment.java
new file mode 100644
index 00000000000..ea36833db54
--- /dev/null
+++ b/src/com/android/settings/accessibility/TouchVibrationPreferenceFragment.java
@@ -0,0 +1,61 @@
+/*
+ * 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.accessibility;
+
+import android.graphics.drawable.Drawable;
+import android.os.Vibrator;
+import android.provider.Settings;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+
+/**
+ * Fragment for picking accessibility shortcut service
+ */
+public class TouchVibrationPreferenceFragment extends VibrationPreferenceFragment {
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.ACCESSIBILITY_VIBRATION_TOUCH;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.accessibility_touch_vibration_settings;
+ }
+
+ /**
+ * Get the setting string of the vibration intensity setting this preference is dealing with.
+ */
+ @Override
+ protected String getVibrationIntensitySetting() {
+ return Settings.System.HAPTIC_FEEDBACK_INTENSITY;
+ }
+
+ @Override
+ protected int getDefaultVibrationIntensity() {
+ Vibrator vibrator = getContext().getSystemService(Vibrator.class);
+ return vibrator.getDefaultHapticFeedbackIntensity();
+ }
+
+ @Override
+ public void onVibrationIntensitySelected(int intensity) {
+ // We want to keep HAPTIC_FEEDBACK_ENABLED consistent with this setting since some
+ // applications check it directly before triggering their own haptic feedback.
+ final boolean hapticFeedbackEnabled = !(intensity == Vibrator.VIBRATION_INTENSITY_OFF);
+ Settings.System.putInt(getContext().getContentResolver(),
+ Settings.System.HAPTIC_FEEDBACK_ENABLED, hapticFeedbackEnabled ? 1 : 0);
+ }
+}
diff --git a/src/com/android/settings/accessibility/VibrationPreferenceFragment.java b/src/com/android/settings/accessibility/VibrationPreferenceFragment.java
new file mode 100644
index 00000000000..f81208f3a5e
--- /dev/null
+++ b/src/com/android/settings/accessibility/VibrationPreferenceFragment.java
@@ -0,0 +1,193 @@
+/*
+ * 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.accessibility;
+
+import static android.os.Vibrator.VibrationIntensity;
+
+import android.support.annotation.VisibleForTesting;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Vibrator;
+import android.provider.Settings;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.accessibility.AccessibilityShortcutController;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settings.widget.RadioButtonPickerFragment;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Fragment for changing vibration settings.
+ */
+public abstract class VibrationPreferenceFragment extends RadioButtonPickerFragment {
+ private static final String TAG = "VibrationPreferenceFragment";
+
+ @VisibleForTesting
+ final static String KEY_INTENSITY_OFF = "intensity_off";
+ @VisibleForTesting
+ final static String KEY_INTENSITY_LOW = "intensity_low";
+ @VisibleForTesting
+ final static String KEY_INTENSITY_MEDIUM = "intensity_medium";
+ @VisibleForTesting
+ final static String KEY_INTENSITY_HIGH = "intensity_high";
+
+ private final Map mCandidates;
+ private final SettingsObserver mSettingsObserver;
+
+ public VibrationPreferenceFragment() {
+ mCandidates = new ArrayMap<>();
+ mCandidates.put(KEY_INTENSITY_OFF,
+ new VibrationIntensityCandidateInfo(KEY_INTENSITY_OFF,
+ R.string.accessibility_vibration_intensity_off,
+ Vibrator.VIBRATION_INTENSITY_OFF));
+ mCandidates.put(KEY_INTENSITY_LOW,
+ new VibrationIntensityCandidateInfo(KEY_INTENSITY_LOW,
+ R.string.accessibility_vibration_intensity_low,
+ Vibrator.VIBRATION_INTENSITY_LOW));
+ mCandidates.put(KEY_INTENSITY_MEDIUM,
+ new VibrationIntensityCandidateInfo(KEY_INTENSITY_MEDIUM,
+ R.string.accessibility_vibration_intensity_medium,
+ Vibrator.VIBRATION_INTENSITY_MEDIUM));
+ mCandidates.put(KEY_INTENSITY_HIGH,
+ new VibrationIntensityCandidateInfo(KEY_INTENSITY_HIGH,
+ R.string.accessibility_vibration_intensity_high,
+ Vibrator.VIBRATION_INTENSITY_HIGH));
+ mSettingsObserver = new SettingsObserver();
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mSettingsObserver.register();
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ mSettingsObserver.unregister();
+ }
+
+ /**
+ * Get the setting string of the vibration intensity setting this preference is dealing with.
+ */
+ protected abstract String getVibrationIntensitySetting();
+
+ /**
+ * Get the default intensity for the desired setting.
+ */
+ protected abstract int getDefaultVibrationIntensity();
+
+ /**
+ * When a new vibration intensity is selected by the user.
+ */
+ protected void onVibrationIntensitySelected(int intensity) { }
+
+ @Override
+ protected List extends CandidateInfo> getCandidates() {
+ List candidates = new ArrayList<>(mCandidates.values());
+ candidates.sort(
+ Comparator.comparing(VibrationIntensityCandidateInfo::getIntensity).reversed());
+ return candidates;
+ }
+
+ @Override
+ protected String getDefaultKey() {
+ final int vibrationIntensity = Settings.System.getInt(getContext().getContentResolver(),
+ getVibrationIntensitySetting(), getDefaultVibrationIntensity());
+ for (VibrationIntensityCandidateInfo candidate : mCandidates.values()) {
+ if (candidate.getIntensity() == vibrationIntensity) {
+ return candidate.getKey();
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected boolean setDefaultKey(String key) {
+ VibrationIntensityCandidateInfo candidate = mCandidates.get(key);
+ if (candidate == null) {
+ Log.e(TAG, "Tried to set unknown intensity (key=" + key + ")!");
+ return false;
+ }
+ Settings.System.putInt(getContext().getContentResolver(),
+ getVibrationIntensitySetting(), candidate.getIntensity());
+ onVibrationIntensitySelected(candidate.getIntensity());
+ return true;
+ }
+
+ @VisibleForTesting
+ class VibrationIntensityCandidateInfo extends CandidateInfo {
+ private String mKey;
+ private int mLabelId;
+ @VibrationIntensity
+ private int mIntensity;
+
+ public VibrationIntensityCandidateInfo(String key, int labelId, int intensity) {
+ super(true /* enabled */);
+ mKey = key;
+ mLabelId = labelId;
+ mIntensity = intensity;
+ }
+
+ @Override
+ public CharSequence loadLabel() {
+ return getContext().getString(mLabelId);
+ }
+
+ @Override
+ public Drawable loadIcon() {
+ return null;
+ }
+
+ @Override
+ public String getKey() {
+ return mKey;
+ }
+
+ public int getIntensity() {
+ return mIntensity;
+ }
+ }
+
+ private class SettingsObserver extends ContentObserver {
+ public SettingsObserver() {
+ super(new Handler());
+ }
+
+ public void register() {
+ getContext().getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(getVibrationIntensitySetting()), false, this);
+ }
+
+ public void unregister() {
+ getContext().getContentResolver().unregisterContentObserver(this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ updateCandidates();
+ }
+ }
+}
diff --git a/src/com/android/settings/accessibility/VibrationSettings.java b/src/com/android/settings/accessibility/VibrationSettings.java
new file mode 100644
index 00000000000..8aa45136831
--- /dev/null
+++ b/src/com/android/settings/accessibility/VibrationSettings.java
@@ -0,0 +1,153 @@
+/*
+ * 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.accessibility;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Vibrator;
+import android.provider.SearchIndexableResource;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.Preference;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Activity with the accessibility settings.
+ */
+public class VibrationSettings extends SettingsPreferenceFragment implements Indexable {
+
+ // Preferences
+ @VisibleForTesting
+ static final String NOTIFICATION_VIBRATION_PREFERENCE_SCREEN =
+ "notification_vibration_preference_screen";
+ @VisibleForTesting
+ static final String TOUCH_VIBRATION_PREFERENCE_SCREEN =
+ "touch_vibration_preference_screen";
+
+ private final Handler mHandler = new Handler();
+ private final SettingsContentObserver mSettingsContentObserver;
+
+ private Preference mNotificationVibrationPreferenceScreen;
+ private Preference mTouchVibrationPreferenceScreen;
+
+ public VibrationSettings() {
+ List vibrationSettings = new ArrayList<>();
+ vibrationSettings.add(Settings.System.HAPTIC_FEEDBACK_INTENSITY);
+ vibrationSettings.add(Settings.System.NOTIFICATION_VIBRATION_INTENSITY);
+ mSettingsContentObserver = new SettingsContentObserver(mHandler, vibrationSettings) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ updatePreferences();
+ }
+ };
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.ACCESSIBILITY_VIBRATION;
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ addPreferencesFromResource(R.xml.accessibility_vibration_settings);
+ initializePreferences();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updatePreferences();
+ mSettingsContentObserver.register(getContentResolver());
+ }
+
+ @Override
+ public void onPause() {
+ mSettingsContentObserver.unregister(getContentResolver());
+ super.onPause();
+ }
+
+ private void initializePreferences() {
+ // Notification and notification vibration strength adjustments.
+ mNotificationVibrationPreferenceScreen =
+ findPreference(NOTIFICATION_VIBRATION_PREFERENCE_SCREEN);
+
+ // Touch feedback strength adjustments.
+ mTouchVibrationPreferenceScreen = findPreference(TOUCH_VIBRATION_PREFERENCE_SCREEN);
+ }
+
+ private void updatePreferences() {
+ updateNotificationVibrationSummary(mNotificationVibrationPreferenceScreen);
+ updateTouchVibrationSummary(mTouchVibrationPreferenceScreen);
+ }
+
+ private void updateNotificationVibrationSummary(Preference pref) {
+ Vibrator vibrator = getContext().getSystemService(Vibrator.class);
+ final int intensity = Settings.System.getInt(getContext().getContentResolver(),
+ Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ vibrator.getDefaultNotificationVibrationIntensity());
+ CharSequence summary = getVibrationIntensitySummary(getContext(), intensity);
+ mNotificationVibrationPreferenceScreen.setSummary(summary);
+ }
+
+ private void updateTouchVibrationSummary(Preference pref) {
+ Vibrator vibrator = getContext().getSystemService(Vibrator.class);
+ final int intensity = Settings.System.getInt(getContext().getContentResolver(),
+ Settings.System.HAPTIC_FEEDBACK_INTENSITY,
+ vibrator.getDefaultHapticFeedbackIntensity());
+ CharSequence summary = getVibrationIntensitySummary(getContext(), intensity);
+ mTouchVibrationPreferenceScreen.setSummary(summary);
+ }
+
+ public static String getVibrationIntensitySummary(Context context, int intensity) {
+ switch (intensity) {
+ case Vibrator.VIBRATION_INTENSITY_OFF:
+ return context.getString(R.string.accessibility_vibration_intensity_off);
+ case Vibrator.VIBRATION_INTENSITY_LOW:
+ return context.getString(R.string.accessibility_vibration_intensity_low);
+ case Vibrator.VIBRATION_INTENSITY_MEDIUM:
+ return context.getString(R.string.accessibility_vibration_intensity_medium);
+ case Vibrator.VIBRATION_INTENSITY_HIGH:
+ return context.getString(R.string.accessibility_vibration_intensity_high);
+ default:
+ return "";
+ }
+ }
+
+ public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ @Override
+ public List getXmlResourcesToIndex(Context context,
+ boolean enabled) {
+ List indexables = new ArrayList<>();
+ SearchIndexableResource indexable = new SearchIndexableResource(context);
+ indexable.xmlResId = R.xml.accessibility_vibration_settings;
+ indexables.add(indexable);
+ return indexables;
+ }
+ };
+}
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index f43c3c8964f..19d0cd17178 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -74,7 +74,7 @@ import com.android.settings.display.NightDisplaySettings;
import com.android.settings.dream.DreamSettings;
import com.android.settings.enterprise.EnterprisePrivacySettings;
import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
-import com.android.settings.fuelgauge.BatterySaverSettings;
+import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.fuelgauge.PowerUsageSummaryLegacy;
import com.android.settings.gestures.AssistGestureSettings;
diff --git a/src/com/android/settings/dashboard/conditional/BatterySaverCondition.java b/src/com/android/settings/dashboard/conditional/BatterySaverCondition.java
index 7feac237084..7877f9d3ee1 100644
--- a/src/com/android/settings/dashboard/conditional/BatterySaverCondition.java
+++ b/src/com/android/settings/dashboard/conditional/BatterySaverCondition.java
@@ -20,7 +20,7 @@ import android.os.PowerManager;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Utils;
-import com.android.settings.fuelgauge.BatterySaverSettings;
+import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
public class BatterySaverCondition extends Condition {
public BatterySaverCondition(ConditionManager manager) {
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
index 62bc148b2cd..b24a9146574 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
@@ -23,12 +23,15 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.service.settings.suggestions.Suggestion;
+import android.support.annotation.VisibleForTesting;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -117,7 +120,7 @@ public class SuggestionAdapter extends RecyclerView.Adapter
mConfig.setCardLayout(holder, suggestionCount, position);
final Icon icon = suggestion.getIcon();
final Drawable drawable = mCache.getIcon(icon);
- if ((suggestion.getFlags() & Suggestion.FLAG_ICON_TINTABLE) != 0) {
+ if (drawable != null && (suggestion.getFlags() & Suggestion.FLAG_ICON_TINTABLE) != 0) {
drawable.setTint(Utils.getColorAccent(mContext));
}
holder.icon.setImageDrawable(drawable);
@@ -226,28 +229,27 @@ public class SuggestionAdapter extends RecyclerView.Adapter
return mSuggestions;
}
- private static class CardConfig {
+ @VisibleForTesting
+ static class CardConfig {
// Card start/end margin
private final int mMarginInner;
private final int mMarginOuter;
- // Card width for different numbers of cards
- private final int mWidthSingleCard;
- private final int mWidthTwoCards;
+ // Card width if there are more than 2 cards
private final int mWidthMultipleCards;
// padding between icon and title
private final int mPaddingTitleTopSingleCard;
private final int mPaddingTitleTopMultipleCards;
+ private final WindowManager mWindowManager;
private static CardConfig sConfig;
private CardConfig(Context context) {
+ mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
final Resources res = context.getResources();
mMarginInner =
res.getDimensionPixelOffset(R.dimen.suggestion_card_inner_margin);
mMarginOuter =
res.getDimensionPixelOffset(R.dimen.suggestion_card_outer_margin);
- mWidthSingleCard = res.getDimensionPixelOffset(R.dimen.suggestion_card_width_one_card);
- mWidthTwoCards = res.getDimensionPixelOffset(R.dimen.suggestion_card_width_two_cards);
mWidthMultipleCards =
res.getDimensionPixelOffset(R.dimen.suggestion_card_width_multiple_cards);
mPaddingTitleTopSingleCard =
@@ -263,12 +265,12 @@ public class SuggestionAdapter extends RecyclerView.Adapter
return sConfig;
}
- private void setCardLayout(DashboardItemHolder holder, int suggestionCount,
- int position) {
+ @VisibleForTesting
+ void setCardLayout(DashboardItemHolder holder, int suggestionCount, int position) {
final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
suggestionCount == 1
- ? mWidthSingleCard : suggestionCount == 2
- ? mWidthTwoCards : mWidthMultipleCards,
+ ? LinearLayout.LayoutParams.MATCH_PARENT : suggestionCount == 2
+ ? getWidthForTwoCrads() : mWidthMultipleCards,
LinearLayout.LayoutParams.WRAP_CONTENT);
if (suggestionCount == 1) {
params.setMarginStart(mMarginOuter);
@@ -281,6 +283,16 @@ public class SuggestionAdapter extends RecyclerView.Adapter
holder.itemView.setLayoutParams(params);
}
+ private int getWidthForTwoCrads() {
+ return (getScreenWidth() - mMarginInner - mMarginOuter * 2) / 2;
+ }
+
+ @VisibleForTesting
+ int getScreenWidth() {
+ final DisplayMetrics metrics = new DisplayMetrics();
+ mWindowManager.getDefaultDisplay().getMetrics(metrics);
+ return metrics.widthPixels;
+ }
}
}
diff --git a/src/com/android/settings/fuelgauge/BatterySaverSettings.java b/src/com/android/settings/fuelgauge/BatterySaverSettings.java
deleted file mode 100644
index 2a4fd6ebd03..00000000000
--- a/src/com/android/settings/fuelgauge/BatterySaverSettings.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2014 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.fuelgauge;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.PowerManager;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.provider.Settings.Global;
-import android.support.annotation.VisibleForTesting;
-import android.util.Log;
-import android.widget.Switch;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.util.ArrayUtils;
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.Utils;
-import com.android.settings.dashboard.conditional.BatterySaverCondition;
-import com.android.settings.dashboard.conditional.ConditionManager;
-import com.android.settings.notification.SettingPref;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-import com.android.settings.widget.SwitchBar;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class BatterySaverSettings extends SettingsPreferenceFragment
- implements SwitchBar.OnSwitchChangeListener, BatterySaverReceiver.BatterySaverListener,
- Indexable {
- private static final String TAG = "BatterySaverSettings";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private static final String KEY_TURN_ON_AUTOMATICALLY = "turn_on_automatically";
- private static final long WAIT_FOR_SWITCH_ANIM = 500;
-
- private final Handler mHandler = new Handler();
- private final SettingsObserver mSettingsObserver = new SettingsObserver(mHandler);
-
- @VisibleForTesting
- SwitchBar mSwitchBar;
- private Context mContext;
- private boolean mCreated;
- private SettingPref mTriggerPref;
- private Switch mSwitch;
- private boolean mValidListener;
- private PowerManager mPowerManager;
- private BatterySaverReceiver mReceiver;
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.FUELGAUGE_BATTERY_SAVER;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- if (mCreated) {
- mSwitchBar.show();
- return;
- }
- mCreated = true;
- addPreferencesFromResource(R.xml.battery_saver_settings);
- mFooterPreferenceMixin.createFooterPreference()
- .setTitle(com.android.internal.R.string.battery_saver_description);
- mContext = getActivity();
- mSwitchBar = ((SettingsActivity) mContext).getSwitchBar();
- mSwitchBar.setSwitchBarText(R.string.battery_saver_master_switch_title,
- R.string.battery_saver_master_switch_title);
- mSwitch = mSwitchBar.getSwitch();
- mSwitchBar.show();
-
- int[] levelChoices = getResources().getIntArray(R.array.battery_saver_trigger_values);
- final int currentThreshold = Global.getInt(mContext.getContentResolver(),
- Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
- levelChoices = ArrayUtils.appendInt(levelChoices, currentThreshold);
- Arrays.sort(levelChoices);
-
- mTriggerPref = new SettingPref(SettingPref.TYPE_GLOBAL, KEY_TURN_ON_AUTOMATICALLY,
- Global.LOW_POWER_MODE_TRIGGER_LEVEL,
- 0, /*default*/
- levelChoices) {
- @Override
- protected String getCaption(Resources res, int value) {
- if (value > 0 && value <= 100) {
- return res.getString(R.string.battery_saver_turn_on_automatically_pct,
- Utils.formatPercentage(value));
- }
- return res.getString(R.string.battery_saver_turn_on_automatically_never);
- }
- };
- mTriggerPref.init(this);
-
- mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mReceiver = new BatterySaverReceiver(mContext);
- mReceiver.setBatterySaverListener(this);
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- mSwitchBar.hide();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mSettingsObserver.setListening(true);
- mReceiver.setListening(true);
- if (!mValidListener) {
- mSwitchBar.addOnSwitchChangeListener(this);
- mValidListener = true;
- }
- updateSwitch();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mSettingsObserver.setListening(false);
- mReceiver.setListening(false);
- if (mValidListener) {
- mSwitchBar.removeOnSwitchChangeListener(this);
- mValidListener = false;
- }
- }
-
- @Override
- public void onSwitchChanged(Switch switchView, boolean isChecked) {
- mHandler.removeCallbacks(mStartMode);
- if (isChecked) {
- mHandler.postDelayed(mStartMode, WAIT_FOR_SWITCH_ANIM);
- } else {
- if (DEBUG) Log.d(TAG, "Stopping low power mode from settings");
- trySetPowerSaveMode(false);
- }
- }
-
- private void trySetPowerSaveMode(boolean mode) {
- if (!mPowerManager.setPowerSaveMode(mode)) {
- if (DEBUG) Log.d(TAG, "Setting mode failed, fallback to current value");
- mHandler.post(mUpdateSwitch);
- }
- // TODO: Remove once broadcast is in place.
- ConditionManager.get(getContext()).getCondition(BatterySaverCondition.class).refreshState();
- }
-
- private void updateSwitch() {
- final boolean mode = mPowerManager.isPowerSaveMode();
- if (DEBUG) Log.d(TAG, "updateSwitch: isChecked=" + mSwitch.isChecked() + " mode=" + mode);
- if (mode == mSwitch.isChecked()) return;
-
- // set listener to null so that that code below doesn't trigger onCheckedChanged()
- if (mValidListener) {
- mSwitchBar.removeOnSwitchChangeListener(this);
- }
- mSwitch.setChecked(mode);
- if (mValidListener) {
- mSwitchBar.addOnSwitchChangeListener(this);
- }
- }
-
- private final Runnable mUpdateSwitch = new Runnable() {
- @Override
- public void run() {
- updateSwitch();
- }
- };
-
- private final Runnable mStartMode = new Runnable() {
- @Override
- public void run() {
- AsyncTask.execute(new Runnable() {
- @Override
- public void run() {
- if (DEBUG) Log.d(TAG, "Starting low power mode from settings");
- trySetPowerSaveMode(true);
- }
- });
- }
- };
-
- @Override
- public void onPowerSaveModeChanged() {
- mHandler.post(mUpdateSwitch);
- }
-
- @Override
- public void onBatteryChanged(boolean pluggedIn) {
- mSwitchBar.setEnabled(!pluggedIn);
- }
-
- private final class SettingsObserver extends ContentObserver {
- private final Uri LOW_POWER_MODE_TRIGGER_LEVEL_URI
- = Global.getUriFor(Global.LOW_POWER_MODE_TRIGGER_LEVEL);
-
- public SettingsObserver(Handler handler) {
- super(handler);
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- if (LOW_POWER_MODE_TRIGGER_LEVEL_URI.equals(uri)) {
- mTriggerPref.update(mContext);
- }
- }
-
- public void setListening(boolean listening) {
- final ContentResolver cr = getContentResolver();
- if (listening) {
- cr.registerContentObserver(LOW_POWER_MODE_TRIGGER_LEVEL_URI, false, this);
- } else {
- cr.unregisterContentObserver(this);
- }
- }
- }
-
- /**
- * For Search.
- */
- public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider() {
- @Override
- public List getXmlResourcesToIndex(
- Context context, boolean enabled) {
- final SearchIndexableResource sir = new SearchIndexableResource(context);
- sir.xmlResId = R.xml.battery_saver_settings;
- return Arrays.asList(sir);
- }
- };
-}
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 2a841f900e5..74dc986b574 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -72,7 +72,7 @@ import java.util.List;
* consumed since the last time it was unplugged.
*/
public class PowerUsageSummary extends PowerUsageBase implements OnLongClickListener,
- OnClickListener, BatteryTipPreferenceController.BatteryTipListener {
+ BatteryTipPreferenceController.BatteryTipListener {
static final String TAG = "PowerUsageSummary";
@@ -80,7 +80,6 @@ public class PowerUsageSummary extends PowerUsageBase implements OnLongClickList
private static final String KEY_APP_LIST = "app_list";
private static final String KEY_BATTERY_HEADER = "battery_header";
private static final String KEY_BATTERY_TIP = "battery_tip";
- private static final String KEY_SHOW_ALL_APPS = "show_all_apps";
private static final String KEY_SCREEN_USAGE = "screen_usage";
private static final String KEY_TIME_SINCE_LAST_FULL_CHARGE = "last_full_charge";
@@ -224,15 +223,6 @@ public class PowerUsageSummary extends PowerUsageBase implements OnLongClickList
return MetricsEvent.FUELGAUGE_POWER_USAGE_SUMMARY_V2;
}
- @Override
- public boolean onPreferenceTreeClick(Preference preference) {
- if (KEY_BATTERY_HEADER.equals(preference.getKey())) {
- performBatteryHeaderClick();
- return true;
- }
- return super.onPreferenceTreeClick(preference);
- }
-
@Override
protected String getLogTag() {
return TAG;
@@ -311,22 +301,6 @@ public class PowerUsageSummary extends PowerUsageBase implements OnLongClickList
}
}
- private void performBatteryHeaderClick() {
- if (mPowerFeatureProvider.isAdvancedUiEnabled()) {
- Utils.startWithFragment(getContext(), PowerUsageAdvanced.class.getName(), null,
- null, 0, R.string.advanced_battery_title, null, getMetricsCategory());
- } else {
- mStatsHelper.storeStatsHistoryInFile(BatteryHistoryDetail.BATTERY_HISTORY_FILE);
- Bundle args = new Bundle(2);
- args.putString(BatteryHistoryDetail.EXTRA_STATS,
- BatteryHistoryDetail.BATTERY_HISTORY_FILE);
- args.putParcelable(BatteryHistoryDetail.EXTRA_BROADCAST,
- mStatsHelper.getBatteryBroadcast());
- Utils.startWithFragment(getContext(), BatteryHistoryDetail.class.getName(), args,
- null, 0, R.string.history_details_title, null, getMetricsCategory());
- }
- }
-
protected void refreshUi() {
final Context context = getContext();
if (context == null) {
@@ -405,12 +379,9 @@ public class PowerUsageSummary extends PowerUsageBase implements OnLongClickList
getLoaderManager().restartLoader(BATTERY_INFO_LOADER, Bundle.EMPTY,
mBatteryInfoLoaderCallbacks);
if (mPowerFeatureProvider.isEstimateDebugEnabled()) {
- // Unfortunately setting a long click listener on a view means it will no
- // longer pass the regular click event to the parent, so we have to register
- // a regular click listener as well.
+ // Set long click action for summary to show debug info
View header = mBatteryLayoutPref.findViewById(R.id.summary1);
header.setOnLongClickListener(this);
- header.setOnClickListener(this);
}
}
@@ -421,11 +392,6 @@ public class PowerUsageSummary extends PowerUsageBase implements OnLongClickList
return true;
}
- @Override
- public void onClick(View view) {
- performBatteryHeaderClick();
- }
-
@Override
protected void restartBatteryStatsLoader() {
restartBatteryStatsLoader(true /* clearHeader */);
diff --git a/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySaverPreferenceController.java b/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySaverPreferenceController.java
new file mode 100644
index 00000000000..4d3dd31cdd8
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySaverPreferenceController.java
@@ -0,0 +1,61 @@
+/*
+ * 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.fuelgauge.batterysaver;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.TogglePreferenceController;
+
+/**
+ * Controller that update whether to turn on battery saver automatically
+ */
+public class AutoBatterySaverPreferenceController extends TogglePreferenceController implements
+ Preference.OnPreferenceChangeListener {
+ private static final int LOW_POWER_MODE_TRIGGER_THRESHOLD = 15;
+
+ @VisibleForTesting
+ static final String KEY_AUTO_BATTERY_SAVER = "auto_battery_saver";
+
+ public AutoBatterySaverPreferenceController(Context context) {
+ super(context, KEY_AUTO_BATTERY_SAVER);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public boolean isChecked() {
+ return Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0) != 0;
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL,
+ isChecked
+ ? LOW_POWER_MODE_TRIGGER_THRESHOLD
+ : 0);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySeekBarPreferenceController.java b/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySeekBarPreferenceController.java
new file mode 100644
index 00000000000..1c787abd5d4
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySeekBarPreferenceController.java
@@ -0,0 +1,135 @@
+/*
+ * 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.fuelgauge.batterysaver;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.widget.SeekBarPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+/**
+ * Controller that update the battery saver seekbar
+ */
+public class AutoBatterySeekBarPreferenceController extends BasePreferenceController implements
+ LifecycleObserver, OnStart, OnStop, SeekBarPreference.OnPreferenceChangeListener {
+ @VisibleForTesting
+ static final String KEY_AUTO_BATTERY_SEEK_BAR = "battery_saver_seek_bar";
+ private SeekBarPreference mPreference;
+ private AutoBatterySaverSettingObserver mContentObserver;
+
+ public AutoBatterySeekBarPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY_AUTO_BATTERY_SEEK_BAR);
+ mContentObserver = new AutoBatterySaverSettingObserver(new Handler());
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = (SeekBarPreference) screen.findPreference(
+ KEY_AUTO_BATTERY_SEEK_BAR);
+ updatePreference(mPreference);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ updatePreference(preference);
+ }
+
+ @Override
+ public void onStart() {
+ mContentObserver.registerContentObserver();
+ }
+
+ @Override
+ public void onStop() {
+ mContentObserver.unRegisterContentObserver();
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final int progress = (int) newValue;
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, progress);
+ return true;
+ }
+
+ @VisibleForTesting
+ void updatePreference(Preference preference) {
+ final ContentResolver contentResolver = mContext.getContentResolver();
+ final int level = Settings.Global.getInt(contentResolver,
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
+ if (level == 0) {
+ preference.setVisible(false);
+ } else {
+ preference.setVisible(true);
+ preference.setTitle(mContext.getString(R.string.battery_saver_seekbar_title,
+ Utils.formatPercentage(level)));
+ ((SeekBarPreference) preference).setProgress(level);
+ }
+ }
+
+ /**
+ * Observer that listens to change from {@link Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL}
+ */
+ private final class AutoBatterySaverSettingObserver extends ContentObserver {
+ private final Uri mUri = Settings.Global.getUriFor(
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL);
+ private final ContentResolver mContentResolver;
+
+ public AutoBatterySaverSettingObserver(Handler handler) {
+ super(handler);
+ mContentResolver = mContext.getContentResolver();
+ }
+
+ public void registerContentObserver() {
+ mContentResolver.registerContentObserver(mUri, false, this);
+ }
+
+ public void unRegisterContentObserver() {
+ mContentResolver.unregisterContentObserver(this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri, int userId) {
+ if (mUri.equals(uri)) {
+ updatePreference(mPreference);
+ }
+ }
+ }
+}
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java
new file mode 100644
index 00000000000..392032ce21b
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2014 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.fuelgauge.batterysaver;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.PowerManager;
+import android.provider.SearchIndexableResource;
+import android.provider.Settings.Global;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.util.ArrayUtils;
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Battery saver settings page
+ */
+public class BatterySaverSettings extends DashboardFragment {
+ private static final String TAG = "BatterySaverSettings";
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.FUELGAUGE_BATTERY_SAVER;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.battery_saver_settings;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ protected List getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, getLifecycle());
+ }
+
+ @Override
+ public int getHelpResource() {
+ return R.string.help_url_battery_saver_settings;
+ }
+
+ private static List buildPreferenceControllers(
+ Context context, Lifecycle lifecycle) {
+ final List controllers = new ArrayList<>();
+ controllers.add(new AutoBatterySaverPreferenceController(context));
+ controllers.add(new AutoBatterySeekBarPreferenceController(context, lifecycle));
+ return controllers;
+ }
+
+ /**
+ * For Search.
+ */
+ public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ @Override
+ public List getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.battery_saver_settings;
+ return Arrays.asList(sir);
+ }
+
+ @Override
+ public List getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, null);
+ }
+ };
+}
diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java
index 14ccf2350c4..78139dc310e 100644
--- a/src/com/android/settings/notification/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/AppNotificationSettings.java
@@ -19,10 +19,8 @@ package com.android.settings.notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.content.Context;
-import android.content.Intent;
import android.os.AsyncTask;
-import android.os.Bundle;
-import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceGroup;
@@ -32,9 +30,8 @@ import android.util.Log;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
-import com.android.settings.Utils;
-import com.android.settings.applications.AppInfoBase;
-import com.android.settings.widget.MasterSwitchPreference;
+import com.android.settings.widget.MasterCheckBoxPreference;
+import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
@@ -179,17 +176,37 @@ public class AppNotificationSettings extends NotificationSettingsBase {
groupCategory.setKey(group.getId());
populateGroupToggle(groupCategory, group);
}
-
- final List channels = group.getChannels();
- Collections.sort(channels, mChannelComparator);
- int N = channels.size();
- for (int i = 0; i < N; i++) {
- final NotificationChannel channel = channels.get(i);
- populateSingleChannelPrefs(groupCategory, channel, group.isBlocked());
+ if (!group.isBlocked()) {
+ final List channels = group.getChannels();
+ Collections.sort(channels, mChannelComparator);
+ int N = channels.size();
+ for (int i = 0; i < N; i++) {
+ final NotificationChannel channel = channels.get(i);
+ populateSingleChannelPrefs(groupCategory, channel, group.isBlocked());
+ }
}
}
}
+ protected void populateGroupToggle(final PreferenceGroup parent,
+ NotificationChannelGroup group) {
+ RestrictedSwitchPreference preference = new RestrictedSwitchPreference(getPrefContext());
+ preference.setTitle(R.string.notification_switch_label);
+ preference.setEnabled(mSuspendedAppsAdmin == null
+ && isChannelGroupBlockable(group));
+ preference.setChecked(!group.isBlocked());
+ preference.setOnPreferenceClickListener(preference1 -> {
+ final boolean allowGroup = ((SwitchPreference) preference1).isChecked();
+ group.setBlocked(!allowGroup);
+ mBackend.updateChannelGroup(mAppRow.pkg, mAppRow.uid, group);
+
+ onGroupBlockStateChanged(group);
+ return true;
+ });
+
+ parent.addPreference(preference);
+ }
+
private Comparator mChannelGroupComparator =
new Comparator() {
@@ -204,4 +221,37 @@ public class AppNotificationSettings extends NotificationSettingsBase {
return left.getId().compareTo(right.getId());
}
};
+
+ protected void onGroupBlockStateChanged(NotificationChannelGroup group) {
+ if (group == null) {
+ return;
+ }
+ PreferenceGroup groupGroup = (
+ PreferenceGroup) getPreferenceScreen().findPreference(group.getId());
+
+ if (groupGroup != null) {
+ if (group.isBlocked()) {
+ List toRemove = new ArrayList<>();
+ int childCount = groupGroup.getPreferenceCount();
+ for (int i = 0; i < childCount; i++) {
+ Preference pref = groupGroup.getPreference(i);
+ if (pref instanceof MasterCheckBoxPreference) {
+ toRemove.add(pref);
+ }
+ }
+ for (Preference pref : toRemove) {
+ groupGroup.removePreference(pref);
+ }
+ } else {
+ final List channels = group.getChannels();
+ Collections.sort(channels, mChannelComparator);
+ int N = channels.size();
+ for (int i = 0; i < N; i++) {
+ final NotificationChannel channel = channels.get(i);
+ populateSingleChannelPrefs(groupGroup, channel, group.isBlocked());
+ }
+ }
+ }
+ }
+
}
diff --git a/src/com/android/settings/notification/BlockPreferenceController.java b/src/com/android/settings/notification/BlockPreferenceController.java
index 6b65b0fdff5..8b270989a8a 100644
--- a/src/com/android/settings/notification/BlockPreferenceController.java
+++ b/src/com/android/settings/notification/BlockPreferenceController.java
@@ -103,6 +103,10 @@ public class BlockPreferenceController extends NotificationPreferenceController
mChannel.setImportance(importance);
saveChannel();
}
+ if (mBackend.onlyHasDefaultChannel(mAppRow.pkg, mAppRow.uid)) {
+ mAppRow.banned = blocked;
+ mBackend.setNotificationsEnabledForPackage(mAppRow.pkg, mAppRow.uid, !blocked);
+ }
} else if (mChannelGroup != null && mChannelGroup.getGroup() != null) {
mChannelGroup.setBlocked(blocked);
mBackend.updateChannelGroup(mAppRow.pkg, mAppRow.uid, mChannelGroup.getGroup());
diff --git a/src/com/android/settings/notification/EnableZenModeDialog.java b/src/com/android/settings/notification/EnableZenModeDialog.java
deleted file mode 100644
index f683a2116cb..00000000000
--- a/src/com/android/settings/notification/EnableZenModeDialog.java
+++ /dev/null
@@ -1,467 +0,0 @@
-package com.android.settings.notification;
-
-/*
- * 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.
- */
-
-import static android.util.Log.wtf;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.AlarmManager;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.service.notification.Condition;
-import android.service.notification.ZenModeConfig;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.RadioButton;
-import android.widget.RadioGroup;
-import android.widget.ScrollView;
-import android.widget.TextView;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
-
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.Objects;
-
-public class EnableZenModeDialog extends InstrumentedDialogFragment {
-
- private static final String TAG = "EnableZenModeDialog";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- private static final int[] MINUTE_BUCKETS = ZenModeConfig.MINUTE_BUCKETS;
- private static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0];
- private static final int MAX_BUCKET_MINUTES = MINUTE_BUCKETS[MINUTE_BUCKETS.length - 1];
- private static final int DEFAULT_BUCKET_INDEX = Arrays.binarySearch(MINUTE_BUCKETS, 60);
-
- @VisibleForTesting
- public static final int FOREVER_CONDITION_INDEX = 0;
- @VisibleForTesting
- public static final int COUNTDOWN_CONDITION_INDEX = 1;
- @VisibleForTesting
- public static final int COUNTDOWN_ALARM_CONDITION_INDEX = 2;
- @VisibleForTesting
- protected Activity mActivity;
-
- private static final int SECONDS_MS = 1000;
- private static final int MINUTES_MS = 60 * SECONDS_MS;
-
- @VisibleForTesting
- protected Uri mForeverId;
- private int mBucketIndex = -1;
-
- private AlarmManager mAlarmManager;
- private int mUserId;
- private boolean mAttached;
-
- @VisibleForTesting
- protected Context mContext;
-
- private RadioGroup mZenRadioGroup;
- @VisibleForTesting
- protected LinearLayout mZenRadioGroupContent;
- private int MAX_MANUAL_DND_OPTIONS = 3;
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- NotificationManager noMan = (NotificationManager) getContext().
- getSystemService(Context.NOTIFICATION_SERVICE);
- mContext = getContext();
- mForeverId = Condition.newId(mContext).appendPath("forever").build();
- mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
- mUserId = mContext.getUserId();
- mAttached = false;
-
- final AlertDialog.Builder builder = new AlertDialog.Builder(getContext())
- .setTitle(R.string.zen_mode_settings_turn_on_dialog_title)
- .setNegativeButton(R.string.cancel, null)
- .setPositiveButton(R.string.zen_mode_enable_dialog_turn_on,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- int checkedId = mZenRadioGroup.getCheckedRadioButtonId();
- ConditionTag tag = getConditionTagAt(checkedId);
-
- if (isForever(tag.condition)) {
- MetricsLogger.action(getContext(),
- MetricsProto.MetricsEvent.
- NOTIFICATION_ZEN_MODE_TOGGLE_ON_FOREVER);
- } else if (isAlarm(tag.condition)) {
- MetricsLogger.action(getContext(),
- MetricsProto.MetricsEvent.
- NOTIFICATION_ZEN_MODE_TOGGLE_ON_ALARM);
- } else if (isCountdown(tag.condition)) {
- MetricsLogger.action(getContext(),
- MetricsProto.MetricsEvent.
- NOTIFICATION_ZEN_MODE_TOGGLE_ON_COUNTDOWN);
- } else {
- wtf(TAG, "Invalid manual condition: " + tag.condition);
- }
- // always triggers priority-only dnd with chosen condition
- noMan.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS,
- getRealConditionId(tag.condition), TAG);
- }
- });
-
- View contentView = getContentView();
- bindConditions(forever());
- builder.setView(contentView);
- return builder.create();
- }
-
- private void hideAllConditions() {
- final int N = mZenRadioGroupContent.getChildCount();
- for (int i = 0; i < N; i++) {
- mZenRadioGroupContent.getChildAt(i).setVisibility(View.GONE);
- }
- }
-
- protected View getContentView() {
- if (mActivity == null) {
- mActivity = getActivity();
- }
- final LayoutInflater inflater = mActivity.getLayoutInflater();
- View contentView = inflater.inflate(R.layout.zen_mode_turn_on_dialog_container, null);
- ScrollView container = (ScrollView) contentView.findViewById(R.id.container);
-
- mZenRadioGroup = container.findViewById(R.id.zen_radio_buttons);
- mZenRadioGroupContent = container.findViewById(R.id.zen_radio_buttons_content);
-
- for (int i = 0; i < MAX_MANUAL_DND_OPTIONS; i++) {
- final View radioButton = inflater.inflate(R.layout.zen_mode_radio_button,
- mZenRadioGroup, false);
- mZenRadioGroup.addView(radioButton);
- radioButton.setId(i);
-
- final View radioButtonContent = inflater.inflate(R.layout.zen_mode_condition,
- mZenRadioGroupContent, false);
- radioButtonContent.setId(i + MAX_MANUAL_DND_OPTIONS);
- mZenRadioGroupContent.addView(radioButtonContent);
- }
- hideAllConditions();
- return contentView;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_ENABLE_DIALOG;
- }
-
- @VisibleForTesting
- protected void bind(final Condition condition, final View row, final int rowId) {
- if (condition == null) throw new IllegalArgumentException("condition must not be null");
- final boolean enabled = condition.state == Condition.STATE_TRUE;
- final ConditionTag tag = row.getTag() != null ? (ConditionTag) row.getTag() :
- new ConditionTag();
- row.setTag(tag);
- final boolean first = tag.rb == null;
- if (tag.rb == null) {
- tag.rb = (RadioButton) mZenRadioGroup.getChildAt(rowId);
- }
- tag.condition = condition;
- final Uri conditionId = getConditionId(tag.condition);
- if (DEBUG) Log.d(TAG, "bind i=" + mZenRadioGroupContent.indexOfChild(row) + " first="
- + first + " condition=" + conditionId);
- tag.rb.setEnabled(enabled);
- tag.rb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (isChecked) {
- tag.rb.setChecked(true);
- if (DEBUG) Log.d(TAG, "onCheckedChanged " + conditionId);
- MetricsLogger.action(mContext,
- MetricsProto.MetricsEvent.QS_DND_CONDITION_SELECT);
- announceConditionSelection(tag);
- }
- }
- });
-
- updateUi(tag, row, condition, enabled, rowId, conditionId);
- row.setVisibility(View.VISIBLE);
- }
-
- @VisibleForTesting
- protected ConditionTag getConditionTagAt(int index) {
- return (ConditionTag) mZenRadioGroupContent.getChildAt(index).getTag();
- }
-
- @VisibleForTesting
- protected void bindConditions(Condition c) {
- // forever
- bind(forever(), mZenRadioGroupContent.getChildAt(FOREVER_CONDITION_INDEX),
- FOREVER_CONDITION_INDEX);
- if (c == null) {
- bindGenericCountdown();
- bindNextAlarm(getTimeUntilNextAlarmCondition());
- } else if (isForever(c)) {
- getConditionTagAt(FOREVER_CONDITION_INDEX).rb.setChecked(true);
- bindGenericCountdown();
- bindNextAlarm(getTimeUntilNextAlarmCondition());
- } else {
- if (isAlarm(c)) {
- bindGenericCountdown();
- bindNextAlarm(c);
- getConditionTagAt(COUNTDOWN_ALARM_CONDITION_INDEX).rb.setChecked(true);
- } else if (isCountdown(c)) {
- bindNextAlarm(getTimeUntilNextAlarmCondition());
- bind(c, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
- COUNTDOWN_CONDITION_INDEX);
- getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.setChecked(true);
- } else {
- wtf(TAG, "Invalid manual condition: " + c);
- }
- }
- }
-
- public static Uri getConditionId(Condition condition) {
- return condition != null ? condition.id : null;
- }
-
- public Condition forever() {
- Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
- return new Condition(foreverId, foreverSummary(mContext), "", "", 0 /*icon*/,
- Condition.STATE_TRUE, 0 /*flags*/);
- }
-
- public long getNextAlarm() {
- final AlarmManager.AlarmClockInfo info = mAlarmManager.getNextAlarmClock(mUserId);
- return info != null ? info.getTriggerTime() : 0;
- }
-
- @VisibleForTesting
- protected boolean isAlarm(Condition c) {
- return c != null && ZenModeConfig.isValidCountdownToAlarmConditionId(c.id);
- }
-
- @VisibleForTesting
- protected boolean isCountdown(Condition c) {
- return c != null && ZenModeConfig.isValidCountdownConditionId(c.id);
- }
-
- private boolean isForever(Condition c) {
- return c != null && mForeverId.equals(c.id);
- }
-
- private Uri getRealConditionId(Condition condition) {
- return isForever(condition) ? null : getConditionId(condition);
- }
-
- private String foreverSummary(Context context) {
- return context.getString(com.android.internal.R.string.zen_mode_forever);
- }
-
- private static void setToMidnight(Calendar calendar) {
- calendar.set(Calendar.HOUR_OF_DAY, 0);
- calendar.set(Calendar.MINUTE, 0);
- calendar.set(Calendar.SECOND, 0);
- calendar.set(Calendar.MILLISECOND, 0);
- }
-
- // Returns a time condition if the next alarm is within the next week.
- @VisibleForTesting
- protected Condition getTimeUntilNextAlarmCondition() {
- GregorianCalendar weekRange = new GregorianCalendar();
- setToMidnight(weekRange);
- weekRange.add(Calendar.DATE, 6);
- final long nextAlarmMs = getNextAlarm();
- if (nextAlarmMs > 0) {
- GregorianCalendar nextAlarm = new GregorianCalendar();
- nextAlarm.setTimeInMillis(nextAlarmMs);
- setToMidnight(nextAlarm);
-
- if (weekRange.compareTo(nextAlarm) >= 0) {
- return ZenModeConfig.toNextAlarmCondition(mContext, nextAlarmMs,
- ActivityManager.getCurrentUser());
- }
- }
- return null;
- }
-
- @VisibleForTesting
- protected void bindGenericCountdown() {
- mBucketIndex = DEFAULT_BUCKET_INDEX;
- Condition countdown = ZenModeConfig.toTimeCondition(mContext,
- MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
- if (!mAttached || getConditionTagAt(COUNTDOWN_CONDITION_INDEX).condition == null) {
- bind(countdown, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
- COUNTDOWN_CONDITION_INDEX);
- }
- }
-
- private void updateUi(ConditionTag tag, View row, Condition condition,
- boolean enabled, int rowId, Uri conditionId) {
- if (tag.lines == null) {
- tag.lines = row.findViewById(android.R.id.content);
- }
- if (tag.line1 == null) {
- tag.line1 = (TextView) row.findViewById(android.R.id.text1);
- }
-
- if (tag.line2 == null) {
- tag.line2 = (TextView) row.findViewById(android.R.id.text2);
- }
-
- final String line1 = !TextUtils.isEmpty(condition.line1) ? condition.line1
- : condition.summary;
- final String line2 = condition.line2;
- tag.line1.setText(line1);
- if (TextUtils.isEmpty(line2)) {
- tag.line2.setVisibility(View.GONE);
- } else {
- tag.line2.setVisibility(View.VISIBLE);
- tag.line2.setText(line2);
- }
- tag.lines.setEnabled(enabled);
- tag.lines.setAlpha(enabled ? 1 : .4f);
-
- tag.lines.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- tag.rb.setChecked(true);
- }
- });
-
- // minus button
- final ImageView button1 = (ImageView) row.findViewById(android.R.id.button1);
- button1.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- onClickTimeButton(row, tag, false /*down*/, rowId);
- }
- });
-
- // plus button
- final ImageView button2 = (ImageView) row.findViewById(android.R.id.button2);
- button2.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- onClickTimeButton(row, tag, true /*up*/, rowId);
- }
- });
-
- final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
- if (rowId == COUNTDOWN_CONDITION_INDEX && time > 0) {
- button1.setVisibility(View.VISIBLE);
- button2.setVisibility(View.VISIBLE);
- if (mBucketIndex > -1) {
- button1.setEnabled(mBucketIndex > 0);
- button2.setEnabled(mBucketIndex < MINUTE_BUCKETS.length - 1);
- } else {
- final long span = time - System.currentTimeMillis();
- button1.setEnabled(span > MIN_BUCKET_MINUTES * MINUTES_MS);
- final Condition maxCondition = ZenModeConfig.toTimeCondition(mContext,
- MAX_BUCKET_MINUTES, ActivityManager.getCurrentUser());
- button2.setEnabled(!Objects.equals(condition.summary, maxCondition.summary));
- }
-
- button1.setAlpha(button1.isEnabled() ? 1f : .5f);
- button2.setAlpha(button2.isEnabled() ? 1f : .5f);
- } else {
- button1.setVisibility(View.GONE);
- button2.setVisibility(View.GONE);
- }
- }
-
- @VisibleForTesting
- protected void bindNextAlarm(Condition c) {
- View alarmContent = mZenRadioGroupContent.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX);
- ConditionTag tag = (ConditionTag) alarmContent.getTag();
-
- if (c != null && (!mAttached || tag == null || tag.condition == null)) {
- bind(c, alarmContent, COUNTDOWN_ALARM_CONDITION_INDEX);
- }
-
- // hide the alarm radio button if there isn't a "next alarm condition"
- tag = (ConditionTag) alarmContent.getTag();
- boolean showAlarm = tag != null && tag.condition != null;
- mZenRadioGroup.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(
- showAlarm ? View.VISIBLE : View.GONE);
- alarmContent.setVisibility(showAlarm ? View.VISIBLE : View.GONE);
- }
-
- private void onClickTimeButton(View row, ConditionTag tag, boolean up, int rowId) {
- MetricsLogger.action(mContext, MetricsProto.MetricsEvent.QS_DND_TIME, up);
- Condition newCondition = null;
- final int N = MINUTE_BUCKETS.length;
- if (mBucketIndex == -1) {
- // not on a known index, search for the next or prev bucket by time
- final Uri conditionId = getConditionId(tag.condition);
- final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
- final long now = System.currentTimeMillis();
- for (int i = 0; i < N; i++) {
- int j = up ? i : N - 1 - i;
- final int bucketMinutes = MINUTE_BUCKETS[j];
- final long bucketTime = now + bucketMinutes * MINUTES_MS;
- if (up && bucketTime > time || !up && bucketTime < time) {
- mBucketIndex = j;
- newCondition = ZenModeConfig.toTimeCondition(mContext,
- bucketTime, bucketMinutes, ActivityManager.getCurrentUser(),
- false /*shortVersion*/);
- break;
- }
- }
- if (newCondition == null) {
- mBucketIndex = DEFAULT_BUCKET_INDEX;
- newCondition = ZenModeConfig.toTimeCondition(mContext,
- MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
- }
- } else {
- // on a known index, simply increment or decrement
- mBucketIndex = Math.max(0, Math.min(N - 1, mBucketIndex + (up ? 1 : -1)));
- newCondition = ZenModeConfig.toTimeCondition(mContext,
- MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
- }
- bind(newCondition, row, rowId);
- tag.rb.setChecked(true);
- announceConditionSelection(tag);
- }
-
- private void announceConditionSelection(ConditionTag tag) {
- // condition will always be priority-only
- String modeText = mContext.getString(R.string.zen_interruption_level_priority);
- if (tag.line1 != null) {
- mZenRadioGroupContent.announceForAccessibility(mContext.getString(
- R.string.zen_mode_and_condition, modeText, tag.line1.getText()));
- }
- }
-
- // used as the view tag on condition rows
- @VisibleForTesting
- protected static class ConditionTag {
- public RadioButton rb;
- public View lines;
- public TextView line1;
- public TextView line2;
- public Condition condition;
- }
-}
diff --git a/src/com/android/settings/notification/NotificationAppPreference.java b/src/com/android/settings/notification/NotificationAppPreference.java
new file mode 100644
index 00000000000..a6bcdd6fd9b
--- /dev/null
+++ b/src/com/android/settings/notification/NotificationAppPreference.java
@@ -0,0 +1,131 @@
+/*
+ * 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.notification;
+
+import android.content.Context;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ProgressBar;
+import android.widget.Switch;
+
+import com.android.settings.R;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.TwoTargetPreference;
+
+/**
+ * Shows an app icon, title and summary. Has a second switch touch target.
+ */
+public class NotificationAppPreference extends TwoTargetPreference {
+
+ private int mProgress;
+ private boolean mProgressVisible;
+ private Switch mSwitch;
+ private boolean mChecked;
+ private boolean mEnableSwitch = true;
+
+ public NotificationAppPreference(Context context) {
+ super(context);
+ setLayoutResource(R.layout.preference_app);
+ }
+
+ public NotificationAppPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setLayoutResource(R.layout.preference_app);
+ }
+
+ @Override
+ protected int getSecondTargetResId() {
+ return R.layout.preference_widget_master_switch;
+ }
+
+ public void setProgress(int amount) {
+ mProgress = amount;
+ mProgressVisible = true;
+ notifyChanged();
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder view) {
+ super.onBindViewHolder(view);
+
+ view.findViewById(R.id.summary_container)
+ .setVisibility(TextUtils.isEmpty(getSummary()) ? View.GONE : View.VISIBLE);
+ final ProgressBar progress = (ProgressBar) view.findViewById(android.R.id.progress);
+ if (mProgressVisible) {
+ progress.setProgress(mProgress);
+ progress.setVisibility(View.VISIBLE);
+ } else {
+ progress.setVisibility(View.GONE);
+ }
+
+ final View widgetView = view.findViewById(android.R.id.widget_frame);
+ if (widgetView != null) {
+ widgetView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mSwitch != null && !mSwitch.isEnabled()) {
+ return;
+ }
+ setChecked(!mChecked);
+ if (!callChangeListener(mChecked)) {
+ setChecked(!mChecked);
+ } else {
+ persistBoolean(mChecked);
+ }
+ }
+ });
+ }
+
+ mSwitch = (Switch) view.findViewById(R.id.switchWidget);
+ if (mSwitch != null) {
+ mSwitch.setContentDescription(getTitle());
+ mSwitch.setChecked(mChecked);
+ mSwitch.setEnabled(mEnableSwitch);
+ }
+ }
+
+ public boolean isChecked() {
+ return mSwitch != null && mChecked;
+ }
+
+ public void setChecked(boolean checked) {
+ mChecked = checked;
+ if (mSwitch != null) {
+ mSwitch.setChecked(checked);
+ }
+ }
+
+ public void setSwitchEnabled(boolean enabled) {
+ mEnableSwitch = enabled;
+ if (mSwitch != null) {
+ mSwitch.setEnabled(enabled);
+ }
+ }
+
+ /**
+ * If admin is not null, disables the switch.
+ * Otherwise, keep it enabled.
+ */
+ public void setDisabledByAdmin(RestrictedLockUtils.EnforcedAdmin admin) {
+ setSwitchEnabled(admin == null);
+ }
+
+ public Switch getSwitch() {
+ return mSwitch;
+ }
+}
diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java
index e047efa154b..d205fb4ab8e 100644
--- a/src/com/android/settings/notification/NotificationBackend.java
+++ b/src/com/android/settings/notification/NotificationBackend.java
@@ -15,6 +15,9 @@
*/
package com.android.settings.notification;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+
import android.app.INotificationManager;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
@@ -101,6 +104,12 @@ public class NotificationBackend {
public boolean setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled) {
try {
+ if (onlyHasDefaultChannel(pkg, uid)) {
+ NotificationChannel defaultChannel =
+ getChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID);
+ defaultChannel.setImportance(enabled ? IMPORTANCE_UNSPECIFIED : IMPORTANCE_NONE);
+ updateChannel(pkg, uid, defaultChannel);
+ }
sINM.setNotificationsEnabledForPackage(pkg, uid, enabled);
return true;
} catch (Exception e) {
diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java
index 18b77bc0883..09789f34477 100644
--- a/src/com/android/settings/notification/NotificationSettingsBase.java
+++ b/src/com/android/settings/notification/NotificationSettingsBase.java
@@ -74,6 +74,7 @@ import android.widget.Toast;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -252,30 +253,6 @@ abstract public class NotificationSettingsBase extends DashboardFragment {
return null;
}
- protected void populateGroupToggle(final PreferenceGroup parent,
- NotificationChannelGroup group) {
- RestrictedSwitchPreference preference = new RestrictedSwitchPreference(getPrefContext());
- preference.setTitle(R.string.notification_switch_label);
- preference.setEnabled(mSuspendedAppsAdmin == null
- && isChannelGroupBlockable(group));
- preference.setChecked(!group.isBlocked());
- preference.setOnPreferenceClickListener(preference1 -> {
- final boolean allowGroup = ((SwitchPreference) preference1).isChecked();
- group.setBlocked(!allowGroup);
- mBackend.updateChannelGroup(mAppRow.pkg, mAppRow.uid, group);
-
- for (int i = 0; i < parent.getPreferenceCount(); i++) {
- Preference pref = parent.getPreference(i);
- if (pref instanceof MasterSwitchPreference) {
- ((MasterSwitchPreference) pref).setSwitchEnabled(allowGroup);
- }
- }
- return true;
- });
-
- parent.addPreference(preference);
- }
-
protected Preference populateSingleChannelPrefs(PreferenceGroup parent,
final NotificationChannel channel, final boolean groupBlocked) {
MasterCheckBoxPreference channelPref = new MasterCheckBoxPreference(
diff --git a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
index 3240ae030af..279dcd39144 100644
--- a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
+++ b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
@@ -21,6 +21,7 @@ import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.os.Bundle;
import android.os.UserHandle;
import android.service.notification.NotifyingApp;
import android.support.annotation.VisibleForTesting;
@@ -32,6 +33,7 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IconDrawableFactory;
import android.util.Log;
+import android.widget.Switch;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
@@ -40,6 +42,7 @@ import com.android.settings.applications.AppInfoBase;
import com.android.settings.applications.InstalledAppCounter;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.widget.AppPreference;
+import com.android.settings.widget.MasterSwitchPreference;
import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -197,13 +200,13 @@ public class RecentNotifyingAppsPreferenceController extends AbstractPreferenceC
// Rebind prefs/avoid adding new prefs if possible. Adding/removing prefs causes jank.
// Build a cached preference pool
- final Map appPreferences = new ArrayMap<>();
+ final Map appPreferences = new ArrayMap<>();
int prefCount = mCategory.getPreferenceCount();
for (int i = 0; i < prefCount; i++) {
final Preference pref = mCategory.getPreference(i);
final String key = pref.getKey();
if (!TextUtils.equals(key, KEY_SEE_ALL)) {
- appPreferences.put(key, pref);
+ appPreferences.put(key, (NotificationAppPreference) pref);
}
}
final int recentAppsCount = recentApps.size();
@@ -218,9 +221,9 @@ public class RecentNotifyingAppsPreferenceController extends AbstractPreferenceC
}
boolean rebindPref = true;
- Preference pref = appPreferences.remove(pkgName);
+ NotificationAppPreference pref = appPreferences.remove(pkgName);
if (pref == null) {
- pref = new AppPreference(prefContext);
+ pref = new NotificationAppPreference(prefContext);
rebindPref = false;
}
pref.setKey(pkgName);
@@ -229,13 +232,23 @@ public class RecentNotifyingAppsPreferenceController extends AbstractPreferenceC
pref.setSummary(Utils.formatRelativeTime(mContext,
System.currentTimeMillis() - app.getLastNotified(), false));
pref.setOrder(i);
- pref.setOnPreferenceClickListener(preference -> {
- AppInfoBase.startAppInfoFragment(AppNotificationSettings.class,
- R.string.notifications_title, pkgName, appEntry.info.uid, mHost,
- 1001 /*RequestCode */,
- MetricsProto.MetricsEvent.MANAGE_APPLICATIONS_NOTIFICATIONS);
- return true;
+ Bundle args = new Bundle();
+ args.putString(AppInfoBase.ARG_PACKAGE_NAME, pkgName);
+ args.putInt(AppInfoBase.ARG_PACKAGE_UID, appEntry.info.uid);
+
+ pref.setIntent(Utils.onBuildStartFragmentIntent(mHost.getActivity(),
+ AppNotificationSettings.class.getName(), args, null,
+ R.string.notifications_title, null, false,
+ MetricsProto.MetricsEvent.MANAGE_APPLICATIONS_NOTIFICATIONS));
+ pref.setOnPreferenceChangeListener((preference, newValue) -> {
+ boolean blocked = !(Boolean) newValue;
+ mNotificationBackend.setNotificationsEnabledForPackage(
+ pkgName, appEntry.info.uid, !blocked);
+ return true;
});
+ pref.setChecked(
+ !mNotificationBackend.getNotificationsBanned(pkgName, appEntry.info.uid));
+
if (!rebindPref) {
mCategory.addPreference(pref);
}
diff --git a/src/com/android/settings/notification/SettingsEnableZenModeDialog.java b/src/com/android/settings/notification/SettingsEnableZenModeDialog.java
new file mode 100644
index 00000000000..dccdc26e880
--- /dev/null
+++ b/src/com/android/settings/notification/SettingsEnableZenModeDialog.java
@@ -0,0 +1,37 @@
+/*
+ * 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.notification;
+
+import android.app.Dialog;
+import android.os.Bundle;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+public class SettingsEnableZenModeDialog extends InstrumentedDialogFragment {
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new com.android.settingslib.notification.EnableZenModeDialog(
+ getContext()).createDialog();
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_ENABLE_DIALOG;
+ }
+}
diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java
index 132dea69dc5..032a5cbf0c9 100644
--- a/src/com/android/settings/notification/SoundSettings.java
+++ b/src/com/android/settings/notification/SoundSettings.java
@@ -180,7 +180,7 @@ public class SoundSettings extends DashboardFragment {
SoundSettings fragment, VolumeSeekBarPreference.Callback callback,
Lifecycle lifecycle) {
final List controllers = new ArrayList<>();
- controllers.add(new ZenModePreferenceController(context));
+ controllers.add(new ZenModePreferenceController(context, lifecycle));
controllers.add(new VibrateWhenRingPreferenceController(context));
// === Volumes ===
@@ -264,7 +264,7 @@ public class SoundSettings extends DashboardFragment {
public List getNonIndexableKeys(Context context) {
List keys = super.getNonIndexableKeys(context);
// Duplicate results
- keys.add((new ZenModePreferenceController(context)).getPreferenceKey());
+ keys.add((new ZenModePreferenceController(context, null)).getPreferenceKey());
return keys;
}
};
diff --git a/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java b/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
index 39cbf5df2ca..9eab8bb1827 100644
--- a/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
+++ b/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
@@ -24,6 +24,7 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
+import android.service.notification.ZenModeConfig;
import android.support.v14.preference.PreferenceFragment;
import android.support.v7.preference.Preference;
import android.util.Slog;
@@ -101,6 +102,13 @@ public class ZenAutomaticRuleHeaderPreferenceController extends AbstractZenModeP
PackageManager packageManager = mContext.getPackageManager();
ApplicationInfo info = packageManager.getApplicationInfo(
mRule.getOwner().getPackageName(), 0);
+ if (info.isSystemApp()) {
+ if (ZenModeConfig.isValidScheduleConditionId(mRule.getConditionId())) {
+ return mContext.getDrawable(R.drawable.ic_timelapse);
+ } else if (ZenModeConfig.isValidEventConditionId(mRule.getConditionId())) {
+ return mContext.getDrawable(R.drawable.ic_event);
+ }
+ }
return info.loadIcon(packageManager);
} catch (PackageManager.NameNotFoundException e) {
Slog.w(TAG, "Unable to load icon - PackageManager.NameNotFoundException");
diff --git a/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java b/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java
index a684d3e6f63..9294a902be5 100644
--- a/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java
+++ b/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java
@@ -22,7 +22,6 @@ import android.content.Context;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.widget.Switch;
-import android.widget.Toast;
import com.android.settings.R;
import com.android.settings.applications.LayoutPreference;
@@ -36,14 +35,11 @@ public class ZenAutomaticRuleSwitchPreferenceController extends
private static final String KEY = "zen_automatic_rule_switch";
private AutomaticZenRule mRule;
private String mId;
- private Toast mEnabledToast;
- private int mToastTextResource;
private SwitchBar mSwitchBar;
public ZenAutomaticRuleSwitchPreferenceController(Context context, Fragment parent,
- int toastTextResource, Lifecycle lifecycle) {
+ Lifecycle lifecycle) {
super(context, KEY, parent, lifecycle);
- mToastTextResource = toastTextResource;
}
@Override
@@ -92,16 +88,5 @@ public class ZenAutomaticRuleSwitchPreferenceController extends
if (enabled == mRule.isEnabled()) return;
mRule.setEnabled(enabled);
mBackend.setZenRule(mId, mRule);
- if (enabled) {
- final int toastText = mToastTextResource;
- if (toastText != 0) {
- mEnabledToast = Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT);
- mEnabledToast.show();
- }
- } else {
- if (mEnabledToast != null) {
- mEnabledToast.cancel();
- }
- }
}
}
diff --git a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
index da540f4100e..d9c96916783 100644
--- a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
@@ -62,7 +62,7 @@ public class ZenModeButtonPreferenceController extends AbstractZenModePreference
mZenButtonOn = (Button) ((LayoutPreference) preference)
.findViewById(R.id.zen_mode_settings_turn_on_button);
mZenButtonOn.setOnClickListener(v ->
- new EnableZenModeDialog().show(mFragment, TAG));
+ new SettingsEnableZenModeDialog().show(mFragment, TAG));
}
if (null == mZenButtonOff) {
diff --git a/src/com/android/settings/notification/ZenModeEventRuleSettings.java b/src/com/android/settings/notification/ZenModeEventRuleSettings.java
index bb667685ed0..cf6d7b507d6 100644
--- a/src/com/android/settings/notification/ZenModeEventRuleSettings.java
+++ b/src/com/android/settings/notification/ZenModeEventRuleSettings.java
@@ -82,8 +82,7 @@ public class ZenModeEventRuleSettings extends ZenModeRuleSettingsBase {
List controllers = new ArrayList<>();
mHeader = new ZenAutomaticRuleHeaderPreferenceController(context, this,
getLifecycle());
- mSwitch = new ZenAutomaticRuleSwitchPreferenceController(context, this,
- R.string.zen_event_rule_enabled_toast, getLifecycle());
+ mSwitch = new ZenAutomaticRuleSwitchPreferenceController(context, this, getLifecycle());
controllers.add(mHeader);
controllers.add(mSwitch);
return controllers;
diff --git a/src/com/android/settings/notification/ZenModePreferenceController.java b/src/com/android/settings/notification/ZenModePreferenceController.java
index e11b422572c..aafda11b82f 100644
--- a/src/com/android/settings/notification/ZenModePreferenceController.java
+++ b/src/com/android/settings/notification/ZenModePreferenceController.java
@@ -16,18 +16,56 @@
package com.android.settings.notification;
+import android.content.ContentResolver;
import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.util.Slog;
-public class ZenModePreferenceController extends AdjustVolumeRestrictedPreferenceController {
+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;
+
+public class ZenModePreferenceController extends AdjustVolumeRestrictedPreferenceController
+ implements LifecycleObserver, OnResume, OnPause {
private static final String KEY_ZEN_MODE = "zen_mode";
-
+ private SettingObserver mSettingObserver;
private ZenModeSettings.SummaryBuilder mSummaryBuilder;
- public ZenModePreferenceController(Context context) {
+ public ZenModePreferenceController(Context context, Lifecycle lifecycle) {
super(context);
mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
+
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mSettingObserver = new SettingObserver(screen.findPreference(KEY_ZEN_MODE));
+ }
+
+ @Override
+ public void onResume() {
+ if (mSettingObserver != null) {
+ mSettingObserver.register(mContext.getContentResolver());
+ }
+ }
+
+ @Override
+ public void onPause() {
+ if (mSettingObserver != null) {
+ mSettingObserver.unregister(mContext.getContentResolver());
+ }
}
@Override
@@ -44,7 +82,41 @@ public class ZenModePreferenceController extends AdjustVolumeRestrictedPreferenc
public void updateState(Preference preference) {
super.updateState(preference);
if (preference.isEnabled()) {
- preference.setSummary(mSummaryBuilder.getAutomaticRulesSummary());
+ preference.setSummary(mSummaryBuilder.getSoundSummary());
+ }
+ }
+
+ class SettingObserver extends ContentObserver {
+ private final Uri ZEN_MODE_URI = Settings.Global.getUriFor(Settings.Global.ZEN_MODE);
+ private final Uri ZEN_MODE_CONFIG_ETAG_URI = Settings.Global.getUriFor(
+ Settings.Global.ZEN_MODE_CONFIG_ETAG);
+
+ private final Preference mPreference;
+
+ public SettingObserver(Preference preference) {
+ super(new Handler());
+ mPreference = preference;
+ }
+
+ public void register(ContentResolver cr) {
+ cr.registerContentObserver(ZEN_MODE_URI, false, this, UserHandle.USER_ALL);
+ cr.registerContentObserver(ZEN_MODE_CONFIG_ETAG_URI, false, this, UserHandle.USER_ALL);
+ }
+
+ public void unregister(ContentResolver cr) {
+ cr.unregisterContentObserver(this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+ if (ZEN_MODE_URI.equals(uri)) {
+ updateState(mPreference);
+ }
+
+ if (ZEN_MODE_CONFIG_ETAG_URI.equals(uri)) {
+ updateState(mPreference);
+ }
}
}
}
diff --git a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
index ecfe91b42b1..9ef1128d593 100644
--- a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
+++ b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
@@ -200,8 +200,7 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
List controllers = new ArrayList<>();
mHeader = new ZenAutomaticRuleHeaderPreferenceController(context, this,
getLifecycle());
- mSwitch = new ZenAutomaticRuleSwitchPreferenceController(context, this,
- R.string.zen_schedule_rule_enabled_toast, getLifecycle());
+ mSwitch = new ZenAutomaticRuleSwitchPreferenceController(context, this, getLifecycle());
controllers.add(mHeader);
controllers.add(mSwitch);
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index a6145c442d1..2b48301aba2 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -115,6 +115,26 @@ public class ZenModeSettings extends ZenModeSettingsBase {
return mContext.getString(R.string.zen_mode_behavior_summary_custom);
}
+ String getSoundSummary() {
+ int zenMode = NotificationManager.from(mContext).getZenMode();
+
+ if (zenMode != Settings.Global.ZEN_MODE_OFF) {
+ Policy policy = NotificationManager.from(mContext).getNotificationPolicy();
+ return mContext.getString(R.string.zen_mode_sound_summary_on,
+ getBehaviorSettingSummary(policy, zenMode));
+ } else {
+ final int count = getEnabledAutomaticRulesCount();
+ if (count > 0) {
+ return mContext.getString(R.string.zen_mode_sound_summary_off_with_info,
+ mContext.getResources().getQuantityString(
+ R.plurals.zen_mode_sound_summary_summary_off_info,
+ count, count));
+ }
+
+ return mContext.getString(R.string.zen_mode_sound_summary_off);
+ }
+ }
+
String getAutomaticRulesSummary() {
final int count = getEnabledAutomaticRulesCount();
return count == 0 ? mContext.getString(R.string.zen_mode_settings_summary_off)
diff --git a/src/com/android/settings/notification/ZenRuleSelectionDialog.java b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
index 0784d5a4674..9beac7c7a2e 100644
--- a/src/com/android/settings/notification/ZenRuleSelectionDialog.java
+++ b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
@@ -119,13 +119,21 @@ public class ZenRuleSelectionDialog extends InstrumentedDialogFragment {
final LinearLayout v = (LinearLayout) LayoutInflater.from(mContext).inflate(
R.layout.zen_rule_type, null, false);
- LoadIconTask task = new LoadIconTask((ImageView) v.findViewById(R.id.icon));
- task.execute(info);
+ ImageView iconView = v.findViewById(R.id.icon);
((TextView) v.findViewById(R.id.title)).setText(ri.title);
if (!ri.isSystem) {
+ LoadIconTask task = new LoadIconTask(iconView);
+ task.execute(info);
+
TextView subtitle = (TextView) v.findViewById(R.id.subtitle);
subtitle.setText(info.loadLabel(mPm));
subtitle.setVisibility(View.VISIBLE);
+ } else {
+ if (ZenModeConfig.isValidScheduleConditionId(ri.defaultConditionId)) {
+ iconView.setImageDrawable(mContext.getDrawable(R.drawable.ic_timelapse));
+ } else if (ZenModeConfig.isValidEventConditionId(ri.defaultConditionId)) {
+ iconView.setImageDrawable(mContext.getDrawable(R.drawable.ic_event));
+ }
}
v.setOnClickListener(new View.OnClickListener() {
@Override
diff --git a/src/com/android/settings/search/SearchIndexableResourcesImpl.java b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
index 1edc2deab9b..2b2551250c3 100644
--- a/src/com/android/settings/search/SearchIndexableResourcesImpl.java
+++ b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
@@ -26,6 +26,7 @@ import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
import com.android.settings.accessibility.AccessibilitySettings;
import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
import com.android.settings.accessibility.MagnificationPreferenceFragment;
+import com.android.settings.accessibility.VibrationSettings;
import com.android.settings.accounts.AccountDashboardFragment;
import com.android.settings.applications.AppAndNotificationDashboardFragment;
import com.android.settings.applications.DefaultAppSettings;
@@ -49,7 +50,7 @@ import com.android.settings.display.NightDisplaySettings;
import com.android.settings.display.ScreenZoomSettings;
import com.android.settings.dream.DreamSettings;
import com.android.settings.enterprise.EnterprisePrivacySettings;
-import com.android.settings.fuelgauge.BatterySaverSettings;
+import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
import com.android.settings.fuelgauge.PowerUsageAdvanced;
import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.fuelgauge.SmartBatterySettings;
@@ -176,6 +177,7 @@ public class SearchIndexableResourcesImpl implements SearchIndexableResources {
addIndex(NightDisplaySettings.class);
addIndex(SmartBatterySettings.class);
addIndex(MyDeviceInfoFragment.class);
+ addIndex(VibrationSettings.class);
}
@Override
diff --git a/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java b/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java
index 5bb8f75e578..3e39860d609 100644
--- a/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java
+++ b/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java
@@ -20,7 +20,6 @@ import android.content.Context;
import android.os.UserHandle;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
@@ -52,21 +51,18 @@ public class ManageTrustAgentsPreferenceController extends BasePreferenceControl
}
@Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- final Preference preference = screen.findPreference(getPreferenceKey());
- if (preference == null) {
- return;
- }
+ public void updateState(Preference preference) {
final int numberOfTrustAgent = getTrustAgentCount();
if (!mLockPatternUtils.isSecure(MY_USER_ID)) {
preference.setEnabled(false);
preference.setSummary(R.string.disabled_because_no_backup_security);
} else if (numberOfTrustAgent > 0) {
+ preference.setEnabled(true);
preference.setSummary(mContext.getResources().getQuantityString(
R.plurals.manage_trust_agents_summary_on,
numberOfTrustAgent, numberOfTrustAgent));
} else {
+ preference.setEnabled(true);
preference.setSummary(R.string.manage_trust_agents_summary);
}
}
diff --git a/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java b/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
index 77142edfeed..8d798b1ced4 100644
--- a/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
+++ b/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
@@ -59,7 +59,8 @@ public class WallpaperSuggestionActivity extends Activity {
@VisibleForTesting
public static boolean isSuggestionComplete(Context context) {
final WallpaperManagerWrapper manager = new WallpaperManagerWrapper(context);
- return manager.getWallpaperId(WallpaperManager.FLAG_SYSTEM) > 0;
+ return manager.isWallpaperServiceEnabled() ? manager.getWallpaperId(
+ WallpaperManager.FLAG_SYSTEM) > 0 : false;
}
}
diff --git a/src/com/android/settings/widget/SeekBarPreference.java b/src/com/android/settings/widget/SeekBarPreference.java
index ee7d4b8587d..5af21b3a004 100644
--- a/src/com/android/settings/widget/SeekBarPreference.java
+++ b/src/com/android/settings/widget/SeekBarPreference.java
@@ -40,6 +40,7 @@ public class SeekBarPreference extends RestrictedPreference
private int mProgress;
private int mMax;
+ private int mMin;
private boolean mTrackingTouch;
private boolean mContinuousUpdates;
@@ -55,6 +56,7 @@ public class SeekBarPreference extends RestrictedPreference
TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.ProgressBar, defStyleAttr, defStyleRes);
setMax(a.getInt(com.android.internal.R.styleable.ProgressBar_max, mMax));
+ setMin(a.getInt(com.android.internal.R.styleable.ProgressBar_min, mMin));
a.recycle();
a = context.obtainStyledAttributes(attrs,
@@ -94,6 +96,7 @@ public class SeekBarPreference extends RestrictedPreference
com.android.internal.R.id.seekbar);
mSeekBar.setOnSeekBarChangeListener(this);
mSeekBar.setMax(mMax);
+ mSeekBar.setMin(mMin);
mSeekBar.setProgress(mProgress);
mSeekBar.setEnabled(isEnabled());
final CharSequence title = getTitle();
@@ -154,10 +157,21 @@ public class SeekBarPreference extends RestrictedPreference
}
}
+ public void setMin(int min) {
+ if (min != mMin) {
+ mMin = min;
+ notifyChanged();
+ }
+ }
+
public int getMax() {
return mMax;
}
+ public int getMin() {
+ return mMin;
+ }
+
public void setProgress(int progress) {
setProgress(progress, true);
}
@@ -187,8 +201,8 @@ public class SeekBarPreference extends RestrictedPreference
if (progress > mMax) {
progress = mMax;
}
- if (progress < 0) {
- progress = 0;
+ if (progress < mMin) {
+ progress = mMin;
}
if (progress != mProgress) {
mProgress = progress;
@@ -257,6 +271,7 @@ public class SeekBarPreference extends RestrictedPreference
final SavedState myState = new SavedState(superState);
myState.progress = mProgress;
myState.max = mMax;
+ myState.min = mMin;
return myState;
}
@@ -273,6 +288,7 @@ public class SeekBarPreference extends RestrictedPreference
super.onRestoreInstanceState(myState.getSuperState());
mProgress = myState.progress;
mMax = myState.max;
+ mMin = myState.min;
notifyChanged();
}
@@ -285,6 +301,7 @@ public class SeekBarPreference extends RestrictedPreference
private static class SavedState extends BaseSavedState {
int progress;
int max;
+ int min;
public SavedState(Parcel source) {
super(source);
@@ -292,6 +309,7 @@ public class SeekBarPreference extends RestrictedPreference
// Restore the click counter
progress = source.readInt();
max = source.readInt();
+ min = source.readInt();
}
@Override
@@ -301,6 +319,7 @@ public class SeekBarPreference extends RestrictedPreference
// Save the click counter
dest.writeInt(progress);
dest.writeInt(max);
+ dest.writeInt(min);
}
public SavedState(Parcelable superState) {
diff --git a/src/com/android/settings/wifi/ConnectedAccessPointPreference.java b/src/com/android/settings/wifi/ConnectedAccessPointPreference.java
index 6b9c788659a..514525caa6c 100644
--- a/src/com/android/settings/wifi/ConnectedAccessPointPreference.java
+++ b/src/com/android/settings/wifi/ConnectedAccessPointPreference.java
@@ -36,6 +36,7 @@ public class ConnectedAccessPointPreference extends AccessPointPreference implem
public ConnectedAccessPointPreference(AccessPoint accessPoint, Context context,
UserBadgeCache cache, @DrawableRes int iconResId, boolean forSavedNetworks) {
super(accessPoint, context, cache, iconResId, forSavedNetworks);
+ setWidgetLayoutResource(R.layout.preference_widget_gear_no_bg);
}
public void setOnGearClickListener(OnGearClickListener l) {
@@ -43,26 +44,6 @@ public class ConnectedAccessPointPreference extends AccessPointPreference implem
notifyChanged();
}
- @Override
- protected int getSecondTargetResId() {
- return R.layout.preference_widget_gear;
- }
-
- @Override
- protected boolean shouldHideSecondTarget() {
- return mOnGearClickListener == null;
- }
-
- @Override
- public void onBindViewHolder(PreferenceViewHolder holder) {
- super.onBindViewHolder(holder);
- final View gear = holder.findViewById(R.id.settings_button);
- if (gear != null) {
- gear.setOnClickListener(this);
- }
- setDividerVisibility(holder, View.VISIBLE);
- }
-
@Override
public void onClick(View v) {
if (v.getId() == R.id.settings_button) {
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 22f8c43f237..ce0ff80c086 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -884,13 +884,14 @@ public class WifiSettings extends RestrictedSettingsFragment
connectedAp);
// Launch details page on click.
- pref.setOnGearClickListener(l -> {
+ pref.setOnPreferenceClickListener(preference -> {
pref.getAccessPoint().saveWifiState(pref.getExtras());
SettingsActivity activity = (SettingsActivity) WifiSettings.this.getActivity();
activity.startPreferencePanel(this,
WifiNetworkDetailsFragment.class.getName(), pref.getExtras(),
-1 /* resId */, pref.getTitle(), null, 0 /* resultRequestCode */);
+ return true;
});
pref.refresh();
diff --git a/src/com/android/settings/wrapper/WallpaperManagerWrapper.java b/src/com/android/settings/wrapper/WallpaperManagerWrapper.java
index 89015e5513e..eabc5bb6e3e 100644
--- a/src/com/android/settings/wrapper/WallpaperManagerWrapper.java
+++ b/src/com/android/settings/wrapper/WallpaperManagerWrapper.java
@@ -22,12 +22,23 @@ import android.content.Context;
public class WallpaperManagerWrapper {
private final WallpaperManager mWallpaperManager;
+ private final boolean mWallpaperServiceEnabled;
public WallpaperManagerWrapper(Context context) {
- mWallpaperManager = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
+ mWallpaperServiceEnabled = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_enableWallpaperService);
+ mWallpaperManager = mWallpaperServiceEnabled ? (WallpaperManager) context.getSystemService(
+ Context.WALLPAPER_SERVICE) : null;
+ }
+
+ public boolean isWallpaperServiceEnabled() {
+ return mWallpaperServiceEnabled;
}
public int getWallpaperId(int which) {
+ if (!mWallpaperServiceEnabled) {
+ throw new RuntimeException("This device does not have wallpaper service enabled.");
+ }
return mWallpaperManager.getWallpaperId(which);
}
}
diff --git a/tests/robotests/src/com/android/internal/app/ColorDisplayController.java b/tests/robotests/src/com/android/internal/app/ColorDisplayController.java
index 74e7d8a8b83..e31ba518688 100644
--- a/tests/robotests/src/com/android/internal/app/ColorDisplayController.java
+++ b/tests/robotests/src/com/android/internal/app/ColorDisplayController.java
@@ -16,8 +16,8 @@
package com.android.internal.app;
/**
- * Fake controller to make robolectric test compile. Should be removed when Robolectric supports
- * API 25.
+ * Fake controller to make robolectric test compile. This is necessary since
+ * ColorDisplayController is not part of Android's API.
*/
public class ColorDisplayController {
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceFragmentTest.java
new file mode 100644
index 00000000000..f6a5a8231b7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceFragmentTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.accessibility;
+
+import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_OFF;
+import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_LOW;
+import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_MEDIUM;
+import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_HIGH;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.UserManager;
+import android.os.Vibrator;
+import android.provider.Settings;
+
+import com.android.settings.TestConfig;
+import com.android.settings.accessibility.VibrationPreferenceFragment.VibrationIntensityCandidateInfo;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.widget.RadioButtonPickerFragment.CandidateInfo;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class VibrationPreferenceFragmentTest {
+ public static final Map INTENSITY_TO_KEY = new HashMap<>();
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Activity mActivity;
+ @Mock
+ private UserManager mUserManager;
+
+ private Context mContext;
+ private TestVibrationPreferenceFragment mFragment;
+
+ static {
+ INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_OFF, KEY_INTENSITY_OFF);
+ INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_LOW, KEY_INTENSITY_LOW);
+ INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_MEDIUM, KEY_INTENSITY_MEDIUM);
+ INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_HIGH, KEY_INTENSITY_HIGH);
+ }
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ FakeFeatureFactory.setupForTest();
+
+ mContext = RuntimeEnvironment.application;
+
+ mFragment = spy(new TestVibrationPreferenceFragment());
+ doReturn(mUserManager).when(mActivity).getSystemService(Context.USER_SERVICE);
+ doReturn(mContext).when(mFragment).getContext();
+ mFragment.onAttach(mActivity);
+ }
+
+ @Test
+ public void changeIntensitySetting_shouldResultInCorrespondingKey() {
+ for (Map.Entry entry : INTENSITY_TO_KEY.entrySet()) {
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.HAPTIC_FEEDBACK_INTENSITY, entry.getKey());
+ assertThat(mFragment.getDefaultKey()).isEqualTo(entry.getValue());
+ }
+ }
+
+ @Test
+ public void initialDefaultKey_shouldBeMedium() {
+ assertThat(mFragment.getDefaultKey()).isEqualTo(KEY_INTENSITY_MEDIUM);
+ }
+
+ @Test
+ public void candidates_shouldBeSortedByIntensity() {
+ final List extends CandidateInfo> candidates = mFragment.getCandidates();
+ assertThat(candidates.size()).isEqualTo(INTENSITY_TO_KEY.size());
+ VibrationIntensityCandidateInfo prevCandidate =
+ (VibrationIntensityCandidateInfo) candidates.get(0);
+ for (int i = 1; i < candidates.size(); i++) {
+ VibrationIntensityCandidateInfo candidate =
+ (VibrationIntensityCandidateInfo) candidates.get(i);
+ assertThat(candidate.getIntensity()).isLessThan(prevCandidate.getIntensity());
+ }
+ }
+
+ private class TestVibrationPreferenceFragment extends VibrationPreferenceFragment {
+ @Override
+ protected int getPreferenceScreenResId() {
+ return 0;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return 0;
+ }
+
+ /**
+ * Get the setting string of the vibration intensity setting this preference is dealing with.
+ */
+ @Override
+ protected String getVibrationIntensitySetting() {
+ return Settings.System.HAPTIC_FEEDBACK_INTENSITY;
+ }
+
+ @Override
+ protected int getDefaultVibrationIntensity() {
+ return Vibrator.VIBRATION_INTENSITY_MEDIUM;
+ }
+ }
+}
+
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
index d25969e4787..cc25b5de902 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
@@ -35,6 +35,7 @@ import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.WindowManager;
import android.widget.TextView;
import com.android.settings.R;
@@ -77,6 +78,8 @@ public class DashboardAdapterTest {
private Condition mCondition;
@Mock
private Resources mResources;
+ @Mock
+ private WindowManager mWindowManager;
private FakeFeatureFactory mFactory;
private DashboardAdapter mDashboardAdapter;
private List mConditionList;
@@ -87,6 +90,7 @@ public class DashboardAdapterTest {
mFactory = FakeFeatureFactory.setupForTest();
when(mFactory.dashboardFeatureProvider.shouldTintIcon()).thenReturn(true);
+ when(mContext.getSystemService(Context.WINDOW_SERVICE)).thenReturn(mWindowManager);
when(mContext.getResources()).thenReturn(mResources);
when(mResources.getQuantityString(any(int.class), any(int.class), any()))
.thenReturn("");
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java
index fc773a7f817..bac02d37d86 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java
@@ -28,12 +28,15 @@ import static org.mockito.Mockito.when;
import android.app.PendingIntent;
import android.content.Context;
+import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.service.settings.suggestions.Suggestion;
+import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
@@ -67,17 +70,33 @@ public class SuggestionAdapterTest {
private SettingsActivity mActivity;
@Mock
private SuggestionControllerMixin mSuggestionControllerMixin;
+ @Mock
+ private Resources mResources;
+ @Mock
+ private WindowManager mWindowManager;
+
private FakeFeatureFactory mFeatureFactory;
private Context mContext;
private SuggestionAdapter mSuggestionAdapter;
private DashboardAdapter.DashboardItemHolder mSuggestionHolder;
private List mOneSuggestion;
private List mTwoSuggestions;
+ private SuggestionAdapter.CardConfig mConfig;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
+ when(mActivity.getSystemService(Context.WINDOW_SERVICE)).thenReturn(mWindowManager);
+ when(mActivity.getResources()).thenReturn(mResources);
+ when(mResources.getDimensionPixelOffset(R.dimen.suggestion_card_inner_margin))
+ .thenReturn(10);
+ when(mResources.getDimensionPixelOffset(R.dimen.suggestion_card_outer_margin))
+ .thenReturn(20);
+ when(mResources.getDimensionPixelOffset(R.dimen.suggestion_card_width_multiple_cards))
+ .thenReturn(120);
+ mConfig = spy(SuggestionAdapter.CardConfig.get(mActivity));
+
mFeatureFactory = FakeFeatureFactory.setupForTest();
final Suggestion suggestion1 = new Suggestion.Builder("id1")
@@ -275,6 +294,44 @@ public class SuggestionAdapterTest {
verify(drawable).setTint(colorAccent);
}
+ @Test
+ public void setCardLayout_oneCard_shouldSetCardWidthToMatchParent() {
+ final List suggestions = makeSuggestions("pkg1");
+ setupSuggestions(mContext, suggestions);
+
+ mConfig.setCardLayout(mSuggestionHolder, 1, 0);
+
+ assertThat(mSuggestionHolder.itemView.getLayoutParams().width)
+ .isEqualTo(LinearLayout.LayoutParams.MATCH_PARENT);
+ }
+
+ @Test
+ public void setCardLayout_twoCards_shouldSetCardWidthToHalfScreenMinusPadding() {
+ final List suggestions = makeSuggestions("pkg1");
+ setupSuggestions(mContext, suggestions);
+ doReturn(200).when(mConfig).getScreenWidth();
+
+ mConfig.setCardLayout(mSuggestionHolder, 2, 0);
+
+ /*
+ * card width = (screen width - left margin - inner margin - right margin) / 2
+ * = (200 - 20 - 10 - 20) / 2
+ * = 75
+ */
+ assertThat(mSuggestionHolder.itemView.getLayoutParams().width).isEqualTo(75);
+ }
+
+
+ @Test
+ public void setCardLayout_multipleCards_shouldSetCardWidthFromResource() {
+ final List suggestions = makeSuggestions("pkg1");
+ setupSuggestions(mContext, suggestions);
+
+ mConfig.setCardLayout(mSuggestionHolder, 3, 0);
+
+ assertThat(mSuggestionHolder.itemView.getLayoutParams().width).isEqualTo(120);
+ }
+
private void setupSuggestions(Context context, List suggestions) {
mSuggestionAdapter = new SuggestionAdapter(context, mSuggestionControllerMixin,
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverSettingsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverSettingsTest.java
deleted file mode 100644
index 0e32f6bd16f..00000000000
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverSettingsTest.java
+++ /dev/null
@@ -1,74 +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.fuelgauge;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-import android.provider.SearchIndexableResource;
-
-import com.android.settings.R;
-import com.android.settings.TestConfig;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.widget.SwitchBar;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.List;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class BatterySaverSettingsTest {
- private Context mContext;
- private BatterySaverSettings mBatterySaverSettings;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- mContext = RuntimeEnvironment.application;
- mBatterySaverSettings = new BatterySaverSettings();
- mBatterySaverSettings.mSwitchBar = new SwitchBar(mContext);
- }
-
- @Test
- public void testOnBatteryChanged_pluggedIn_setDisable() {
- mBatterySaverSettings.onBatteryChanged(true /* pluggedIn */);
-
- assertThat(mBatterySaverSettings.mSwitchBar.isEnabled()).isFalse();
- }
-
- @Test
- public void testOnBatteryChanged_notPluggedIn_setEnable() {
- mBatterySaverSettings.onBatteryChanged(false /* pluggedIn */);
-
- assertThat(mBatterySaverSettings.mSwitchBar.isEnabled()).isTrue();
- }
-
- @Test
- public void searchProvider_shouldIndexDefaultXml() {
- final List sir = mBatterySaverSettings.SEARCH_INDEX_DATA_PROVIDER
- .getXmlResourcesToIndex(mContext, true /* enabled */);
-
- assertThat(sir).hasSize(1);
- assertThat(sir.get(0).xmlResId).isEqualTo(R.xml.battery_saver_settings);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySaverPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySaverPreferenceControllerTest.java
new file mode 100644
index 00000000000..cabcdcf26dc
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySaverPreferenceControllerTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.fuelgauge.batterysaver;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AutoBatterySaverPreferenceControllerTest {
+
+ private AutoBatterySaverPreferenceController mController;
+ private Context mContext;
+ private SwitchPreference mPreference;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = RuntimeEnvironment.application;
+ mPreference = new SwitchPreference(mContext);
+ mController = new AutoBatterySaverPreferenceController(mContext);
+ }
+
+ @Test
+ public void testUpdateState_lowPowerLevelZero_preferenceNotChecked() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isChecked()).isFalse();
+ }
+
+ @Test
+ public void testUpdateState_lowPowerLevelZero_preferenceChecked() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 15);
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isChecked()).isTrue();
+ }
+
+ @Test
+ public void testOnPreferenceChange_turnOn_setValueNotZero() {
+ mController.onPreferenceChange(mPreference, true);
+
+ assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0)).isNotEqualTo(0);
+ }
+
+ @Test
+ public void testOnPreferenceChange_turnOff_setValueZero() {
+ mController.onPreferenceChange(mPreference, false);
+
+ assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0)).isEqualTo(0);
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySeekBarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySeekBarPreferenceControllerTest.java
new file mode 100644
index 00000000000..32a4facb6a9
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySeekBarPreferenceControllerTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.fuelgauge.batterysaver;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.arch.lifecycle.LifecycleOwner;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.widget.SeekBarPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AutoBatterySeekBarPreferenceControllerTest {
+ private static final int TRIGGER_LEVEL = 15;
+
+ private AutoBatterySeekBarPreferenceController mController;
+ private Context mContext;
+ private SeekBarPreference mPreference;
+ private Lifecycle mLifecycle;
+ private LifecycleOwner mLifecycleOwner;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mLifecycleOwner = () -> mLifecycle;
+ mLifecycle = new Lifecycle(mLifecycleOwner);
+
+ mContext = RuntimeEnvironment.application;
+ mPreference = new SeekBarPreference(mContext);
+ mPreference.setMax(100);
+ mController = new AutoBatterySeekBarPreferenceController(mContext, mLifecycle);
+ }
+
+ @Test
+ public void testPreference_lowPowerLevelZero_preferenceInvisible() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isVisible()).isFalse();
+ }
+
+ @Test
+ public void testPreference_lowPowerLevelNotZero_updatePreference() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, TRIGGER_LEVEL);
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getTitle()).isEqualTo("Turn on automatically at 15%");
+ assertThat(mPreference.getProgress()).isEqualTo(TRIGGER_LEVEL);
+ }
+
+ @Test
+ public void testOnPreferenceChange_updateValue() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
+
+ mController.onPreferenceChange(mPreference, TRIGGER_LEVEL);
+
+ assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0)).isEqualTo(TRIGGER_LEVEL);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
index d6df6123510..7327d01605f 100644
--- a/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
@@ -29,7 +29,9 @@ import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -238,19 +240,26 @@ public class BlockPreferenceControllerTest {
@Test
public void testOnSwitchChanged_channel_default() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.pkg = "pkg";
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_UNSPECIFIED);
+ when(mBackend.onlyHasDefaultChannel(anyString(), anyInt())).thenReturn(true);
mController.onResume(appRow, channel, null, null);
mController.updateState(mPreference);
mController.onSwitchChanged(null, false);
assertEquals(IMPORTANCE_NONE, channel.getImportance());
+ assertTrue(appRow.banned);
mController.onSwitchChanged(null, true);
assertEquals(IMPORTANCE_UNSPECIFIED, channel.getImportance());
+ assertFalse(appRow.banned);
verify(mBackend, times(2)).updateChannel(any(), anyInt(), any());
+ // 2 calls for onSwitchChanged + once when calling updateState originally
+ verify(mBackend, times(3)).setNotificationsEnabledForPackage(
+ anyString(), anyInt(), anyBoolean());
}
@Test
diff --git a/tests/robotests/src/com/android/settings/notification/EnableZenModeDialogTest.java b/tests/robotests/src/com/android/settings/notification/EnableZenModeDialogTest.java
deleted file mode 100644
index 8b5ef79dcbc..00000000000
--- a/tests/robotests/src/com/android/settings/notification/EnableZenModeDialogTest.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.notification;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.content.Context;
-import android.net.Uri;
-import android.service.notification.Condition;
-import android.view.LayoutInflater;
-
-import com.android.settings.TestConfig;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class EnableZenModeDialogTest {
- private EnableZenModeDialog mController;
-
- @Mock
- private Context mContext;
- @Mock
- private Activity mActivity;
- @Mock
- private Fragment mFragment;
-
- private Context mShadowContext;
- private LayoutInflater mLayoutInflater;
- private Condition mCountdownCondition;
- private Condition mAlarmCondition;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- mShadowContext = RuntimeEnvironment.application;
- when(mActivity.getApplicationContext()).thenReturn(mShadowContext);
- when(mContext.getApplicationContext()).thenReturn(mContext);
- when(mFragment.getContext()).thenReturn(mShadowContext);
- mLayoutInflater = LayoutInflater.from(mShadowContext);
- when(mActivity.getLayoutInflater()).thenReturn(mLayoutInflater);
-
- mController = spy(new EnableZenModeDialog());
- mController.mContext = mContext;
- mController.mActivity = mActivity;
- mController.mForeverId = Condition.newId(mContext).appendPath("forever").build();
- when(mContext.getString(com.android.internal.R.string.zen_mode_forever))
- .thenReturn("testSummary");
- mController.getContentView();
-
- // these methods use static calls to ZenModeConfig which would normally fail in robotests,
- // so instead do nothing:
- doNothing().when(mController).bindGenericCountdown();
- doReturn(null).when(mController).getTimeUntilNextAlarmCondition();
- doNothing().when(mController).bindNextAlarm(any());
-
- // as a result of doing nothing above, must bind manually:
- Uri alarm = Condition.newId(mContext).appendPath("alarm").build();
- mAlarmCondition = new Condition(alarm, "alarm", "", "", 0, 0, 0);
- Uri countdown = Condition.newId(mContext).appendPath("countdown").build();
- mCountdownCondition = new Condition(countdown, "countdown", "", "", 0, 0, 0);
- mController.bind(mCountdownCondition,
- mController.mZenRadioGroupContent.getChildAt(
- EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX),
- EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX);
- mController.bind(mAlarmCondition,
- mController.mZenRadioGroupContent.getChildAt(
- EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX),
- EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX);
- }
-
- @Test
- public void testForeverChecked() {
- mController.bindConditions(mController.forever());
-
- assertTrue(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb
- .isChecked());
- assertFalse(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb
- .isChecked());
- assertFalse(mController.getConditionTagAt(
- EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked());
- }
-
- @Test
- public void testNoneChecked() {
- mController.bindConditions(null);
- assertFalse(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb
- .isChecked());
- assertFalse(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb
- .isChecked());
- assertFalse(mController.getConditionTagAt(
- EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked());
- }
-
- @Test
- public void testAlarmChecked() {
- doReturn(false).when(mController).isCountdown(mAlarmCondition);
- doReturn(true).when(mController).isAlarm(mAlarmCondition);
-
- mController.bindConditions(mAlarmCondition);
- assertFalse(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb
- .isChecked());
- assertFalse(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb
- .isChecked());
- assertTrue(mController.getConditionTagAt(
- EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked());
- }
-
- @Test
- public void testCountdownChecked() {
- doReturn(false).when(mController).isAlarm(mCountdownCondition);
- doReturn(true).when(mController).isCountdown(mCountdownCondition);
-
- mController.bindConditions(mCountdownCondition);
- assertFalse(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb
- .isChecked());
- assertTrue(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb
- .isChecked());
- assertFalse(mController.getConditionTagAt(
- EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked());
- }
-}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationAppPreferenceTest.java b/tests/robotests/src/com/android/settings/notification/NotificationAppPreferenceTest.java
new file mode 100644
index 00000000000..dc8ee1317f6
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/NotificationAppPreferenceTest.java
@@ -0,0 +1,239 @@
+/*
+ * 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.notification;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.Switch;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.RestrictedLockUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class NotificationAppPreferenceTest {
+
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ }
+
+ @Test
+ public void createNewPreference_shouldSetLayout() {
+ final NotificationAppPreference preference = new NotificationAppPreference(mContext);
+ assertThat(preference.getWidgetLayoutResource()).isEqualTo(
+ R.layout.preference_widget_master_switch);
+ }
+
+ @Test
+ public void setChecked_shouldUpdateButtonCheckedState() {
+ final NotificationAppPreference preference = new NotificationAppPreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.preference_app, null));
+ final LinearLayout widgetView = holder.itemView.findViewById(android.R.id.widget_frame);
+ inflater.inflate(R.layout.preference_widget_master_switch, widgetView, true);
+ final Switch toggle = (Switch) holder.findViewById(R.id.switchWidget);
+ preference.onBindViewHolder(holder);
+
+ preference.setChecked(true);
+ assertThat(toggle.isChecked()).isTrue();
+
+ preference.setChecked(false);
+ assertThat(toggle.isChecked()).isFalse();
+ }
+
+ @Test
+ public void setSwitchEnabled_shouldUpdateButtonEnabledState() {
+ final NotificationAppPreference preference = new NotificationAppPreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.preference_app, null));
+ final LinearLayout widgetView = holder.itemView.findViewById(android.R.id.widget_frame);
+ inflater.inflate(R.layout.preference_widget_master_switch, widgetView, true);
+ final Switch toggle = (Switch) holder.findViewById(R.id.switchWidget);
+ preference.onBindViewHolder(holder);
+
+ preference.setSwitchEnabled(true);
+ assertThat(toggle.isEnabled()).isTrue();
+
+ preference.setSwitchEnabled(false);
+ assertThat(toggle.isEnabled()).isFalse();
+ }
+
+ @Test
+ public void setSwitchEnabled_shouldUpdateButtonEnabledState_beforeViewBound() {
+ final NotificationAppPreference preference = new NotificationAppPreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.preference_app, null));
+ final LinearLayout widgetView = holder.itemView.findViewById(android.R.id.widget_frame);
+ inflater.inflate(R.layout.preference_widget_master_switch, widgetView, true);
+ final Switch toggle = (Switch) holder.findViewById(R.id.switchWidget);
+
+ preference.setSwitchEnabled(false);
+ preference.onBindViewHolder(holder);
+ assertThat(toggle.isEnabled()).isFalse();
+ }
+
+ @Test
+ public void clickWidgetView_shouldToggleButton() {
+ final NotificationAppPreference preference = new NotificationAppPreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.preference_app, null));
+ final LinearLayout widgetView = holder.itemView.findViewById(android.R.id.widget_frame);
+ inflater.inflate(R.layout.preference_widget_master_switch, widgetView, true);
+ final Switch toggle = (Switch) holder.findViewById(R.id.switchWidget);
+ preference.onBindViewHolder(holder);
+
+ widgetView.performClick();
+ assertThat(toggle.isChecked()).isTrue();
+
+ widgetView.performClick();
+ assertThat(toggle.isChecked()).isFalse();
+ }
+
+ @Test
+ public void clickWidgetView_shouldNotToggleButtonIfDisabled() {
+ final NotificationAppPreference preference = new NotificationAppPreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.preference_app, null));
+ final LinearLayout widgetView = holder.itemView.findViewById(android.R.id.widget_frame);
+ inflater.inflate(R.layout.preference_widget_master_switch, widgetView, true);
+ final Switch toggle = (Switch) holder.findViewById(R.id.switchWidget);
+ preference.onBindViewHolder(holder);
+ toggle.setEnabled(false);
+
+ widgetView.performClick();
+ assertThat(toggle.isChecked()).isFalse();
+ }
+
+ @Test
+ public void clickWidgetView_shouldNotifyPreferenceChanged() {
+ final NotificationAppPreference preference = new NotificationAppPreference(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ LayoutInflater.from(mContext).inflate(R.layout.preference_app, null));
+ final View widgetView = holder.findViewById(android.R.id.widget_frame);
+ final Preference.OnPreferenceChangeListener
+ listener = mock(Preference.OnPreferenceChangeListener.class);
+ preference.setOnPreferenceChangeListener(listener);
+ preference.onBindViewHolder(holder);
+
+ preference.setChecked(false);
+ widgetView.performClick();
+ verify(listener).onPreferenceChange(preference, true);
+
+ preference.setChecked(true);
+ widgetView.performClick();
+ verify(listener).onPreferenceChange(preference, false);
+ }
+
+ @Test
+ public void setDisabledByAdmin_hasEnforcedAdmin_shouldDisableButton() {
+ final NotificationAppPreference preference = new NotificationAppPreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.preference_app, null));
+ final LinearLayout widgetView = holder.itemView.findViewById(android.R.id.widget_frame);
+ inflater.inflate(R.layout.preference_widget_master_switch, widgetView, true);
+ final Switch toggle = (Switch) holder.findViewById(R.id.switchWidget);
+ toggle.setEnabled(true);
+ preference.onBindViewHolder(holder);
+
+ preference.setDisabledByAdmin(mock(RestrictedLockUtils.EnforcedAdmin.class));
+ assertThat(toggle.isEnabled()).isFalse();
+ }
+
+ @Test
+ public void setDisabledByAdmin_noEnforcedAdmin_shouldEnableButton() {
+ final NotificationAppPreference preference = new NotificationAppPreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.preference_app, null));
+ final LinearLayout widgetView = holder.itemView.findViewById(android.R.id.widget_frame);
+ inflater.inflate(R.layout.preference_widget_master_switch, widgetView, true);
+ final Switch toggle = (Switch) holder.findViewById(R.id.switchWidget);
+ toggle.setEnabled(false);
+ preference.onBindViewHolder(holder);
+
+ preference.setDisabledByAdmin(null);
+ assertThat(toggle.isEnabled()).isTrue();
+ }
+
+ @Test
+ public void onBindViewHolder_toggleButtonShouldHaveContentDescription() {
+ final NotificationAppPreference preference = new NotificationAppPreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.preference_app, null));
+ final LinearLayout widgetView = holder.itemView.findViewById(android.R.id.widget_frame);
+ inflater.inflate(R.layout.preference_widget_master_switch, widgetView, true);
+ final Switch toggle = (Switch) holder.findViewById(R.id.switchWidget);
+ final String label = "TestButton";
+ preference.setTitle(label);
+
+ preference.onBindViewHolder(holder);
+
+ assertThat(toggle.getContentDescription()).isEqualTo(label);
+ }
+
+ @Test
+ public void setSummary_showSummaryContainer() {
+ final NotificationAppPreference preference = new NotificationAppPreference(mContext);
+ View rootView = View.inflate(mContext, R.layout.preference_app, null /* parent */);
+ PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(rootView);
+ preference.setSummary("test");
+ preference.onBindViewHolder(holder);
+
+ assertThat(holder.findViewById(R.id.summary_container).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void noSummary_hideSummaryContainer() {
+ final NotificationAppPreference preference = new NotificationAppPreference(mContext);
+ View rootView = View.inflate(mContext, R.layout.preference_app, null /* parent */);
+ PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(rootView);
+ preference.setSummary(null);
+ preference.onBindViewHolder(holder);
+
+ assertThat(holder.findViewById(R.id.summary_container).getVisibility())
+ .isEqualTo(View.GONE);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
index a25bb002502..1aa963db74c 100644
--- a/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
@@ -31,7 +31,9 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.Activity;
import android.app.Application;
+import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -90,6 +92,10 @@ public class RecentNotifyingAppsPreferenceControllerTest {
private ApplicationInfo mApplicationInfo;
@Mock
private NotificationBackend mBackend;
+ @Mock
+ private Fragment mHost;
+ @Mock
+ private Activity mActivity;
private Context mContext;
private RecentNotifyingAppsPreferenceController mController;
@@ -102,7 +108,7 @@ public class RecentNotifyingAppsPreferenceControllerTest {
doReturn(mPackageManager).when(mContext).getPackageManager();
mController = new RecentNotifyingAppsPreferenceController(
- mContext, mBackend, mAppState, null);
+ mContext, mBackend, mAppState, mHost);
when(mScreen.findPreference(anyString())).thenReturn(mCategory);
when(mScreen.findPreference(RecentNotifyingAppsPreferenceController.KEY_SEE_ALL))
@@ -110,6 +116,7 @@ public class RecentNotifyingAppsPreferenceControllerTest {
when(mScreen.findPreference(RecentNotifyingAppsPreferenceController.KEY_DIVIDER))
.thenReturn(mDivider);
when(mCategory.getContext()).thenReturn(mContext);
+ when(mHost.getActivity()).thenReturn(mActivity);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java
index 1d71a8a5f0a..86f0f2d9639 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java
@@ -19,6 +19,7 @@ package com.android.settings.notification;
import android.app.NotificationManager;
import android.app.NotificationManager.Policy;
import android.content.Context;
+import android.provider.Settings;
import android.support.v7.preference.Preference;
import com.android.settings.R;
@@ -63,7 +64,7 @@ public class ZenModePreferenceControllerTest {
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
mContext = shadowApplication.getApplicationContext();
- mController = new ZenModePreferenceController(mContext);
+ mController = new ZenModePreferenceController(mContext, null);
when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
mSummaryBuilder = spy(new ZenModeSettings.SummaryBuilder(mContext));
ReflectionHelpers.setField(mController, "mSummaryBuilder", mSummaryBuilder);
@@ -76,16 +77,16 @@ public class ZenModePreferenceControllerTest {
}
@Test
- public void updateState_preferenceEnabled_shouldSetSummary() {
+ public void updateState_automaticRuleEnabled_shouldSetSummary() {
when(mPreference.isEnabled()).thenReturn(true);
mController.updateState(mPreference);
- verify(mPreference).setSummary(mContext.getString(R.string.zen_mode_settings_summary_off));
+ verify(mPreference).setSummary(mContext.getResources().getString(
+ R.string.zen_mode_sound_summary_off));
doReturn(1).when(mSummaryBuilder).getEnabledAutomaticRulesCount();
mController.updateState(mPreference);
- verify(mPreference).setSummary(mContext.getResources().getQuantityString(
- R.plurals.zen_mode_settings_summary_on, 1, 1));
+ verify(mPreference).setSummary(mSummaryBuilder.getSoundSummary());
}
@Test
diff --git a/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java
index 42d640a8a10..64a0cea41aa 100644
--- a/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java
@@ -16,14 +16,12 @@
package com.android.settings.security.trustagent;
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
@@ -50,8 +48,6 @@ public class ManageTrustAgentsPreferenceControllerTest {
private TrustAgentManager mTrustAgentManager;
@Mock
private LockPatternUtils mLockPatternUtils;
- @Mock
- private PreferenceScreen mScreen;
private FakeFeatureFactory mFeatureFactory;
private Context mContext;
@@ -70,8 +66,6 @@ public class ManageTrustAgentsPreferenceControllerTest {
mController = new ManageTrustAgentsPreferenceController(mContext);
mPreference = new Preference(mContext);
mPreference.setKey(mController.getPreferenceKey());
- when(mScreen.findPreference(mController.getPreferenceKey()))
- .thenReturn(mPreference);
}
@Test
@@ -86,10 +80,10 @@ public class ManageTrustAgentsPreferenceControllerTest {
}
@Test
- public void displayPreference_isNotSecure_shouldDisablePreference() {
+ public void updateState_isNotSecure_shouldDisablePreference() {
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
- mController.displayPreference(mScreen);
+ mController.updateState(mPreference);
assertThat(mPreference.isEnabled()).isFalse();
assertThat(mPreference.getSummary())
@@ -97,12 +91,12 @@ public class ManageTrustAgentsPreferenceControllerTest {
}
@Test
- public void displayPreference_isSecure_noTrustAgent_shouldShowGenericSummary() {
+ public void updateState_isSecure_noTrustAgent_shouldShowGenericSummary() {
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
when(mTrustAgentManager.getActiveTrustAgents(mContext, mLockPatternUtils))
.thenReturn(new ArrayList<>());
- mController.displayPreference(mScreen);
+ mController.updateState(mPreference);
assertThat(mPreference.isEnabled()).isTrue();
assertThat(mPreference.getSummary())
@@ -110,12 +104,12 @@ public class ManageTrustAgentsPreferenceControllerTest {
}
@Test
- public void displayPreference_isSecure_hasTrustAgent_shouldShowDetailedSummary() {
+ public void updateState_isSecure_hasTrustAgent_shouldShowDetailedSummary() {
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
when(mTrustAgentManager.getActiveTrustAgents(mContext, mLockPatternUtils))
.thenReturn(Arrays.asList(new TrustAgentManager.TrustAgentComponentInfo()));
- mController.displayPreference(mScreen);
+ mController.updateState(mPreference);
assertThat(mPreference.isEnabled()).isTrue();
assertThat(mPreference.getSummary())
diff --git a/tests/robotests/src/com/android/settings/wallpaper/WallpaperSuggestionActivityTest.java b/tests/robotests/src/com/android/settings/wallpaper/WallpaperSuggestionActivityTest.java
index ced4b0ac31a..daaf4b3e857 100644
--- a/tests/robotests/src/com/android/settings/wallpaper/WallpaperSuggestionActivityTest.java
+++ b/tests/robotests/src/com/android/settings/wallpaper/WallpaperSuggestionActivityTest.java
@@ -17,12 +17,14 @@
package com.android.settings.wallpaper;
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import com.android.settings.SubSettings;
import com.android.settings.TestConfig;
@@ -42,16 +44,16 @@ import org.robolectric.annotation.Implements;
import org.robolectric.shadows.ShadowActivity;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows = {
- WallpaperSuggestionActivityTest.ShadowWallpaperManagerWrapper.class
- })
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class WallpaperSuggestionActivityTest {
@Mock
private Context mContext;
@Mock
private PackageManager mPackageManager;
+ @Mock
+ private Resources mResources;
+
private ActivityController mController;
@Before
@@ -72,6 +74,17 @@ public class WallpaperSuggestionActivityTest {
}
@Test
+ public void wallpaperServiceEnabled_no_shouldReturnFalse() {
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mResources.getBoolean(
+ com.android.internal.R.bool.config_enableWallpaperService)).thenReturn(false);
+
+ assertThat(WallpaperSuggestionActivity.isSuggestionComplete(mContext))
+ .isFalse();
+ }
+
+ @Test
+ @Config(shadows = WallpaperSuggestionActivityTest.ShadowWallpaperManagerWrapper.class)
public void hasWallpaperSet_no_shouldReturnFalse() {
ShadowWallpaperManagerWrapper.setWallpaperId(0);
@@ -80,6 +93,7 @@ public class WallpaperSuggestionActivityTest {
}
@Test
+ @Config(shadows = WallpaperSuggestionActivityTest.ShadowWallpaperManagerWrapper.class)
public void hasWallpaperSet_yes_shouldReturnTrue() {
ShadowWallpaperManagerWrapper.setWallpaperId(100);
@@ -100,6 +114,15 @@ public class WallpaperSuggestionActivityTest {
sWallpaperId = 0;
}
+ public void __constructor__(Context context) {
+
+ }
+
+ @Implementation
+ public boolean isWallpaperServiceEnabled() {
+ return true;
+ }
+
@Implementation
public int getWallpaperId(int which) {
return sWallpaperId;
diff --git a/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java
new file mode 100644
index 00000000000..7a042a06d82
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.widget;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.os.Parcelable;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SeekBarPreferenceTest {
+ private static final int MAX = 75;
+ private static final int MIN = 5;
+ private static final int PROGRESS = 16;
+
+ private Context mContext;
+ private SeekBarPreference mSeekBarPreference;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+
+ mSeekBarPreference = new SeekBarPreference(mContext);
+ mSeekBarPreference.setMax(MAX);
+ mSeekBarPreference.setMin(MIN);
+ mSeekBarPreference.setProgress(PROGRESS);
+ mSeekBarPreference.setPersistent(false);
+ }
+
+ @Test
+ public void testSaveAndRestoreInstanceState() {
+ final Parcelable parcelable = mSeekBarPreference.onSaveInstanceState();
+
+ final SeekBarPreference preference = new SeekBarPreference(mContext);
+ preference.onRestoreInstanceState(parcelable);
+
+ assertThat(preference.getMax()).isEqualTo(MAX);
+ assertThat(preference.getMin()).isEqualTo(MIN);
+ assertThat(preference.getProgress()).isEqualTo(PROGRESS);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java b/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java
index 2eaa5875012..c122a65c02c 100644
--- a/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java
@@ -16,6 +16,8 @@
package com.android.settings.wifi;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -75,4 +77,9 @@ public class ConnectedAccessPointPreferenceTest {
verify(mOnGearClickListener, never()).onGearClick(mConnectedAccessPointPreference);
}
+ @Test
+ public void testWidgetLayoutPreference() {
+ assertThat(mConnectedAccessPointPreference.getWidgetLayoutResource()).isEqualTo(
+ R.layout.preference_widget_gear_no_bg);
+ }
}