diff --git a/res/layout/data_usage_spinner_item.xml b/res/layout/data_usage_spinner_item.xml
new file mode 100644
index 00000000000..1706edfc508
--- /dev/null
+++ b/res/layout/data_usage_spinner_item.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f68323a6763..567f255c2ae 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7998,7 +7998,7 @@
App modify system settings permission
- Allow modify system settings
+ Allow modifying system settings
This permission allows an app to modify system settings.
diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java
index 9c61873cb99..d4397dc1c13 100644
--- a/src/com/android/settings/dashboard/DashboardAdapter.java
+++ b/src/com/android/settings/dashboard/DashboardAdapter.java
@@ -31,7 +31,6 @@ import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
-import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -47,11 +46,9 @@ import com.android.settings.dashboard.DashboardData.SuggestionConditionHeaderDat
import com.android.settings.dashboard.conditional.Condition;
import com.android.settings.dashboard.conditional.ConditionAdapter;
import com.android.settings.dashboard.suggestions.SuggestionAdapter;
-import com.android.settings.dashboard.suggestions.SuggestionController;
import com.android.settings.dashboard.suggestions.SuggestionControllerMixin;
import com.android.settings.dashboard.suggestions.SuggestionDismissController;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
-import com.android.settings.dashboard.suggestions.SuggestionLogHelper;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.Utils;
import com.android.settingslib.drawer.DashboardCategory;
@@ -164,24 +161,6 @@ public class DashboardAdapter extends RecyclerView.Adapter shownSuggestions = null;
- final int mode = mDashboardData.getSuggestionConditionMode();
- if (mode == DashboardData.HEADER_MODE_DEFAULT) {
- shownSuggestions = suggestions.subList(0,
- Math.min(suggestions.size(), DashboardData.DEFAULT_SUGGESTION_COUNT));
- } else if (mode != DashboardData.HEADER_MODE_COLLAPSED) {
- shownSuggestions = suggestions;
- }
- if (shownSuggestions != null) {
- for (Tile suggestion : shownSuggestions) {
- final String identifier = mSuggestionFeatureProvider.getSuggestionIdentifier(
- mContext, suggestion);
- mMetricsFeatureProvider.action(
- mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, identifier,
- getSuggestionTaggedData());
- mSuggestionsShownLogged.add(identifier);
- }
- }
}
public void setSuggestionsV2(List data) {
@@ -191,7 +170,6 @@ public class DashboardAdapter extends RecyclerView.Adapter suggestions = mDashboardData.getSuggestions();
- if (suggestions == null) {
- return;
- }
- for (Tile suggestion : suggestions) {
- final String suggestionId = mSuggestionFeatureProvider.getSuggestionIdentifier(
- mContext, suggestion);
- if (!mSuggestionsShownLogged.contains(suggestionId)) {
- mMetricsFeatureProvider.action(
- mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, suggestionId,
- getSuggestionTaggedData());
- mSuggestionsShownLogged.add(suggestionId);
- }
- }
- }
-
@VisibleForTesting
void onBindSuggestionConditionHeader(final SuggestionAndConditionHeaderHolder holder,
SuggestionConditionHeaderData data) {
@@ -460,9 +405,7 @@ public class DashboardAdapter extends RecyclerView.Adapter {
- if (moreSuggestions) {
- logSuggestions();
- } else if (hasConditions) {
+ if (hasConditions) {
mMetricsFeatureProvider.action(mContext,
MetricsEvent.ACTION_SETTINGS_CONDITION_EXPAND, true);
}
@@ -587,11 +530,6 @@ public class DashboardAdapter extends RecyclerView.Adapter[] getSuggestionTaggedData() {
- return SuggestionLogHelper.getSuggestionTaggedData(
- mSuggestionFeatureProvider.isSmartSuggestionEnabled(mContext));
- }
-
public static class IconCache {
private final Context mContext;
private final ArrayMap mMap = new ArrayMap<>();
diff --git a/src/com/android/settings/dashboard/DashboardSummary.java b/src/com/android/settings/dashboard/DashboardSummary.java
index 4810c7227b3..30a2fce8d7e 100644
--- a/src/com/android/settings/dashboard/DashboardSummary.java
+++ b/src/com/android/settings/dashboard/DashboardSummary.java
@@ -152,9 +152,6 @@ public class DashboardSummary extends InstrumentedFragment
mMetricsFeatureProvider.hidden(getContext(), c.getMetricsConstant());
}
}
- if (!getActivity().isChangingConfigurations()) {
- mAdapter.onPause();
- }
}
@Override
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
index 2a9463fe929..8502fa7f2cf 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
@@ -21,7 +21,6 @@ import android.service.settings.suggestions.Suggestion;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
-import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -131,7 +130,7 @@ public class SuggestionAdapter extends RecyclerView.Adapter
if (!mSuggestionsShownLogged.contains(suggestionId)) {
mMetricsFeatureProvider.action(
mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, suggestionId,
- getSuggestionTaggedData());
+ mSuggestionFeatureProvider.getLoggingTaggedData(mContext));
mSuggestionsShownLogged.add(suggestionId);
}
if (suggestion.remoteViews != null) {
@@ -165,7 +164,7 @@ public class SuggestionAdapter extends RecyclerView.Adapter
clickHandler.setOnClickListener(v -> {
mMetricsFeatureProvider.action(mContext,
MetricsEvent.ACTION_SETTINGS_SUGGESTION, suggestionId,
- getSuggestionTaggedData());
+ mSuggestionFeatureProvider.getLoggingTaggedData(mContext));
((SettingsActivity) mContext).startSuggestion(suggestion.intent);
});
}
@@ -237,11 +236,6 @@ public class SuggestionAdapter extends RecyclerView.Adapter
notifyDataSetChanged();
}
- private Pair[] getSuggestionTaggedData() {
- return SuggestionLogHelper.getSuggestionTaggedData(
- mSuggestionFeatureProvider.isSmartSuggestionEnabled(mContext));
- }
-
public void removeSuggestion(Suggestion suggestion) {
mSuggestionsV2.remove(suggestion);
notifyDataSetChanged();
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java
index 0f8bccc660d..f9114011a0e 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.service.settings.suggestions.Suggestion;
import android.support.annotation.NonNull;
+import android.util.Pair;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.suggestions.SuggestionParser;
@@ -93,6 +94,14 @@ public interface SuggestionFeatureProvider {
/**
* Returns an identifier for the suggestion
+ *
+ * @deprecated in favor or {@link Suggestion#getId()}
*/
+ @Deprecated
String getSuggestionIdentifier(Context context, Tile suggestion);
+
+ /**
+ * Returns common tagged data for suggestion logging.
+ */
+ Pair[] getLoggingTaggedData(Context context);
}
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
index 02a9223fec6..783987dc8b0 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
@@ -170,8 +170,7 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider
if (parser == null || suggestion == null || context == null) {
return;
}
- final Pair[] taggedData =
- SuggestionLogHelper.getSuggestionTaggedData(isSmartSuggestionEnabled(context));
+ final Pair[] taggedData = getLoggingTaggedData(context);
mMetricsFeatureProvider.action(
context, MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION,
@@ -213,6 +212,14 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider
return packageName;
}
+ @Override
+ public Pair[] getLoggingTaggedData(Context context) {
+ final boolean isSmartSuggestionEnabled = isSmartSuggestionEnabled(context);
+ return new Pair[]{Pair.create(
+ MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED,
+ isSmartSuggestionEnabled ? 1 : 0)};
+ }
+
@VisibleForTesting
boolean hasUsedNightDisplay(Context context) {
final ContentResolver cr = context.getContentResolver();
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionLogHelper.java b/src/com/android/settings/dashboard/suggestions/SuggestionLogHelper.java
deleted file mode 100644
index 339392fa780..00000000000
--- a/src/com/android/settings/dashboard/suggestions/SuggestionLogHelper.java
+++ /dev/null
@@ -1,29 +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.dashboard.suggestions;
-
-import android.util.Pair;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-public class SuggestionLogHelper {
-
- public static Pair[] getSuggestionTaggedData(boolean enabled) {
- return new Pair[]{
- Pair.create(
- MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, enabled ? 1 : 0)};
- }
-}
diff --git a/src/com/android/settings/datausage/BillingCycleSettings.java b/src/com/android/settings/datausage/BillingCycleSettings.java
index d00749d837e..fb8119c60e4 100644
--- a/src/com/android/settings/datausage/BillingCycleSettings.java
+++ b/src/com/android/settings/datausage/BillingCycleSettings.java
@@ -264,7 +264,7 @@ public class BillingCycleSettings extends DataUsageBase implements
formatter.getUnitDisplayName(MeasureUnit.GIGABYTE)
};
final ArrayAdapter adapter = new ArrayAdapter(
- getContext(), android.R.layout.simple_spinner_item, unitNames);
+ getContext(), R.layout.data_usage_spinner_item, unitNames);
type.setAdapter(adapter);
if (bytes > 1.5f * GB_IN_BYTES) {
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index a867330d040..8f61c52d897 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -280,7 +280,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
controllers.add(new WifiRoamScansPreferenceController(context));
controllers.add(new MobileDataAlwaysOnPreferenceController(context));
controllers.add(new TetheringHardwareAccelPreferenceController(context));
- // select usb configuration
+ controllers.add(new SelectUsbConfigPreferenceController(context, lifecycle));
controllers.add(new BluetoothDeviceNoNamePreferenceController(context));
controllers.add(new BluetoothAbsoluteVolumePreferenceController(context));
controllers.add(new BluetoothInbandRingingPreferenceController(context));
diff --git a/src/com/android/settings/development/SelectUsbConfigPreferenceController.java b/src/com/android/settings/development/SelectUsbConfigPreferenceController.java
new file mode 100644
index 00000000000..41fe6a3967e
--- /dev/null
+++ b/src/com/android/settings/development/SelectUsbConfigPreferenceController.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.development;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbManager;
+import android.os.Bundle;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.TextUtils;
+
+import com.android.settings.R;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnCreate;
+import com.android.settingslib.core.lifecycle.events.OnDestroy;
+
+public class SelectUsbConfigPreferenceController extends
+ DeveloperOptionsPreferenceController implements
+ Preference.OnPreferenceChangeListener, LifecycleObserver, OnCreate, OnDestroy {
+
+ private static final String USB_CONFIGURATION_KEY = "select_usb_configuration";
+
+ private final String[] mListValues;
+ private final String[] mListSummaries;
+ private final UsbManager mUsbManager;
+ private BroadcastReceiver mUsbReceiver;
+ private ListPreference mPreference;
+
+ public SelectUsbConfigPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context);
+
+ mListValues = context.getResources().getStringArray(R.array.usb_configuration_values);
+ mListSummaries = context.getResources().getStringArray(R.array.usb_configuration_titles);
+ mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
+ mUsbReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (mPreference != null) {
+ updateUsbConfigurationValues();
+ }
+ }
+ };
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(UsbManager.ACTION_USB_STATE);
+ mContext.registerReceiver(mUsbReceiver, filter);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return USB_CONFIGURATION_KEY;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+
+ mPreference = (ListPreference) screen.findPreference(getPreferenceKey());
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ writeUsbConfigurationOption(newValue.toString());
+ updateUsbConfigurationValues();
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ updateUsbConfigurationValues();
+ }
+
+ @Override
+ public void onDestroy() {
+ mContext.unregisterReceiver(mUsbReceiver);
+ }
+
+ @Override
+ protected void onDeveloperOptionsSwitchEnabled() {
+ mPreference.setEnabled(true);
+ }
+
+ @Override
+ protected void onDeveloperOptionsSwitchDisabled() {
+ mPreference.setEnabled(false);
+ }
+
+ @VisibleForTesting
+ void setCurrentFunction(String newValue, boolean usbDataUnlocked) {
+ mUsbManager.setCurrentFunction(newValue, usbDataUnlocked);
+ }
+
+ private void updateUsbConfigurationValues() {
+ int index = 0;
+ for (int i = 0; i < mListValues.length; i++) {
+ if (mUsbManager.isFunctionEnabled(mListValues[i])) {
+ index = i;
+ break;
+ }
+ }
+ mPreference.setValue(mListValues[index]);
+ mPreference.setSummary(mListSummaries[index]);
+ }
+
+ private void writeUsbConfigurationOption(String newValue) {
+ if (TextUtils.equals(newValue, "none")) {
+ setCurrentFunction(newValue, false);
+ } else {
+ setCurrentFunction(newValue, true);
+ }
+ }
+
+}
diff --git a/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java b/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java
index 382c6921dbf..3791d89c8de 100644
--- a/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java
+++ b/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java
@@ -17,6 +17,7 @@
package com.android.settings.fuelgauge.anomaly;
import android.content.Context;
+import android.net.Uri;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
import android.text.format.DateUtils;
@@ -25,6 +26,10 @@ import android.util.Log;
import com.android.settings.wrapper.KeyValueListParserWrapper;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
/**
* Class to store the policy for anomaly detection, which comes from
* {@link android.provider.Settings.Global}
@@ -45,6 +50,8 @@ public class AnomalyDetectionPolicy {
@VisibleForTesting
static final String KEY_WAKEUP_ALARM_THRESHOLD = "wakeup_alarm_threshold";
@VisibleForTesting
+ static final String KEY_WAKEUP_BLACKLISTED_TAGS = "wakeup_blacklisted_tags";
+ @VisibleForTesting
static final String KEY_BLUETOOTH_SCAN_THRESHOLD = "bluetooth_scan_threshold";
/**
@@ -95,6 +102,14 @@ public class AnomalyDetectionPolicy {
*/
public final long wakeupAlarmThreshold;
+ /**
+ * Array of blacklisted wakeups, by tag.
+ *
+ * @see Settings.Global#ANOMALY_DETECTION_CONSTANTS
+ * @see #KEY_WAKEUP_BLACKLISTED_TAGS
+ */
+ public final Set wakeupBlacklistedTags;
+
/**
* Threshold for bluetooth unoptimized scanning time in milli seconds
*
@@ -121,15 +136,18 @@ public class AnomalyDetectionPolicy {
Log.e(TAG, "Bad anomaly detection constants");
}
- anomalyDetectionEnabled = mParserWrapper.getBoolean(KEY_ANOMALY_DETECTION_ENABLED, true);
- wakeLockDetectionEnabled = mParserWrapper.getBoolean(KEY_WAKELOCK_DETECTION_ENABLED, true);
- wakeupAlarmDetectionEnabled = mParserWrapper.getBoolean(KEY_WAKEUP_ALARM_DETECTION_ENABLED,
- false);
+ anomalyDetectionEnabled =
+ mParserWrapper.getBoolean(KEY_ANOMALY_DETECTION_ENABLED, false);
+ wakeLockDetectionEnabled =
+ mParserWrapper.getBoolean(KEY_WAKELOCK_DETECTION_ENABLED,false);
+ wakeupAlarmDetectionEnabled =
+ mParserWrapper.getBoolean(KEY_WAKEUP_ALARM_DETECTION_ENABLED,false);
bluetoothScanDetectionEnabled = mParserWrapper.getBoolean(
- KEY_BLUETOOTH_SCAN_DETECTION_ENABLED, true);
+ KEY_BLUETOOTH_SCAN_DETECTION_ENABLED, false);
wakeLockThreshold = mParserWrapper.getLong(KEY_WAKELOCK_THRESHOLD,
DateUtils.HOUR_IN_MILLIS);
- wakeupAlarmThreshold = mParserWrapper.getLong(KEY_WAKEUP_ALARM_THRESHOLD, 60);
+ wakeupAlarmThreshold = mParserWrapper.getLong(KEY_WAKEUP_ALARM_THRESHOLD, 10);
+ wakeupBlacklistedTags = parseStringSet(KEY_WAKEUP_BLACKLISTED_TAGS, null);
bluetoothScanThreshold = mParserWrapper.getLong(KEY_BLUETOOTH_SCAN_THRESHOLD,
30 * DateUtils.MINUTE_IN_MILLIS);
}
@@ -150,4 +168,14 @@ public class AnomalyDetectionPolicy {
return false; // Disabled when no this type
}
}
+
+ private Set parseStringSet(final String key, final Set defaultSet) {
+ final String value = mParserWrapper.getString(key, null);
+ if (value != null) {
+ return Arrays.stream(value.split(":"))
+ .map(String::trim).map(Uri::decode).collect(Collectors.toSet());
+ } else {
+ return defaultSet;
+ }
+ }
}
diff --git a/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetector.java b/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetector.java
index 8823a177092..46f31ab3a8e 100644
--- a/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetector.java
+++ b/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetector.java
@@ -21,6 +21,8 @@ import android.os.BatteryStats;
import android.support.annotation.VisibleForTesting;
import android.text.format.DateUtils;
import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
@@ -29,10 +31,12 @@ import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.anomaly.Anomaly;
import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy;
import com.android.settings.fuelgauge.anomaly.AnomalyUtils;
-import com.android.settings.fuelgauge.anomaly.action.AnomalyAction;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
* Check whether apps has too many wakeup alarms
@@ -42,6 +46,7 @@ public class WakeupAlarmAnomalyDetector implements AnomalyDetector {
@VisibleForTesting
BatteryUtils mBatteryUtils;
private long mWakeupAlarmThreshold;
+ private Set mWakeupBlacklistedTags;
private Context mContext;
private AnomalyUtils mAnomalyUtils;
@@ -56,6 +61,7 @@ public class WakeupAlarmAnomalyDetector implements AnomalyDetector {
mBatteryUtils = BatteryUtils.getInstance(context);
mAnomalyUtils = anomalyUtils;
mWakeupAlarmThreshold = policy.wakeupAlarmThreshold;
+ mWakeupBlacklistedTags = policy.wakeupBlacklistedTags;
}
@Override
@@ -123,11 +129,14 @@ public class WakeupAlarmAnomalyDetector implements AnomalyDetector {
final BatteryStats.Uid.Pkg ps = packageStats.valueAt(ipkg);
final ArrayMap alarms =
ps.getWakeupAlarmStats();
- for (int iwa = alarms.size() - 1; iwa >= 0; iwa--) {
- int count = alarms.valueAt(iwa).getCountLocked(BatteryStats.STATS_SINCE_CHARGED);
+ for (Map.Entry alarm : alarms.entrySet()) {
+ if (mWakeupBlacklistedTags != null
+ && mWakeupBlacklistedTags.contains(alarm.getKey())) {
+ continue;
+ }
+ int count = alarm.getValue().getCountLocked(BatteryStats.STATS_SINCE_CHARGED);
wakeups += count;
}
-
}
return wakeups;
diff --git a/src/com/android/settings/wrapper/KeyValueListParserWrapper.java b/src/com/android/settings/wrapper/KeyValueListParserWrapper.java
index 16dc50eecdc..3fab5711db0 100644
--- a/src/com/android/settings/wrapper/KeyValueListParserWrapper.java
+++ b/src/com/android/settings/wrapper/KeyValueListParserWrapper.java
@@ -56,12 +56,22 @@ public class KeyValueListParserWrapper {
* Get the value for key as a boolean.
* @param key The key to lookup.
* @param defaultValue The value to return if the key was not found.
- * @return the string value associated with the key.
+ * @return the boolean value associated with the key.
*/
public boolean getBoolean(String key, boolean defaultValue) {
return mParser.getBoolean(key, defaultValue);
}
+ /**
+ * Get the value for key as a string.
+ * @param key The key to lookup.
+ * @param defaultValue The value to return if the key was not found.
+ * @return the string value associated with the key.
+ */
+ public String getString(String key, String defaultValue) {
+ return mParser.getString(key, defaultValue);
+ }
+
/**
* Get the value for key as a long.
* @param key The key to lookup.
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
index 595a9c6f739..14da5d6cd79 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
@@ -24,7 +24,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -39,12 +38,10 @@ import android.os.Bundle;
import android.service.settings.suggestions.Suggestion;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
-import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.RelativeLayout;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.TestConfig;
@@ -61,8 +58,6 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
@@ -88,12 +83,6 @@ public class DashboardAdapterTest {
private Condition mCondition;
@Mock
private Resources mResources;
- @Captor
- private ArgumentCaptor mActionCategoryCaptor = ArgumentCaptor.forClass(Integer.class);
- @Captor
- private ArgumentCaptor mActionPackageCaptor = ArgumentCaptor.forClass(String.class);
- @Captor
- private ArgumentCaptor mTaggedDataCaptor = ArgumentCaptor.forClass(Pair.class);
private FakeFeatureFactory mFactory;
private DashboardAdapter mDashboardAdapter;
private DashboardAdapter.SuggestionAndConditionHeaderHolder mSuggestionHolder;
@@ -110,7 +99,7 @@ public class DashboardAdapterTest {
.getSuggestionIdentifier(any(Context.class), any(Tile.class)))
.thenAnswer(invocation -> {
final Object[] args = invocation.getArguments();
- return ((Tile)args[1]).intent.getComponent().getPackageName();
+ return ((Tile) args[1]).intent.getComponent().getPackageName();
});
when(mContext.getResources()).thenReturn(mResources);
@@ -125,282 +114,6 @@ public class DashboardAdapterTest {
when(mView.getTag()).thenReturn(mCondition);
}
- @Test
- public void testSuggestionsLogs_NotExpanded() {
- setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
-
- verify(mFactory.metricsFeatureProvider, times(2)).action(
- any(Context.class), mActionCategoryCaptor.capture(),
- mActionPackageCaptor.capture(),
- mTaggedDataCaptor.capture());
- assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION);
- assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg2");
- assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
- }
-
- @Test
- public void testSuggestionsLogs_NotExpandedAndPaused() {
- setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
-
- mDashboardAdapter.onPause();
-
- verify(mFactory.metricsFeatureProvider, times(4)).action(
- any(Context.class), mActionCategoryCaptor.capture(),
- mActionPackageCaptor.capture(),
- mTaggedDataCaptor.capture());
- assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION);
- assertThat(mActionPackageCaptor.getAllValues()).containsExactly(
- "pkg1", "pkg2", "pkg1", "pkg2");
- assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
- }
-
- @Test
- public void testSuggestionsLogs_Expanded() {
- setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
-
- mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
- mSuggestionHolder.itemView.callOnClick();
-
- verify(mFactory.metricsFeatureProvider, times(3)).action(
- any(Context.class), mActionCategoryCaptor.capture(),
- mActionPackageCaptor.capture(),
- mTaggedDataCaptor.capture());
- assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION);
- assertThat(mActionPackageCaptor.getAllValues()).containsExactly(
- "pkg1", "pkg2", "pkg3");
- assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
- }
-
- @Test
- public void testSuggestionsLogs_ExpandedAndPaused() {
- setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
-
- mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
- mSuggestionHolder.itemView.callOnClick();
- mDashboardAdapter.onPause();
-
- verify(mFactory.metricsFeatureProvider, times(6)).action(
- any(Context.class), mActionCategoryCaptor.capture(),
- mActionPackageCaptor.capture(),
- mTaggedDataCaptor.capture());
- assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION);
- assertThat(mActionPackageCaptor.getAllValues()).containsExactly(
- "pkg1", "pkg2", "pkg3", "pkg1", "pkg2", "pkg3");
- assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
- }
-
- @Test
- public void testSuggestionsLogs_ExpandedAfterPause() {
- setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
-
- mDashboardAdapter.onPause();
- mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
- mSuggestionHolder.itemView.callOnClick();
-
- verify(mFactory.metricsFeatureProvider, times(7)).action(
- any(Context.class), mActionCategoryCaptor.capture(),
- mActionPackageCaptor.capture(),
- mTaggedDataCaptor.capture());
- assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION);
- assertThat(mActionPackageCaptor.getAllValues()).containsExactly(
- "pkg1", "pkg2", "pkg1", "pkg2", "pkg1", "pkg2", "pkg3");
- assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
- }
-
- @Test
- public void testSuggestionsLogs_ExpandedAfterPauseAndPausedAgain() {
- setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
-
- mDashboardAdapter.onPause();
- mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
- mSuggestionHolder.itemView.callOnClick();
- mDashboardAdapter.onPause();
-
- verify(mFactory.metricsFeatureProvider, times(10)).action(
- any(Context.class), mActionCategoryCaptor.capture(),
- mActionPackageCaptor.capture(),
- mTaggedDataCaptor.capture());
- assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION);
- assertThat(mActionPackageCaptor.getAllValues()).containsExactly(
- "pkg1", "pkg2", "pkg1", "pkg2", "pkg1", "pkg2", "pkg3", "pkg1", "pkg2", "pkg3");
- assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
- }
-
- @Test
- public void testSuggestionsLogs_ExpandedWithLessThanDefaultShown() {
- setupSuggestions(makeSuggestions("pkg1"));
-
- mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
- mSuggestionHolder.itemView.callOnClick();
-
- verify(mFactory.metricsFeatureProvider, times(1)).action(
- any(Context.class), mActionCategoryCaptor.capture(),
- mActionPackageCaptor.capture(),
- mTaggedDataCaptor.capture());
- assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION);
- assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1");
- assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
- }
-
- @Test
- public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAndPaused() {
- setupSuggestions(makeSuggestions("pkg1"));
-
- mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
- mSuggestionHolder.itemView.callOnClick();
- mDashboardAdapter.onPause();
-
- verify(mFactory.metricsFeatureProvider, times(2)).action(
- any(Context.class), mActionCategoryCaptor.capture(),
- mActionPackageCaptor.capture(),
- mTaggedDataCaptor.capture());
- assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION);
- assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg1");
- assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
- }
-
- @Test
- public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAfterPause() {
- setupSuggestions(makeSuggestions("pkg1"));
-
- mDashboardAdapter.onPause();
- mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
- mSuggestionHolder.itemView.callOnClick();
-
- verify(mFactory.metricsFeatureProvider, times(3)).action(
- any(Context.class), mActionCategoryCaptor.capture(),
- mActionPackageCaptor.capture(),
- mTaggedDataCaptor.capture());
- assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION);
- assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg1", "pkg1");
- assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
- }
-
- @Test
- public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAfterPauseAndPausedAgain() {
- setupSuggestions(makeSuggestions("pkg1"));
- mDashboardAdapter.onPause();
- mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
- mSuggestionHolder.itemView.callOnClick();
- mDashboardAdapter.onPause();
-
- verify(mFactory.metricsFeatureProvider, times(4)).action(
- any(Context.class), mActionCategoryCaptor.capture(),
- mActionPackageCaptor.capture(),
- mTaggedDataCaptor.capture());
- assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION);
- assertThat(mActionPackageCaptor.getAllValues()).containsExactly(
- "pkg1", "pkg1", "pkg1", "pkg1");
- assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
- }
-
- @Test
- public void testSuggestionsLogs_SmartSuggestionEnabled() {
- when(mFactory.suggestionsFeatureProvider
- .isSmartSuggestionEnabled(any(Context.class))).thenReturn(true);
- setupSuggestions(makeSuggestions("pkg1"));
-
- mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
- mSuggestionHolder.itemView.callOnClick();
- mDashboardAdapter.onPause();
-
- verify(mFactory.metricsFeatureProvider, times(2)).action(
- any(Context.class), mActionCategoryCaptor.capture(),
- mActionPackageCaptor.capture(),
- mTaggedDataCaptor.capture());
- assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
- MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION);
- assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg1");
- assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1),
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1));
- }
-
@Test
public void testSuggestionsLogs_nullSuggestionsList_shouldNotCrash() {
setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3", "pkg4", "pkg5"));
@@ -618,6 +331,10 @@ public class DashboardAdapterTest {
verify(data).setAdapter(any(ConditionAdapter.class));
}
+ /**
+ * @deprecated in favor of {@link #makeSuggestionsV2(String...)}
+ */
+ @Deprecated
private List makeSuggestions(String... pkgNames) {
final List suggestions = new ArrayList<>();
for (String pkgName : pkgNames) {
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 d43a1692abf..825b388f018 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java
@@ -39,6 +39,7 @@ import android.widget.LinearLayout;
import android.widget.RemoteViews;
import android.widget.TextView;
+import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.TestConfig;
@@ -66,7 +67,7 @@ public class SuggestionAdapterTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private SettingsActivity mActivity;
-
+ private FakeFeatureFactory mFeatureFactory;
private Context mContext;
private SuggestionAdapter mSuggestionAdapter;
private DashboardAdapter.DashboardItemHolder mSuggestionHolder;
@@ -79,7 +80,7 @@ public class SuggestionAdapterTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- FakeFeatureFactory.setupForTest(mActivity);
+ mFeatureFactory = FakeFeatureFactory.setupForTest(mActivity);
final Tile suggestion1 = new Tile();
final Tile suggestion2 = new Tile();
@@ -171,6 +172,24 @@ public class SuggestionAdapterTest {
verify(view).setOnClickListener(any(View.OnClickListener.class));
}
+ @Test
+ public void onBindViewHolder_shouldLog() {
+ final View view = spy(LayoutInflater.from(mContext).inflate(
+ R.layout.suggestion_tile, new LinearLayout(mContext), true));
+ mSuggestionHolder = new DashboardAdapter.DashboardItemHolder(view);
+ mSuggestionAdapter = new SuggestionAdapter(mContext, null /* suggestionV1*/,
+ mOneSuggestionV2, new ArrayList<>());
+
+ // Bind twice
+ mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
+ mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
+
+ // Log once
+ verify(mFeatureFactory.metricsFeatureProvider).action(
+ mContext, MetricsProto.MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
+ mOneSuggestionV2.get(0).getId());
+ }
+
@Test
public void onBindViewHolder_shouldInflateRemoteView() {
List packages = makeSuggestions("pkg1");
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
index 69b76fa8a31..5e567144a2e 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
@@ -22,6 +22,7 @@ import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@@ -313,4 +314,19 @@ public class SuggestionFeatureProviderImplTest {
new ComponentName(mContext, NightDisplaySuggestionActivity.class);
assertThat(mProvider.isSuggestionComplete(mContext, componentName)).isFalse();
}
+
+ @Test
+ public void testGetSmartSuggestionEnabledTaggedData_disabled() {
+ assertThat(mProvider.getLoggingTaggedData(mContext)).asList().containsExactly(
+ Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
+ }
+
+ @Test
+ public void testGetSmartSuggestionEnabledTaggedData_enabled() {
+ final SuggestionFeatureProvider provider = spy(mProvider);
+ when(provider.isSmartSuggestionEnabled(any(Context.class))).thenReturn(true);
+
+ assertThat(provider.getLoggingTaggedData(mContext)).asList().containsExactly(
+ Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1));
+ }
}
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionLogHelperTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionLogHelperTest.java
deleted file mode 100644
index 01d253f7fb3..00000000000
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionLogHelperTest.java
+++ /dev/null
@@ -1,47 +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.dashboard.suggestions;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.util.Pair;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.TestConfig;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.annotation.Config;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class SuggestionLogHelperTest {
-
- @Test
- public void testGetSmartSuggestionEnabledTaggedData_disabled() {
- assertThat(SuggestionLogHelper.getSuggestionTaggedData(false)).asList().containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
- }
-
- @Test
- public void testGetSmartSuggestionEnabledTaggedData_enabled() {
- assertThat(SuggestionLogHelper.getSuggestionTaggedData(true)).asList().containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1));
- }
-}
-
diff --git a/tests/robotests/src/com/android/settings/development/SelectUsbConfigPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/SelectUsbConfigPreferenceControllerTest.java
new file mode 100644
index 00000000000..8b96af0f7e9
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/SelectUsbConfigPreferenceControllerTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.development;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.hardware.usb.UsbManager;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SelectUsbConfigPreferenceControllerTest {
+
+ @Mock
+ private ListPreference mPreference;
+ @Mock
+ private PreferenceScreen mScreen;
+ @Mock
+ private UsbManager mUsbManager;
+
+ private Context mContext;
+ private Lifecycle mLifecycle;
+ private SelectUsbConfigPreferenceController mController;
+
+ /**
+ * Array Values Key
+ *
+ * 0: Charging
+ * 1: MTP
+ * 2: PTP
+ * 3: RNDIS
+ * 4: Audio Source
+ * 5: MIDI
+ */
+ private String[] mValues;
+ private String[] mSummaries;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mLifecycle = new Lifecycle();
+ mContext = spy(RuntimeEnvironment.application);
+ doReturn(mUsbManager).when(mContext).getSystemService(Context.USB_SERVICE);
+ mValues = mContext.getResources().getStringArray(R.array.usb_configuration_values);
+ mSummaries = mContext.getResources().getStringArray(R.array.usb_configuration_titles);
+ mController = spy(new SelectUsbConfigPreferenceController(mContext, mLifecycle));
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ mController.displayPreference(mScreen);
+
+ }
+
+ @Test
+ public void onPreferenceChange_setCharging_shouldEnableCharging() {
+ when(mUsbManager.isFunctionEnabled(mValues[0])).thenReturn(true);
+ doNothing().when(mController).setCurrentFunction(anyString(), anyBoolean());
+ mController.onPreferenceChange(mPreference, mValues[0]);
+
+ verify(mController).setCurrentFunction(mValues[0], false /* usb data unlock */);
+ }
+
+ @Test
+ public void onPreferenceChange_setMtp_shouldEnableMtp() {
+ when(mUsbManager.isFunctionEnabled(mValues[1])).thenReturn(true);
+ doNothing().when(mController).setCurrentFunction(anyString(), anyBoolean());
+ mController.onPreferenceChange(mPreference, mValues[1]);
+
+ verify(mController).setCurrentFunction(mValues[1], true /* usb data unlock */);
+ }
+
+ @Test
+ public void updateState_chargingEnabled_shouldSetPreferenceToCharging() {
+ when(mUsbManager.isFunctionEnabled(mValues[0])).thenReturn(true);
+
+ mController.updateState(mPreference);
+
+ verify(mPreference).setValue(mValues[0]);
+ verify(mPreference).setSummary(mSummaries[0]);
+ }
+
+ @Test
+ public void updateState_RndisEnabled_shouldEnableRndis() {
+ when(mUsbManager.isFunctionEnabled(mValues[3])).thenReturn(true);
+
+ mController.updateState(mPreference);
+
+ verify(mPreference).setValue(mValues[3]);
+ verify(mPreference).setSummary(mSummaries[3]);
+ }
+
+ @Test
+ public void updateState_noValueSet_shouldEnableChargingAsDefault() {
+ mController.updateState(mPreference);
+
+ verify(mPreference).setValue(mValues[0]);
+ verify(mPreference).setSummary(mSummaries[0]);
+ }
+
+ @Test
+ public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() {
+ mController.onDeveloperOptionsSwitchDisabled();
+
+ verify(mPreference).setEnabled(false);
+ }
+
+ @Test
+ public void onDeveloperOptionsSwitchEnabled_shouldEnablePreference() {
+ mController.onDeveloperOptionsSwitchEnabled();
+
+ verify(mPreference).setEnabled(true);
+ }
+
+ @Test
+ public void onCreate_shouldRegisterReceiver() {
+ mLifecycle.onCreate(null /* bundle */);
+
+ verify(mContext).registerReceiver(any(), any());
+ }
+
+ @Test
+ public void onDestroy_shouldUnregisterReceiver() {
+ doNothing().when(mContext).unregisterReceiver(any());
+ mLifecycle.onDestroy();
+
+ verify(mContext).unregisterReceiver(any());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java
index 9bbc9bd7be6..46db6b37f92 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java
@@ -41,11 +41,13 @@ import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AnomalyDetectionPolicyTest {
- private static final String ANOMALY_DETECTION_CONSTANTS_VALUE = "anomaly_detection_enabled=true"
+ private static final String ANOMALY_DETECTION_CONSTANTS_VALUE =
+ "anomaly_detection_enabled=true"
+ ",wakelock_enabled=false"
+ ",wakelock_threshold=3000"
+ ",wakeup_alarm_enabled=true"
+ ",wakeup_alarm_threshold=100"
+ + ",wakeup_blacklisted_tags=tag1:tag2:with%2Ccomma:with%3Acolon"
+ ",bluetooth_scan_enabled=true"
+ ",bluetooth_scan_threshold=2000";
private Context mContext;
@@ -59,7 +61,7 @@ public class AnomalyDetectionPolicyTest {
}
@Test
- public void testInit_containsDataFromSettings() {
+ public void testInit_usesConfigValues() {
AnomalyDetectionPolicy anomalyDetectionPolicy = createAnomalyPolicyWithConfig();
assertThat(anomalyDetectionPolicy.anomalyDetectionEnabled).isTrue();
@@ -67,12 +69,14 @@ public class AnomalyDetectionPolicyTest {
assertThat(anomalyDetectionPolicy.wakeLockThreshold).isEqualTo(3000);
assertThat(anomalyDetectionPolicy.wakeupAlarmDetectionEnabled).isTrue();
assertThat(anomalyDetectionPolicy.wakeupAlarmThreshold).isEqualTo(100);
+ assertThat(anomalyDetectionPolicy.wakeupBlacklistedTags)
+ .containsExactly("tag1", "tag2", "with,comma", "with:colon");
assertThat(anomalyDetectionPolicy.bluetoothScanDetectionEnabled).isTrue();
assertThat(anomalyDetectionPolicy.bluetoothScanThreshold).isEqualTo(2000);
}
@Test
- public void testInit_containsDefaultData() {
+ public void testInit_defaultValues() {
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.ANOMALY_DETECTION_CONSTANTS, "");
// Mock it to avoid noSuchMethodError
@@ -82,18 +86,19 @@ public class AnomalyDetectionPolicyTest {
AnomalyDetectionPolicy anomalyDetectionPolicy = new AnomalyDetectionPolicy(mContext,
mKeyValueListParserWrapper);
- assertThat(anomalyDetectionPolicy.anomalyDetectionEnabled).isTrue();
- assertThat(anomalyDetectionPolicy.wakeLockDetectionEnabled).isTrue();
+ assertThat(anomalyDetectionPolicy.anomalyDetectionEnabled).isFalse();
+ assertThat(anomalyDetectionPolicy.wakeLockDetectionEnabled).isFalse();
assertThat(anomalyDetectionPolicy.wakeLockThreshold).isEqualTo(DateUtils.HOUR_IN_MILLIS);
assertThat(anomalyDetectionPolicy.wakeupAlarmDetectionEnabled).isFalse();
- assertThat(anomalyDetectionPolicy.wakeupAlarmThreshold).isEqualTo(60);
- assertThat(anomalyDetectionPolicy.bluetoothScanDetectionEnabled).isTrue();
+ assertThat(anomalyDetectionPolicy.wakeupAlarmThreshold).isEqualTo(10);
+ assertThat(anomalyDetectionPolicy.wakeupBlacklistedTags).isNull();
+ assertThat(anomalyDetectionPolicy.bluetoothScanDetectionEnabled).isFalse();
assertThat(anomalyDetectionPolicy.bluetoothScanThreshold).isEqualTo(
30 * DateUtils.MINUTE_IN_MILLIS);
}
@Test
- public void testIsAnomalyDetectorEnabled() {
+ public void testIsAnomalyDetectorEnabled_usesConfigValues() {
AnomalyDetectionPolicy anomalyDetectionPolicy = createAnomalyPolicyWithConfig();
assertThat(anomalyDetectionPolicy.isAnomalyDetectorEnabled(
@@ -104,18 +109,37 @@ public class AnomalyDetectionPolicyTest {
Anomaly.AnomalyType.BLUETOOTH_SCAN)).isTrue();
}
+ @Test
+ public void testIsAnomalyDetectorEnabled_usesDefaultValues() {
+ Settings.Global.putString(mContext.getContentResolver(),
+ Settings.Global.ANOMALY_DETECTION_CONSTANTS, "");
+ // Mock it to avoid noSuchMethodError
+ doReturn(true).when(mKeyValueListParserWrapper).getBoolean(anyString(), eq(true));
+ doReturn(false).when(mKeyValueListParserWrapper).getBoolean(anyString(), eq(false));
+
+ AnomalyDetectionPolicy anomalyDetectionPolicy = new AnomalyDetectionPolicy(mContext,
+ mKeyValueListParserWrapper);
+
+ assertThat(anomalyDetectionPolicy.isAnomalyDetectorEnabled(
+ Anomaly.AnomalyType.WAKE_LOCK)).isFalse();
+ assertThat(anomalyDetectionPolicy.isAnomalyDetectorEnabled(
+ Anomaly.AnomalyType.WAKEUP_ALARM)).isFalse();
+ assertThat(anomalyDetectionPolicy.isAnomalyDetectorEnabled(
+ Anomaly.AnomalyType.BLUETOOTH_SCAN)).isFalse();
+ }
+
private AnomalyDetectionPolicy createAnomalyPolicyWithConfig() {
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.ANOMALY_DETECTION_CONSTANTS, ANOMALY_DETECTION_CONSTANTS_VALUE);
// Mock it to avoid noSuchMethodError
doReturn(true).when(mKeyValueListParserWrapper).getBoolean(
- AnomalyDetectionPolicy.KEY_ANOMALY_DETECTION_ENABLED, true);
+ AnomalyDetectionPolicy.KEY_ANOMALY_DETECTION_ENABLED, false);
doReturn(false).when(mKeyValueListParserWrapper).getBoolean(
- AnomalyDetectionPolicy.KEY_WAKELOCK_DETECTION_ENABLED, true);
+ AnomalyDetectionPolicy.KEY_WAKELOCK_DETECTION_ENABLED, false);
doReturn(true).when(mKeyValueListParserWrapper).getBoolean(
AnomalyDetectionPolicy.KEY_WAKEUP_ALARM_DETECTION_ENABLED, false);
doReturn(true).when(mKeyValueListParserWrapper).getBoolean(
- AnomalyDetectionPolicy.KEY_BLUETOOTH_SCAN_DETECTION_ENABLED, true);
+ AnomalyDetectionPolicy.KEY_BLUETOOTH_SCAN_DETECTION_ENABLED, false);
return new AnomalyDetectionPolicy(mContext, mKeyValueListParserWrapper);
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetectorTest.java
index 55be734e232..13a5ab8531f 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetectorTest.java
@@ -30,6 +30,7 @@ import android.os.BatteryStats;
import android.os.Build;
import android.text.format.DateUtils;
import android.util.ArrayMap;
+import android.util.ArraySet;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
@@ -52,6 +53,7 @@ import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -69,6 +71,7 @@ public class WakeupAlarmAnomalyDetectorTest {
1 * DateUtils.HOUR_IN_MILLIS + 10 * DateUtils.MINUTE_IN_MILLIS;
private static final int ANOMALY_WAKEUP_COUNT = 500;
private static final int NORMAL_WAKEUP_COUNT = 61;
+ private static final int BLACKLISTED_WAKEUP_COUNT = 37;
private static final int ANOMALY_WAKEUP_FREQUENCY = 428; // count per hour
@Mock
private BatteryStatsHelper mBatteryStatsHelper;
@@ -87,12 +90,12 @@ public class WakeupAlarmAnomalyDetectorTest {
@Mock
private BatteryUtils mBatteryUtils;
@Mock
- private ApplicationInfo mApplicationInfo;
- @Mock
private BatteryStats.Uid.Pkg mPkg;
@Mock
private BatteryStats.Counter mCounter;
@Mock
+ private BatteryStats.Counter mCounter2;
+ @Mock
private AnomalyDetectionPolicy mPolicy;
@Mock
private AnomalyAction mAnomalyAction;
@@ -111,6 +114,9 @@ public class WakeupAlarmAnomalyDetectorTest {
mContext = spy(RuntimeEnvironment.application);
ReflectionHelpers.setField(mPolicy, "wakeupAlarmThreshold", 60);
+ final Set blacklistedTags = new ArraySet<>();
+ blacklistedTags.add("blacklistedTag");
+ ReflectionHelpers.setField(mPolicy, "wakeupBlacklistedTags", blacklistedTags);
doReturn(false).when(mBatteryUtils).shouldHideSipper(any());
doReturn(RUNNING_TIME_MS).when(mBatteryUtils).calculateRunningTimeBasedOnStatsType(any(),
@@ -207,4 +213,20 @@ public class WakeupAlarmAnomalyDetectorTest {
assertThat(mWakeupAlarmAnomalyDetector.getWakeupAlarmCountFromUid(mAnomalyUid)).isEqualTo(
2 * NORMAL_WAKEUP_COUNT);
}
+
+ @Test
+ public void testGetWakeupAlarmCountFromUid_filterOutBlacklistedTags() {
+ final ArrayMap packageStats = new ArrayMap<>();
+ final ArrayMap alarms = new ArrayMap<>();
+ doReturn(alarms).when(mPkg).getWakeupAlarmStats();
+ doReturn(NORMAL_WAKEUP_COUNT).when(mCounter).getCountLocked(anyInt());
+ doReturn(BLACKLISTED_WAKEUP_COUNT).when(mCounter2).getCountLocked(anyInt());
+ doReturn(packageStats).when(mAnomalyUid).getPackageStats();
+ packageStats.put("", mPkg);
+ alarms.put("allowedTag", mCounter);
+ alarms.put("blacklistedTag", mCounter2);
+
+ assertThat(mWakeupAlarmAnomalyDetector.getWakeupAlarmCountFromUid(mAnomalyUid)).isEqualTo(
+ NORMAL_WAKEUP_COUNT);
+ }
}