Merge "Change the string"
diff --git a/res/drawable/ic_signal_flashlight.xml b/res/drawable/ic_signal_flashlight.xml
new file mode 100644
index 0000000..e635953
--- /dev/null
+++ b/res/drawable/ic_signal_flashlight.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M18,2H6v6l2,3v11h8V11l2,-3L18,2zM16,4l0,1H8V4H16zM14,10.4V20h-4v-9.61l-2,-3V7h8l0,0.39L14,10.4z"/>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M12,14m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
+</vector>
diff --git a/res/layout/color_mode_preview.xml b/res/layout/color_mode_preview.xml
index 2838345..88b8281 100644
--- a/res/layout/color_mode_preview.xml
+++ b/res/layout/color_mode_preview.xml
@@ -21,7 +21,6 @@
<ImageView
android:layout_width="match_parent"
android:layout_height="@dimen/color_mode_preview_height"
- android:paddingBottom="@dimen/color_mode_preview_padding_bottom"
android:scaleType="centerCrop"
android:cropToPadding="true"
android:src="@drawable/color_mode_preview"
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 37462f9..cbfc428 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -268,17 +268,27 @@
<!-- Wi-Fi AP band settings. Either Auto, 2.4GHz or 5GHz. -->
<!-- Note that adding/removing/moving the items will need wifi settings code change. -->
- <string-array name="wifi_ap_band_config_full">
+ <string-array translatable="false" name="wifi_ap_band_config_full">
+ <item>0</item>
+ <item>1</item>
+ </string-array>
+
+ <string-array translatable="false" name="wifi_ap_band_summary_full">
<item>@string/wifi_ap_choose_2G</item>
<item>@string/wifi_ap_choose_5G</item>
</string-array>
- <string-array name="wifi_ap_band_summary_full">
- <item>@string/wifi_ap_2G</item>
- <item>@string/wifi_ap_5G</item>
+ <string-array translatable="false" name="wifi_ap_band_dual_mode">
+ <item>0</item>
+ <item>-1</item>
</string-array>
- <string-array name="wifi_ap_band_config_2G_only">
+ <string-array translatable="false" name="wifi_ap_band_dual_mode_summary">
+ <item>@string/wifi_ap_choose_2G</item>
+ <item>@string/wifi_ap_prefer_5G</item>
+ </string-array>
+
+ <string-array translatable="false" name="wifi_ap_band_config_2G_only">
<item>@string/wifi_ap_choose_auto</item>
<item>@string/wifi_ap_choose_2G</item>
</string-array>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index e0b8c48..08160ba 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -62,7 +62,6 @@
<dimen name="captioning_preview_height">200dp</dimen>
<dimen name="color_mode_preview_height">320dp</dimen>
- <dimen name="color_mode_preview_padding_bottom">40dp</dimen>
<dimen name="ring_progress_bar_thickness">4dp</dimen>
<dimen name="settings_side_margin">0dip</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7bfb7af..eba90fd 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1995,8 +1995,10 @@
<string name="wifi_ap_choose_auto">Auto</string>
<!-- Label for the radio button to choose wifi ap 2.4 GHz band -->
<string name="wifi_ap_choose_2G">2.4 GHz Band</string>
- <!-- Label for the radio button to choose wifi ap 5GHz band -->
+ <!-- Label for the radio button to only choose wifi ap 5GHz band -->
<string name="wifi_ap_choose_5G">5.0 GHz Band</string>
+ <!-- Label for the radio button to prefer 5GHz wifi ap band [CHAR LIMIT=80]-->
+ <string name="wifi_ap_prefer_5G">5.0 GHz Band preferred</string>
<!-- Label for adding to the list of selected bands when 2.4 GHz is selected -->
<string name="wifi_ap_2G">2.4 GHz</string>
<!-- Label for adding to the list of selected bands when 5.0 GHz is selected -->
@@ -7410,7 +7412,7 @@
<!-- Do not disturb settings, messages, events and reminders title [CHAR LIMIT=100]-->
<string name="zen_msg_event_reminder_title">Messages, events & reminders</string>
<!-- Do not disturb settings, messages, events and reminders footer [CHAR LIMIT=NONE]-->
- <string name="zen_msg_event_reminder_footer">When Do Not Disturb is on, messages, reminders, and events will muted, except for the items you allow above. You can adjust messages settings to allow your friends, family, or other contacts to reach you.</string>
+ <string name="zen_msg_event_reminder_footer">When Do Not Disturb is on, messages, reminders, and events will be muted, except for the items you allow above. You can adjust messages settings to allow your friends, family, or other contacts to reach you.</string>
<!-- Do not disturb onboarding dialog, accept new settings [CHAR LIMIT=30]-->
<string name="zen_onboarding_ok">Done</string>
@@ -7975,9 +7977,15 @@
<!-- [CHAR LIMIT=50] Zen mode settings: All messages summary -->
<string name="zen_mode_all_messages">Messages</string>
+ <!-- [CHAR LIMIT=50] Zen mode settings: Messages option (ie: text messages) -->
+ <string name="zen_mode_all_messages_list">messages</string>
+
<!-- [CHAR LIMIT=50] Zen mode settings: Selected messages summary -->
<string name="zen_mode_selected_messages">Some messages</string>
+ <!-- [CHAR LIMIT=50] Zen mode settings: Selected messages (ie: some text messages are allowed to bypass dnd) -->
+ <string name="zen_mode_selected_messages_list">some messages</string>
+
<!-- [CHAR LIMIT=40] Zen mode settings: Calls or messages option value: From anyone -->
<string name="zen_mode_from_anyone">From anyone</string>
@@ -8002,21 +8010,36 @@
<!-- [CHAR LIMIT=50] Zen mode settings: Alarms option -->
<string name="zen_mode_alarms">Alarms</string>
+ <!-- [CHAR LIMIT=50] Zen mode settings: Alarms option (ie: sound from alarm clock) -->
+ <string name="zen_mode_alarms_list">alarms</string>
+
<!-- [CHAR LIMIT=50] Zen mode settings: Media option -->
<string name="zen_mode_media">Media</string>
+ <!-- [CHAR LIMIT=50] Zen mode settings: Media (ie: sound from video) -->
+ <string name="zen_mode_media_list">media</string>
+
<!-- [CHAR LIMIT=50] Zen mode settings: System option which includes sounds such as touch sounds -->
<string name="zen_mode_system">Touch sounds</string>
+ <!-- [CHAR LIMIT=50] Zen mode settings: System sounds (ie: touch sounds) -->
+ <string name="zen_mode_system_list">touch sounds</string>
+
<!-- [CHAR LIMIT=50] Zen mode settings: Reminders option -->
<string name="zen_mode_reminders">Reminders</string>
+ <!-- [CHAR LIMIT=50] Zen mode settings: Reminders (ie: calendar reminders are allowed to bypass dnd) -->
+ <string name="zen_mode_reminders_list">reminders</string>
+
<!-- [CHAR LIMIT=70] Zen mode settings: Allow reminders toggle title -->
<string name="zen_mode_reminders_title">Allow reminders</string>
<!-- [CHAR LIMIT=50] Zen mode settings: Events option -->
<string name="zen_mode_events">Events</string>
+ <!-- [CHAR LIMIT=50] Zen mode settings: Events (ie: calendar events) -->
+ <string name="zen_mode_events_list">events</string>
+
<!-- [CHAR LIMIT=70] Zen mode settings: Allow events toggle title -->
<string name="zen_mode_events_title">Allow events</string>
@@ -8032,6 +8055,9 @@
<!-- [CHAR LIMIT=50] Zen mode settings: Repeat callers option -->
<string name="zen_mode_repeat_callers">Repeat callers</string>
+ <!-- [CHAR LIMIT=50] Zen mode settings: Repeat callers (ie: repeat callers are allowed to bypass dnd) -->
+ <string name="zen_mode_repeat_callers_list">repeat callers</string>
+
<!-- [CHAR LIMIT=70] Zen mode settings: Allow repeat callers toggle title -->
<string name="zen_mode_repeat_callers_title">Allow repeat callers</string>
@@ -9918,6 +9944,9 @@
<!-- Help URI, smart battery page [DO NOT TRANSLATE] -->
<string name="help_uri_smart_battery_settings" translatable="false"></string>
+ <!-- Help URI, prevent ringing gesture [DO NOT TRANSLATE] -->
+ <string name="help_uri_prevent_ringing_gesture" translatable="false"></string>
+
<!-- Title label for dnd suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] -->
<string name="zen_suggestion_title">Update Do Not Disturb</string>
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index ec8a197..683abd3 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -75,6 +75,7 @@
android:key="color_mode"
android:title="@string/color_mode_title"
android:fragment="com.android.settings.display.ColorModePreferenceFragment"
+ settings:controller="com.android.settings.display.ColorModePreferenceController"
settings:keywords="@string/keywords_color_mode" />
<Preference
diff --git a/res/xml/wifi_tether_settings.xml b/res/xml/wifi_tether_settings.xml
index e869483..3e8f93f 100644
--- a/res/xml/wifi_tether_settings.xml
+++ b/res/xml/wifi_tether_settings.xml
@@ -44,11 +44,7 @@
android:title="@string/wifi_hotspot_auto_off_title"
android:summary="@string/wifi_hotspot_auto_off_summary" />
- <com.android.settings.widget.HotspotApBandSelectionPreference
+ <ListPreference
android:key="wifi_tether_network_ap_band"
- android:title="@string/wifi_hotspot_ap_band_title"
- android:dialogLayout="@layout/hotspot_ap_band_selection_dialog"
- android:dialogTitle="@string/wifi_hotspot_ap_band_title"
- android:negativeButtonText="@string/cancel"
- android:positiveButtonText="@string/apply" />
+ android:title="@string/wifi_hotspot_ap_band_title" />
</PreferenceScreen>
diff --git a/src/com/android/settings/DisplaySettings.java b/src/com/android/settings/DisplaySettings.java
index 32d68ba..afdf9d0 100644
--- a/src/com/android/settings/DisplaySettings.java
+++ b/src/com/android/settings/DisplaySettings.java
@@ -23,7 +23,6 @@
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.display.BrightnessLevelPreferenceController;
import com.android.settings.display.CameraGesturePreferenceController;
-import com.android.settings.display.ColorModePreferenceController;
import com.android.settings.display.LiftToWakePreferenceController;
import com.android.settings.display.NightDisplayPreferenceController;
import com.android.settings.display.NightModePreferenceController;
@@ -94,7 +93,6 @@
controllers.add(new WallpaperPreferenceController(context));
controllers.add(new ThemePreferenceController(context));
controllers.add(new BrightnessLevelPreferenceController(context, lifecycle));
- controllers.add(new ColorModePreferenceController(context));
return controllers;
}
diff --git a/src/com/android/settings/FallbackHome.java b/src/com/android/settings/FallbackHome.java
index 5f7b639..84a3283 100644
--- a/src/com/android/settings/FallbackHome.java
+++ b/src/com/android/settings/FallbackHome.java
@@ -18,6 +18,8 @@
import android.app.Activity;
import android.app.ProgressDialog;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -68,15 +70,27 @@
// we don't flash the wallpaper before SUW
mProvisioned = Settings.Global.getInt(getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+ int flags;
if (!mProvisioned) {
setTheme(R.style.FallbackHome_SetupWizard);
- getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
- | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+ flags = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
} else {
- getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
+ flags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
}
+ // Set the system ui flags to light status bar if the wallpaper supports dark text to match
+ // current system ui color tints.
+ final WallpaperColors colors = getSystemService(WallpaperManager.class)
+ .getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+ if (colors != null
+ && (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0) {
+ flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
+ | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+ }
+ getWindow().getDecorView().setSystemUiVisibility(flags);
+
registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
maybeFinish();
}
diff --git a/src/com/android/settings/RadioInfo.java b/src/com/android/settings/RadioInfo.java
index c04269c..557c39b 100644
--- a/src/com/android/settings/RadioInfo.java
+++ b/src/com/android/settings/RadioInfo.java
@@ -17,6 +17,7 @@
package com.android.settings;
import static android.net.ConnectivityManager.NetworkCallback;
+import static android.provider.Settings.Global.PREFERRED_NETWORK_MODE;
import android.app.Activity;
import android.app.AlertDialog;
@@ -39,6 +40,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
@@ -1451,6 +1453,19 @@
if (mPreferredNetworkTypeResult != pos && pos >= 0
&& pos <= mPreferredNetworkLabels.length - 2) {
mPreferredNetworkTypeResult = pos;
+
+ // TODO: Possibly migrate this to TelephonyManager.setPreferredNetworkType()
+ // which today still has some issues (mostly that the "set" is conditional
+ // on a successful modem call, which is not what we want). Instead we always
+ // want this setting to be set, so that if the radio hiccups and this setting
+ // is for some reason unsuccessful, future calls to the radio will reflect
+ // the users's preference which is set here.
+ final int subId = phone.getSubId();
+ if (SubscriptionManager.isUsableSubIdValue(subId)) {
+ Settings.Global.putInt(phone.getContext().getContentResolver(),
+ PREFERRED_NETWORK_MODE + subId, mPreferredNetworkTypeResult);
+ }
+ log("Calling setPreferredNetworkType(" + mPreferredNetworkTypeResult + ")");
Message msg = mHandler.obtainMessage(EVENT_SET_PREFERRED_TYPE_DONE);
phone.setPreferredNetworkType(mPreferredNetworkTypeResult, msg);
}
diff --git a/src/com/android/settings/accounts/AccountSyncSettings.java b/src/com/android/settings/accounts/AccountSyncSettings.java
index 66f9179..66e8d22 100644
--- a/src/com/android/settings/accounts/AccountSyncSettings.java
+++ b/src/com/android/settings/accounts/AccountSyncSettings.java
@@ -247,10 +247,13 @@
}
if (preference instanceof SyncStateSwitchPreference) {
SyncStateSwitchPreference syncPref = (SyncStateSwitchPreference) preference;
- String authority = syncPref.getAuthority();
- Account account = syncPref.getAccount();
+ final String authority = syncPref.getAuthority();
+ if (TextUtils.isEmpty(authority)) {
+ return false;
+ }
+ final Account account = syncPref.getAccount();
final int userId = mUserHandle.getIdentifier();
- String packageName = syncPref.getPackageName();
+ final String packageName = syncPref.getPackageName();
boolean syncAutomatically = ContentResolver.getSyncAutomaticallyAsUser(account,
authority, userId);
diff --git a/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java b/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java
index bb60df9..27b7676 100644
--- a/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java
@@ -21,11 +21,13 @@
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
+
import com.android.settings.bluetooth.BluetoothDeviceUpdater;
import com.android.settings.bluetooth.SavedBluetoothDeviceUpdater;
+import com.android.settings.connecteddevice.dock.DockUpdater;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.dashboard.DashboardFragment;
-
+import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -35,10 +37,14 @@
private Preference mPreference;
private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
+ private DockUpdater mSavedDockUpdater;
private int mPreferenceSize;
public PreviouslyConnectedDevicePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
+
+ mSavedDockUpdater = FeatureFactory.getFactory(
+ context).getDockUpdaterFeatureProvider().getSavedDockUpdater(context, this);
}
@Override
@@ -60,12 +66,14 @@
@Override
public void onStart() {
mBluetoothDeviceUpdater.registerCallback();
+ mSavedDockUpdater.registerCallback();
updatePreferenceOnSizeChanged();
}
@Override
public void onStop() {
mBluetoothDeviceUpdater.unregisterCallback();
+ mSavedDockUpdater.unregisterCallback();
}
public void init(DashboardFragment fragment) {
@@ -91,6 +99,11 @@
}
@VisibleForTesting
+ void setSavedDockUpdater(DockUpdater savedDockUpdater) {
+ mSavedDockUpdater = savedDockUpdater;
+ }
+
+ @VisibleForTesting
void setPreferenceSize(int size) {
mPreferenceSize = size;
}
@@ -105,4 +118,4 @@
mPreference.setEnabled(mPreferenceSize != 0);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/datausage/DataUsageSummaryLegacy.java b/src/com/android/settings/datausage/DataUsageSummaryLegacy.java
index 5c19afb..f54d6ef 100644
--- a/src/com/android/settings/datausage/DataUsageSummaryLegacy.java
+++ b/src/com/android/settings/datausage/DataUsageSummaryLegacy.java
@@ -22,10 +22,6 @@
import android.net.NetworkTemplate;
import android.os.Bundle;
import android.os.UserManager;
-import android.provider.SearchIndexableResource;
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.text.BidiFormatter;
@@ -43,20 +39,20 @@
import com.android.settings.SummaryPreference;
import com.android.settings.Utils;
import com.android.settings.dashboard.SummaryLoader;
-import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settingslib.NetworkPolicyEditor;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.net.DataUsageController;
-import com.android.settingslib.search.SearchIndexable;
-import java.util.ArrayList;
import java.util.List;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
/**
* Legacy {@link DataUsageSummary} fragment.
*/
-@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class DataUsageSummaryLegacy extends DataUsageBaseFragment implements Indexable,
DataUsageEditController {
@@ -143,7 +139,7 @@
}
mDataUsageTemplate = hasMobileData ? R.string.cell_data_template
: hasWifiRadio ? R.string.wifi_data_template
- : R.string.ethernet_data_template;
+ : R.string.ethernet_data_template;
setHasOptionsMenu(true);
}
@@ -204,7 +200,7 @@
category.setTemplate(getNetworkTemplate(subId), subId, services);
category.pushTemplates(services);
if (subInfo != null && !TextUtils.isEmpty(subInfo.getDisplayName())) {
- Preference title = category.findPreference(KEY_MOBILE_USAGE_TITLE);
+ Preference title = category.findPreference(KEY_MOBILE_USAGE_TITLE);
title.setTitle(subInfo.getDisplayName());
}
}
@@ -260,7 +256,7 @@
final SpannableString amountTemplate = new SpannableString(
context.getString(com.android.internal.R.string.fileSizeSuffix)
- .replace("%1$s", "^1").replace("%2$s", "^2"));
+ .replace("%1$s", "^1").replace("%2$s", "^2"));
final CharSequence formattedUsage = TextUtils.expandTemplate(amountTemplate,
enlargedValue, usedResult.units);
@@ -359,52 +355,5 @@
}
public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
- = SummaryProvider::new;
-
- /**
- * For search
- */
- public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider() {
-
- @Override
- public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
- boolean enabled) {
- List<SearchIndexableResource> resources = new ArrayList<>();
- SearchIndexableResource resource = new SearchIndexableResource(context);
- resource.xmlResId = R.xml.data_usage_legacy;
- resources.add(resource);
-
- resource = new SearchIndexableResource(context);
- resource.xmlResId = R.xml.data_usage_cellular;
- resources.add(resource);
-
- resource = new SearchIndexableResource(context);
- resource.xmlResId = R.xml.data_usage_wifi;
- resources.add(resource);
-
- return resources;
- }
-
- @Override
- public List<String> getNonIndexableKeys(Context context) {
- List<String> keys = super.getNonIndexableKeys(context);
-
- if (!DataUsageUtils.hasMobileData(context)) {
- keys.add(KEY_MOBILE_USAGE_TITLE);
- keys.add(KEY_MOBILE_DATA_USAGE_TOGGLE);
- keys.add(KEY_MOBILE_DATA_USAGE);
- keys.add(KEY_MOBILE_BILLING_CYCLE);
- }
-
- if (!DataUsageUtils.hasWifiRadio(context)) {
- keys.add(KEY_WIFI_DATA_USAGE);
- }
-
- // This title is named Wifi, and will confuse users.
- keys.add(KEY_WIFI_USAGE_TITLE);
-
- return keys;
- }
- };
+ = SummaryProvider::new;
}
diff --git a/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogController.java b/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogController.java
index 71da4a3..4157886 100644
--- a/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogController.java
+++ b/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogController.java
@@ -53,6 +53,9 @@
static final int ID_GSM_SETTINGS = R.id.gsm_settings;
private static CharSequence getTextAsDigits(CharSequence text) {
+ if (TextUtils.isEmpty(text)) {
+ return "";
+ }
if (TextUtils.isDigitsOnly(text)) {
final Spannable spannable = new SpannableStringBuilder(text);
final TtsSpan span = new TtsSpan.DigitsBuilder(text.toString()).build();
diff --git a/src/com/android/settings/display/ColorModePreferenceController.java b/src/com/android/settings/display/ColorModePreferenceController.java
index ebb4370..6a86cd9 100644
--- a/src/com/android/settings/display/ColorModePreferenceController.java
+++ b/src/com/android/settings/display/ColorModePreferenceController.java
@@ -27,15 +27,14 @@
public class ColorModePreferenceController extends BasePreferenceController {
private static final String TAG = "ColorModePreference";
- private static final String KEY_COLOR_MODE = "color_mode";
private static final int SURFACE_FLINGER_TRANSACTION_QUERY_WIDE_COLOR = 1024;
private final ConfigurationWrapper mConfigWrapper;
private ColorDisplayController mColorDisplayController;
- public ColorModePreferenceController(Context context) {
- super(context, KEY_COLOR_MODE);
+ public ColorModePreferenceController(Context context, String key) {
+ super(context, key);
mConfigWrapper = new ConfigurationWrapper();
}
@@ -43,7 +42,7 @@
public int getAvailabilityStatus() {
return mConfigWrapper.isScreenWideColorGamut()
&& !getColorDisplayController().getAccessibilityTransformActivated() ?
- AVAILABLE : DISABLED_FOR_USER;
+ AVAILABLE_UNSEARCHABLE : DISABLED_FOR_USER;
}
@Override
diff --git a/src/com/android/settings/display/ColorModePreferenceFragment.java b/src/com/android/settings/display/ColorModePreferenceFragment.java
index ab17c72..874dc71 100644
--- a/src/com/android/settings/display/ColorModePreferenceFragment.java
+++ b/src/com/android/settings/display/ColorModePreferenceFragment.java
@@ -15,6 +15,8 @@
import android.content.Context;
import android.graphics.drawable.Drawable;
+import android.provider.SearchIndexableResource;
+
import androidx.annotation.VisibleForTesting;
import androidx.preference.PreferenceScreen;
@@ -23,13 +25,18 @@
import com.android.settings.applications.LayoutPreference;
import com.android.settings.R;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
import com.android.settings.widget.RadioButtonPickerFragment;
+import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.widget.CandidateInfo;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
@SuppressWarnings("WeakerAccess")
+@SearchIndexable
public class ColorModePreferenceFragment extends RadioButtonPickerFragment
implements ColorDisplayController.Callback {
@@ -181,4 +188,15 @@
getActivity().onBackPressed();
}
}
+
+ public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ @Override
+ public List<SearchIndexableResource> getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.color_mode_settings;
+ return Arrays.asList(sir);
+ }
+ };
}
diff --git a/src/com/android/settings/fingerprint/FingerprintSettings.java b/src/com/android/settings/fingerprint/FingerprintSettings.java
index 0fd3f8b..4aaf997 100644
--- a/src/com/android/settings/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/fingerprint/FingerprintSettings.java
@@ -785,6 +785,7 @@
if (mDeleteInProgress) {
mAlertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(false);
}
+ mDialogTextField.requestFocus();
}
});
if (mTextHadFocus == null || mTextHadFocus) {
diff --git a/src/com/android/settings/flashlight/FlashlightSliceBuilder.java b/src/com/android/settings/flashlight/FlashlightSliceBuilder.java
new file mode 100644
index 0000000..6317ce7
--- /dev/null
+++ b/src/com/android/settings/flashlight/FlashlightSliceBuilder.java
@@ -0,0 +1,156 @@
+/*
+ * 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.flashlight;
+
+import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
+import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
+
+import android.annotation.ColorInt;
+import android.app.PendingIntent;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
+import android.net.Uri;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.provider.SettingsSlicesContract;
+import android.util.Log;
+
+import androidx.core.graphics.drawable.IconCompat;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.slices.SettingsSliceProvider;
+import com.android.settings.slices.SliceBroadcastReceiver;
+
+import androidx.slice.Slice;
+import androidx.slice.builders.ListBuilder;
+import androidx.slice.builders.SliceAction;
+
+import android.app.StatusBarManager;
+
+
+/**
+ * Utility class to build a Flashlight Slice, and handle all associated actions.
+ */
+public class FlashlightSliceBuilder {
+
+ private static final String TAG = "FlashlightSliceBuilder";
+
+ public static final String KEY_FLASHLIGHT = "flashlight";
+
+ /**
+ * Backing Uri for the Flashlight Slice.
+ */
+ public static final Uri FLASHLIGHT_URI = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(KEY_FLASHLIGHT)
+ .build();
+
+ /**
+ * Action notifying a change on the Flashlight Slice.
+ */
+ public static final String ACTION_FLASHLIGHT_SLICE_CHANGED =
+ "com.android.settings.flashlight.action.FLASHLIGHT_SLICE_CHANGED";
+
+ /**
+ * Action broadcasting a change on whether flashlight is on or off.
+ */
+ public static final String ACTION_FLASHLIGHT_CHANGED =
+ "com.android.settings.flashlight.action.FLASHLIGHT_CHANGED";
+
+ public static final IntentFilter INTENT_FILTER = new IntentFilter(ACTION_FLASHLIGHT_CHANGED);
+
+ private FlashlightSliceBuilder() {}
+
+ /**
+ * Return a Flashlight Slice bound to {@link #FLASHLIGHT_URI}.
+ */
+ public static Slice getSlice(Context context) {
+ if (!isFlashlightAvailable(context)) {
+ return null;
+ }
+ final PendingIntent toggleAction = getBroadcastIntent(context);
+ @ColorInt final int color = Utils.getColorAccentDefaultColor(context);
+ final IconCompat icon =
+ IconCompat.createWithResource(context, R.drawable.ic_signal_flashlight);
+ return new ListBuilder(context, FLASHLIGHT_URI, ListBuilder.INFINITY)
+ .setAccentColor(color)
+ .addRow(b -> b
+ .setTitle(context.getText(R.string.power_flashlight))
+ .setTitleItem(icon, ICON_IMAGE)
+ .setPrimaryAction(
+ new SliceAction(toggleAction, null, isFlashlightEnabled(context))))
+ .build();
+ }
+
+ /**
+ * Update the current flashlight status to the boolean value keyed by
+ * {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}.
+ */
+ public static void handleUriChange(Context context, Intent intent) {
+ try {
+ final String cameraId = getCameraId(context);
+ if (cameraId != null) {
+ final boolean state = intent.getBooleanExtra(
+ EXTRA_TOGGLE_STATE, isFlashlightEnabled(context));
+ final CameraManager cameraManager = context.getSystemService(CameraManager.class);
+ cameraManager.setTorchMode(cameraId, state);
+ }
+ } catch (CameraAccessException e) {
+ Log.e(TAG, "Camera couldn't set torch mode.", e);
+ }
+ context.getContentResolver().notifyChange(FLASHLIGHT_URI, null);
+ }
+
+ private static String getCameraId(Context context) throws CameraAccessException {
+ final CameraManager cameraManager = context.getSystemService(CameraManager.class);
+ final String[] ids = cameraManager.getCameraIdList();
+ for (String id : ids) {
+ CameraCharacteristics c = cameraManager.getCameraCharacteristics(id);
+ Boolean flashAvailable = c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
+ Integer lensFacing = c.get(CameraCharacteristics.LENS_FACING);
+ if (flashAvailable != null && flashAvailable
+ && lensFacing != null && lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
+ return id;
+ }
+ }
+ return null;
+ }
+
+ private static PendingIntent getBroadcastIntent(Context context) {
+ final Intent intent = new Intent(ACTION_FLASHLIGHT_SLICE_CHANGED);
+ intent.setClass(context, SliceBroadcastReceiver.class);
+ return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
+ PendingIntent.FLAG_CANCEL_CURRENT);
+ }
+
+ private static boolean isFlashlightAvailable(Context context) {
+ return Settings.Secure.getInt(
+ context.getContentResolver(), Secure.FLASHLIGHT_AVAILABLE, 0) == 1;
+ }
+
+ private static boolean isFlashlightEnabled(Context context) {
+ return Settings.Secure.getInt(
+ context.getContentResolver(), Secure.FLASHLIGHT_ENABLED, 0) == 1;
+ }
+}
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
index 4a3e6d4..83b0e1b 100644
--- a/src/com/android/settings/fuelgauge/BatteryUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -24,18 +24,12 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.BatteryStats;
-import android.os.Bundle;
import android.os.Build;
+import android.os.Bundle;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
-import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import androidx.annotation.VisibleForTesting;
-import androidx.annotation.WorkerThread;
-import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.SparseLongArray;
@@ -48,7 +42,6 @@
import com.android.settings.fuelgauge.batterytip.AnomalyInfo;
import com.android.settings.fuelgauge.batterytip.StatsManagerConfig;
import com.android.settings.overlay.FeatureFactory;
-
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
import com.android.settingslib.utils.PowerUtil;
@@ -58,6 +51,12 @@
import java.util.Comparator;
import java.util.List;
+import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
+import androidx.annotation.VisibleForTesting;
+import androidx.annotation.WorkerThread;
+
/**
* Utils for battery operation
*/
@@ -93,14 +92,14 @@
public static BatteryUtils getInstance(Context context) {
if (sInstance == null || sInstance.isDataCorrupted()) {
- sInstance = new BatteryUtils(context);
+ sInstance = new BatteryUtils(context.getApplicationContext());
}
return sInstance;
}
@VisibleForTesting
BatteryUtils(Context context) {
- mContext = context.getApplicationContext();
+ mContext = context;
mPackageManager = context.getPackageManager();
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
mPowerUsageFeatureProvider = FeatureFactory.getFactory(
diff --git a/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java b/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java
index a0d4e9b..7d81c42 100644
--- a/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java
+++ b/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java
@@ -46,15 +46,181 @@
AnomalyType.EXCESSIVE_WAKEUPS_IN_BACKGROUND,
AnomalyType.EXCESSIVE_UNOPTIMIZED_BLE_SCAN,
AnomalyType.EXCESSIVE_BACKGROUND_SERVICE,
- AnomalyType.EXCESSIVE_WIFI_SCAN})
+ AnomalyType.EXCESSIVE_WIFI_SCAN,
+ AnomalyType.EXCESSIVE_FLASH_WRITES,
+ AnomalyType.EXCESSIVE_MEMORY_IN_BACKGROUND,
+ AnomalyType.EXCESSIVE_DAVEY_RATE,
+ AnomalyType.EXCESSIVE_JANKY_FRAMES,
+ AnomalyType.SLOW_COLD_START_TIME,
+ AnomalyType.SLOW_HOT_START_TIME,
+ AnomalyType.SLOW_WARM_START_TIME,
+ AnomalyType.EXCESSIVE_BACKGROUND_SYNCS,
+ AnomalyType.EXCESSIVE_GPS_SCANS_IN_BACKGROUND,
+ AnomalyType.EXCESSIVE_JOB_SCHEDULING,
+ AnomalyType.EXCESSIVE_MOBILE_NETWORK_IN_BACKGROUND,
+ AnomalyType.EXCESSIVE_WIFI_LOCK_TIME,
+ AnomalyType.JOB_TIMED_OUT,
+ AnomalyType.LONG_UNOPTIMIZED_BLE_SCAN,
+ AnomalyType.BACKGROUND_ANR,
+ AnomalyType.BACKGROUND_CRASH_RATE,
+ AnomalyType.EXCESSIVE_ANR_LOOPING,
+ AnomalyType.EXCESSIVE_ANRS,
+ AnomalyType.EXCESSIVE_CRASH_RATE,
+ AnomalyType.EXCESSIVE_CRASH_LOOPING,
+ AnomalyType.NUMBER_OF_OPEN_FILES,
+ })
public @interface AnomalyType {
+ /**
+ * This represents an error condition in the anomaly detection.
+ */
int NULL = -1;
+
+ /**
+ * The anomaly type does not match any other defined type.
+ */
int UNKNOWN_REASON = 0;
+
+ /**
+ * The application held a partial (screen off) wake lock for a period of time that
+ * exceeded the threshold with the screen off when not charging.
+ */
int EXCESSIVE_WAKELOCK_ALL_SCREEN_OFF = 1;
+
+ /**
+ * The application exceeded the maximum number of wakeups while in the background
+ * when not charging.
+ */
int EXCESSIVE_WAKEUPS_IN_BACKGROUND = 2;
+
+ /**
+ * The application did unoptimized Bluetooth scans too frequently when not charging.
+ */
int EXCESSIVE_UNOPTIMIZED_BLE_SCAN = 3;
+
+ /**
+ * The application ran in the background for a period of time that exceeded the
+ * threshold.
+ */
int EXCESSIVE_BACKGROUND_SERVICE = 4;
+
+ /**
+ * The application exceeded the maximum number of wifi scans when not charging.
+ */
int EXCESSIVE_WIFI_SCAN = 5;
+
+ /**
+ * The application exceed the maximum number of flash writes
+ */
+ int EXCESSIVE_FLASH_WRITES = 6;
+
+ /**
+ * The application used more than the maximum memory, while not spending any time
+ * in the foreground.
+ */
+ int EXCESSIVE_MEMORY_IN_BACKGROUND = 7;
+
+ /**
+ * The application exceeded the maximum percentage of frames with a render rate of
+ * greater than 700ms.
+ */
+ int EXCESSIVE_DAVEY_RATE = 8;
+
+ /**
+ * The application exceeded the maximum percentage of frames with a render rate
+ * greater than 16ms.
+ */
+ int EXCESSIVE_JANKY_FRAMES = 9;
+
+ /**
+ * The application exceeded the maximum cold start time - the app has not been
+ * launched since last system start, died or was killed.
+ */
+ int SLOW_COLD_START_TIME = 10;
+
+ /**
+ * The application exceeded the maximum hot start time - the app and activity are
+ * already in memory.
+ */
+ int SLOW_HOT_START_TIME = 11;
+
+ /**
+ * The application exceeded the maximum warm start time - the app was already in
+ * memory but the activity wasn’t created yet or was removed from memory.
+ */
+ int SLOW_WARM_START_TIME = 12;
+
+ /**
+ * The application exceeded the maximum number of syncs while in the background.
+ */
+ int EXCESSIVE_BACKGROUND_SYNCS = 13;
+
+ /**
+ * The application exceeded the maximum number of gps scans while in the background.
+ */
+ int EXCESSIVE_GPS_SCANS_IN_BACKGROUND = 14;
+
+ /**
+ * The application scheduled more than the maximum number of jobs while not charging.
+ */
+ int EXCESSIVE_JOB_SCHEDULING = 15;
+
+ /**
+ * The application exceeded the maximum amount of mobile network traffic while in
+ * the background.
+ */
+ int EXCESSIVE_MOBILE_NETWORK_IN_BACKGROUND = 16;
+
+ /**
+ * The application held the WiFi lock for more than the maximum amount of time while
+ * not charging.
+ */
+ int EXCESSIVE_WIFI_LOCK_TIME = 17;
+
+ /**
+ * The application scheduled a job that ran longer than the maximum amount of time.
+ */
+ int JOB_TIMED_OUT = 18;
+
+ /**
+ * The application did an unoptimized Bluetooth scan that exceeded the maximum
+ * time while in the background.
+ */
+ int LONG_UNOPTIMIZED_BLE_SCAN = 19;
+
+ /**
+ * The application exceeded the maximum ANR rate while in the background.
+ */
+ int BACKGROUND_ANR = 20;
+
+ /**
+ * The application exceeded the maximum crash rate while in the background.
+ */
+ int BACKGROUND_CRASH_RATE = 21;
+
+ /**
+ * The application exceeded the maximum ANR-looping rate.
+ */
+ int EXCESSIVE_ANR_LOOPING = 22;
+
+ /**
+ * The application exceeded the maximum ANR rate.
+ */
+ int EXCESSIVE_ANRS = 23;
+
+ /**
+ * The application exceeded the maximum crash rate.
+ */
+ int EXCESSIVE_CRASH_RATE = 24;
+
+ /**
+ * The application exceeded the maximum crash-looping rate.
+ */
+ int EXCESSIVE_CRASH_LOOPING = 25;
+
+ /**
+ * The application crashed because no more file descriptors were available.
+ */
+ int NUMBER_OF_OPEN_FILES = 26;
}
}
diff --git a/src/com/android/settings/gestures/PreventRingingGestureSettings.java b/src/com/android/settings/gestures/PreventRingingGestureSettings.java
index 58ff5fa..b8d157c 100644
--- a/src/com/android/settings/gestures/PreventRingingGestureSettings.java
+++ b/src/com/android/settings/gestures/PreventRingingGestureSettings.java
@@ -60,7 +60,7 @@
@Override
public int getHelpResource() {
- return 0;
+ return R.string.help_uri_prevent_ringing_gesture;
}
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
diff --git a/src/com/android/settings/location/LocationServicePreferenceController.java b/src/com/android/settings/location/LocationServicePreferenceController.java
index f865b44..9860abd 100644
--- a/src/com/android/settings/location/LocationServicePreferenceController.java
+++ b/src/com/android/settings/location/LocationServicePreferenceController.java
@@ -25,6 +25,7 @@
import androidx.preference.PreferenceScreen;
import android.util.Log;
+import com.android.settings.Utils;
import com.android.settings.widget.RestrictedAppPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -130,8 +131,11 @@
private List<Preference> getLocationServices() {
// If location access is locked down by device policy then we only show injected settings
// for the primary profile.
+ final int profileUserId = Utils.getManagedProfileId(mUserManager, UserHandle.myUserId());
+
return mInjector.getInjectedSettings(mFragment.getPreferenceManager().getContext(),
- mLocationEnabler.isManagedProfileRestrictedByBase()
+ (profileUserId != UserHandle.USER_NULL
+ && mLocationEnabler.getShareLocationEnforcedAdmin(profileUserId) != null)
? UserHandle.myUserId() : UserHandle.USER_CURRENT);
}
}
diff --git a/src/com/android/settings/notification/NotificationPreferenceController.java b/src/com/android/settings/notification/NotificationPreferenceController.java
index 49bb08e..1ce42c2 100644
--- a/src/com/android/settings/notification/NotificationPreferenceController.java
+++ b/src/com/android/settings/notification/NotificationPreferenceController.java
@@ -138,11 +138,11 @@
protected boolean isChannelBlockable() {
if (mChannel != null && mAppRow != null) {
- if (!mAppRow.systemApp) {
- return true;
+ if (!isChannelConfigurable()) {
+ return mChannel.getImportance() == IMPORTANCE_NONE;
}
- return mChannel.isBlockableSystem()
+ return mChannel.isBlockableSystem() || !mAppRow.systemApp
|| mChannel.getImportance() == IMPORTANCE_NONE;
}
return false;
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index 240ab68..e05dabe 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -119,22 +119,22 @@
List<String> enabledCategories = getEnabledCategories(policy,
category -> PRIORITY_CATEGORY_ALARMS == category
|| PRIORITY_CATEGORY_MEDIA == category
- || PRIORITY_CATEGORY_SYSTEM == category);
+ || PRIORITY_CATEGORY_SYSTEM == category, false);
int numCategories = enabledCategories.size();
if (numCategories == 0) {
return mContext.getString(R.string.zen_sound_all_muted);
} else if (numCategories == 1) {
return mContext.getString(R.string.zen_sound_one_allowed,
- enabledCategories.get(0).toLowerCase());
+ enabledCategories.get(0));
} else if (numCategories == 2) {
return mContext.getString(R.string.zen_sound_two_allowed,
- enabledCategories.get(0).toLowerCase(),
- enabledCategories.get(1).toLowerCase());
+ enabledCategories.get(0),
+ enabledCategories.get(1));
} else if (numCategories == 3) {
return mContext.getString(R.string.zen_sound_three_allowed,
- enabledCategories.get(0).toLowerCase(),
- enabledCategories.get(1).toLowerCase(),
- enabledCategories.get(2).toLowerCase());
+ enabledCategories.get(0),
+ enabledCategories.get(1),
+ enabledCategories.get(2));
} else {
return mContext.getString(R.string.zen_sound_none_muted);
}
@@ -143,17 +143,17 @@
String getCallsSettingSummary(Policy policy) {
List<String> enabledCategories = getEnabledCategories(policy,
category -> PRIORITY_CATEGORY_CALLS == category
- || PRIORITY_CATEGORY_REPEAT_CALLERS == category);
+ || PRIORITY_CATEGORY_REPEAT_CALLERS == category, false);
int numCategories = enabledCategories.size();
if (numCategories == 0) {
return mContext.getString(R.string.zen_mode_no_exceptions);
} else if (numCategories == 1) {
return mContext.getString(R.string.zen_mode_calls_summary_one,
- enabledCategories.get(0).toLowerCase());
+ enabledCategories.get(0));
} else {
return mContext.getString(R.string.zen_mode_calls_summary_two,
- enabledCategories.get(0).toLowerCase(),
- enabledCategories.get(1).toLowerCase());
+ enabledCategories.get(0),
+ enabledCategories.get(1));
}
}
@@ -161,7 +161,7 @@
List<String> enabledCategories = getEnabledCategories(policy,
category -> PRIORITY_CATEGORY_EVENTS == category
|| PRIORITY_CATEGORY_REMINDERS == category
- || PRIORITY_CATEGORY_MESSAGES == category);
+ || PRIORITY_CATEGORY_MESSAGES == category, true);
int numCategories = enabledCategories.size();
if (numCategories == 0) {
return mContext.getString(R.string.zen_mode_no_exceptions);
@@ -169,19 +169,19 @@
return enabledCategories.get(0);
} else if (numCategories == 2) {
return mContext.getString(R.string.join_two_items, enabledCategories.get(0),
- enabledCategories.get(1).toLowerCase());
+ enabledCategories.get(1));
} else if (numCategories == 3){
final List<String> summaries = new ArrayList<>();
summaries.add(enabledCategories.get(0));
- summaries.add(enabledCategories.get(1).toLowerCase());
- summaries.add(enabledCategories.get(2).toLowerCase());
+ summaries.add(enabledCategories.get(1));
+ summaries.add(enabledCategories.get(2));
return ListFormatter.getInstance().format(summaries);
} else {
final List<String> summaries = new ArrayList<>();
summaries.add(enabledCategories.get(0));
- summaries.add(enabledCategories.get(1).toLowerCase());
- summaries.add(enabledCategories.get(2).toLowerCase());
+ summaries.add(enabledCategories.get(1));
+ summaries.add(enabledCategories.get(2));
summaries.add(mContext.getString(R.string.zen_mode_other_options));
return ListFormatter.getInstance().format(summaries);
@@ -251,48 +251,18 @@
}
private List<String> getEnabledCategories(Policy policy,
- Predicate<Integer> filteredCategories) {
+ Predicate<Integer> filteredCategories, boolean capitalizeFirstInList) {
List<String> enabledCategories = new ArrayList<>();
for (int category : ALL_PRIORITY_CATEGORIES) {
+ boolean isFirst = capitalizeFirstInList && enabledCategories.isEmpty();
if (filteredCategories.test(category) && isCategoryEnabled(policy, category)) {
- if (category == PRIORITY_CATEGORY_ALARMS) {
- enabledCategories.add(mContext.getString(R.string.zen_mode_alarms));
- } else if (category == PRIORITY_CATEGORY_MEDIA) {
- enabledCategories.add(mContext.getString(
- R.string.zen_mode_media));
- } else if (category == PRIORITY_CATEGORY_SYSTEM) {
- enabledCategories.add(mContext.getString(
- R.string.zen_mode_system));
- } else if (category == Policy.PRIORITY_CATEGORY_MESSAGES) {
- if (policy.priorityMessageSenders == Policy.PRIORITY_SENDERS_ANY) {
- enabledCategories.add(mContext.getString(
- R.string.zen_mode_all_messages));
- } else {
- enabledCategories.add(mContext.getString(
- R.string.zen_mode_selected_messages));
- }
- } else if (category == Policy.PRIORITY_CATEGORY_EVENTS) {
- enabledCategories.add(mContext.getString(R.string.zen_mode_events));
- } else if (category == Policy.PRIORITY_CATEGORY_REMINDERS) {
- enabledCategories.add(mContext.getString(R.string.zen_mode_reminders));
- } else if (category == Policy.PRIORITY_CATEGORY_CALLS) {
- if (policy.priorityCallSenders == Policy.PRIORITY_SENDERS_ANY) {
- enabledCategories.add(mContext.getString(
- R.string.zen_mode_all_callers));
- } else if (policy.priorityCallSenders == Policy.PRIORITY_SENDERS_CONTACTS){
- enabledCategories.add(mContext.getString(
- R.string.zen_mode_contacts_callers));
- } else {
- enabledCategories.add(mContext.getString(
- R.string.zen_mode_starred_callers));
- }
- } else if (category == Policy.PRIORITY_CATEGORY_REPEAT_CALLERS) {
- if (!enabledCategories.contains(mContext.getString(
- R.string.zen_mode_all_callers))) {
- enabledCategories.add(mContext.getString(
- R.string.zen_mode_repeat_callers));
- }
+ if (category == Policy.PRIORITY_CATEGORY_REPEAT_CALLERS
+ && isCategoryEnabled(policy, Policy.PRIORITY_CATEGORY_CALLS)
+ && policy.priorityCallSenders == Policy.PRIORITY_SENDERS_ANY) {
+ continue;
}
+
+ enabledCategories.add(getCategory(category, policy, isFirst));
}
}
return enabledCategories;
@@ -301,6 +271,70 @@
private boolean isCategoryEnabled(Policy policy, int categoryType) {
return (policy.priorityCategories & categoryType) != 0;
}
+
+ private String getCategory(int category, Policy policy, boolean isFirst) {
+ if (category == PRIORITY_CATEGORY_ALARMS) {
+ if (isFirst) {
+ return mContext.getString(R.string.zen_mode_alarms);
+ } else {
+ return mContext.getString(R.string.zen_mode_alarms_list);
+ }
+ } else if (category == PRIORITY_CATEGORY_MEDIA) {
+ if (isFirst) {
+ return mContext.getString(R.string.zen_mode_media);
+ } else {
+ return mContext.getString(R.string.zen_mode_media_list);
+ }
+ } else if (category == PRIORITY_CATEGORY_SYSTEM) {
+ if (isFirst) {
+ return mContext.getString(R.string.zen_mode_system);
+ } else {
+ return mContext.getString(R.string.zen_mode_system_list);
+ }
+ } else if (category == Policy.PRIORITY_CATEGORY_MESSAGES) {
+ if (policy.priorityMessageSenders == Policy.PRIORITY_SENDERS_ANY) {
+ if (isFirst) {
+ return mContext.getString(R.string.zen_mode_all_messages);
+ } else {
+ return mContext.getString(R.string.zen_mode_all_messages_list);
+ }
+ } else {
+ if (isFirst) {
+ return mContext.getString(R.string.zen_mode_selected_messages);
+ } else {
+ return mContext.getString(R.string.zen_mode_selected_messages_list);
+ }
+ }
+ } else if (category == Policy.PRIORITY_CATEGORY_EVENTS) {
+ if (isFirst) {
+ return mContext.getString(R.string.zen_mode_events);
+ } else {
+ return mContext.getString(R.string.zen_mode_events_list);
+ }
+ } else if (category == Policy.PRIORITY_CATEGORY_REMINDERS) {
+ if (isFirst) {
+ return mContext.getString(R.string.zen_mode_reminders);
+ } else {
+ return mContext.getString(R.string.zen_mode_reminders_list);
+ }
+ } else if (category == Policy.PRIORITY_CATEGORY_CALLS) {
+ if (policy.priorityCallSenders == Policy.PRIORITY_SENDERS_ANY) {
+ return mContext.getString(R.string.zen_mode_all_callers);
+ } else if (policy.priorityCallSenders == Policy.PRIORITY_SENDERS_CONTACTS){
+ return mContext.getString(R.string.zen_mode_contacts_callers);
+ } else {
+ return mContext.getString(R.string.zen_mode_starred_callers);
+ }
+ } else if (category == Policy.PRIORITY_CATEGORY_REPEAT_CALLERS) {
+ if (isFirst) {
+ return mContext.getString(R.string.zen_mode_repeat_callers);
+ } else {
+ return mContext.getString(R.string.zen_mode_repeat_callers_list);
+ }
+ }
+
+ return "";
+ }
}
/**
diff --git a/src/com/android/settings/notification/ZenOnboardingActivity.java b/src/com/android/settings/notification/ZenOnboardingActivity.java
index 7b50dde..99bc172 100644
--- a/src/com/android/settings/notification/ZenOnboardingActivity.java
+++ b/src/com/android/settings/notification/ZenOnboardingActivity.java
@@ -157,6 +157,12 @@
// ZEN_SETTINGS_UPDATED is true for:
// - fresh P+ device
// - if zen visual effects values were changed by the user in Settings
+ NotificationManager nm = context.getSystemService(NotificationManager.class);
+ if (NotificationManager.Policy.areAllVisualEffectsSuppressed(
+ nm.getNotificationPolicy().suppressedVisualEffects)) {
+ Settings.Global.putInt(context.getContentResolver(),
+ Settings.Global.ZEN_SETTINGS_UPDATED, 1);
+ }
return Settings.Global.getInt(context.getContentResolver(),
Settings.Global.ZEN_SETTINGS_UPDATED, 0) != 0;
}
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
index b64e5403..48d563f 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.java
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -21,7 +21,6 @@
import android.content.Context;
import android.net.ConnectivityManager;
import android.os.UserManager;
-import androidx.annotation.Keep;
import com.android.settings.accounts.AccountFeatureProvider;
import com.android.settings.accounts.AccountFeatureProviderImpl;
@@ -54,6 +53,8 @@
import com.android.settings.users.UserFeatureProviderImpl;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import androidx.annotation.Keep;
+
/**
* {@link FeatureFactory} implementation for AOSP Settings.
*/
@@ -93,7 +94,8 @@
@Override
public PowerUsageFeatureProvider getPowerUsageFeatureProvider(Context context) {
if (mPowerUsageFeatureProvider == null) {
- mPowerUsageFeatureProvider = new PowerUsageFeatureProviderImpl(context);
+ mPowerUsageFeatureProvider = new PowerUsageFeatureProviderImpl(
+ context.getApplicationContext());
}
return mPowerUsageFeatureProvider;
}
@@ -101,7 +103,8 @@
@Override
public DashboardFeatureProvider getDashboardFeatureProvider(Context context) {
if (mDashboardFeatureProvider == null) {
- mDashboardFeatureProvider = new DashboardFeatureProviderImpl(context);
+ mDashboardFeatureProvider = new DashboardFeatureProviderImpl(
+ context.getApplicationContext());
}
return mDashboardFeatureProvider;
}
@@ -117,10 +120,11 @@
@Override
public ApplicationFeatureProvider getApplicationFeatureProvider(Context context) {
if (mApplicationFeatureProvider == null) {
- mApplicationFeatureProvider = new ApplicationFeatureProviderImpl(context,
- context.getPackageManager(),
+ final Context appContext = context.getApplicationContext();
+ mApplicationFeatureProvider = new ApplicationFeatureProviderImpl(appContext,
+ appContext.getPackageManager(),
AppGlobals.getPackageManager(),
- (DevicePolicyManager) context
+ (DevicePolicyManager) appContext
.getSystemService(Context.DEVICE_POLICY_SERVICE));
}
return mApplicationFeatureProvider;
@@ -137,12 +141,14 @@
@Override
public EnterprisePrivacyFeatureProvider getEnterprisePrivacyFeatureProvider(Context context) {
if (mEnterprisePrivacyFeatureProvider == null) {
- mEnterprisePrivacyFeatureProvider = new EnterprisePrivacyFeatureProviderImpl(context,
- (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE),
- context.getPackageManager(),
- UserManager.get(context),
- (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE),
- context.getResources());
+ final Context appContext = context.getApplicationContext();
+ mEnterprisePrivacyFeatureProvider = new EnterprisePrivacyFeatureProviderImpl(appContext,
+ (DevicePolicyManager) appContext.getSystemService(
+ Context.DEVICE_POLICY_SERVICE),
+ appContext.getPackageManager(),
+ UserManager.get(appContext),
+ (ConnectivityManager) appContext.getSystemService(Context.CONNECTIVITY_SERVICE),
+ appContext.getResources());
}
return mEnterprisePrivacyFeatureProvider;
}
@@ -171,7 +177,8 @@
@Override
public SuggestionFeatureProvider getSuggestionFeatureProvider(Context context) {
if (mSuggestionFeatureProvider == null) {
- mSuggestionFeatureProvider = new SuggestionFeatureProviderImpl(context);
+ mSuggestionFeatureProvider = new SuggestionFeatureProviderImpl(
+ context.getApplicationContext());
}
return mSuggestionFeatureProvider;
}
@@ -179,7 +186,7 @@
@Override
public UserFeatureProvider getUserFeatureProvider(Context context) {
if (mUserFeatureProvider == null) {
- mUserFeatureProvider = new UserFeatureProviderImpl(context);
+ mUserFeatureProvider = new UserFeatureProviderImpl(context.getApplicationContext());
}
return mUserFeatureProvider;
}
diff --git a/src/com/android/settings/print/PrintSettingsFragment.java b/src/com/android/settings/print/PrintSettingsFragment.java
index dca1f58..bad1e03 100644
--- a/src/com/android/settings/print/PrintSettingsFragment.java
+++ b/src/com/android/settings/print/PrintSettingsFragment.java
@@ -56,6 +56,7 @@
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.utils.ProfileSettingsPreferenceFragment;
+import com.android.settings.widget.AppPreference;
import com.android.settingslib.search.SearchIndexable;
import java.text.DateFormat;
@@ -193,7 +194,7 @@
}
for (PrintServiceInfo service : services) {
- Preference preference = new Preference(context);
+ AppPreference preference = new AppPreference(context);
String title = service.getResolveInfo().loadLabel(pm).toString();
preference.setTitle(title);
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index db09a37..7eda82b 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -34,6 +34,7 @@
import com.android.settings.bluetooth.BluetoothSliceBuilder;
import com.android.settings.core.BasePreferenceController;
+import com.android.settings.flashlight.FlashlightSliceBuilder;
import com.android.settings.location.LocationSliceBuilder;
import com.android.settings.notification.ZenModeSliceBuilder;
import com.android.settings.mobilenetwork.Enhanced4gLteSliceHelper;
@@ -160,6 +161,10 @@
} else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
registerIntentToUri(BluetoothSliceBuilder.INTENT_FILTER, sliceUri);
return;
+ } else if (FlashlightSliceBuilder.FLASHLIGHT_URI.equals(sliceUri)) {
+ registerIntentToUri(FlashlightSliceBuilder.INTENT_FILTER , sliceUri);
+ mRegisteredUris.add(sliceUri);
+ return;
}
// Start warming the slice, we expect someone will want it soon.
@@ -191,32 +196,35 @@
Log.e(TAG, "Requested blocked slice with Uri: " + sliceUri);
return null;
}
- // If adding a new Slice, do not directly match Slice URIs.
- // Use {@link SlicesDatabaseAccessor}.
- if (WifiCallingSliceHelper.WIFI_CALLING_URI.equals(sliceUri)) {
- return FeatureFactory.getFactory(getContext())
- .getSlicesFeatureProvider()
- .getNewWifiCallingSliceHelper(getContext())
- .createWifiCallingSlice(sliceUri);
- } else if (WifiSliceBuilder.WIFI_URI.equals(sliceUri)) {
- return WifiSliceBuilder.getSlice(getContext());
- } else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
- return ZenModeSliceBuilder.getSlice(getContext());
- } else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
- return BluetoothSliceBuilder.getSlice(getContext());
- } else if (LocationSliceBuilder.LOCATION_URI.equals(sliceUri)) {
- return LocationSliceBuilder.getSlice(getContext());
- } else if (Enhanced4gLteSliceHelper.SLICE_URI.equals(sliceUri)) {
- return FeatureFactory.getFactory(getContext())
- .getSlicesFeatureProvider()
- .getNewEnhanced4gLteSliceHelper(getContext())
- .createEnhanced4gLteSlice(sliceUri);
- } else if (WifiCallingSliceHelper.WIFI_CALLING_PREFERENCE_URI.equals(sliceUri)) {
- return FeatureFactory.getFactory(getContext())
- .getSlicesFeatureProvider()
- .getNewWifiCallingSliceHelper(getContext())
- .createWifiCallingPreferenceSlice(sliceUri);
- }
+
+ // If adding a new Slice, do not directly match Slice URIs.
+ // Use {@link SlicesDatabaseAccessor}.
+ if (WifiCallingSliceHelper.WIFI_CALLING_URI.equals(sliceUri)) {
+ return FeatureFactory.getFactory(getContext())
+ .getSlicesFeatureProvider()
+ .getNewWifiCallingSliceHelper(getContext())
+ .createWifiCallingSlice(sliceUri);
+ } else if (WifiSliceBuilder.WIFI_URI.equals(sliceUri)) {
+ return WifiSliceBuilder.getSlice(getContext());
+ } else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
+ return ZenModeSliceBuilder.getSlice(getContext());
+ } else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
+ return BluetoothSliceBuilder.getSlice(getContext());
+ } else if (LocationSliceBuilder.LOCATION_URI.equals(sliceUri)) {
+ return LocationSliceBuilder.getSlice(getContext());
+ } else if (Enhanced4gLteSliceHelper.SLICE_URI.equals(sliceUri)) {
+ return FeatureFactory.getFactory(getContext())
+ .getSlicesFeatureProvider()
+ .getNewEnhanced4gLteSliceHelper(getContext())
+ .createEnhanced4gLteSlice(sliceUri);
+ } else if (WifiCallingSliceHelper.WIFI_CALLING_PREFERENCE_URI.equals(sliceUri)) {
+ return FeatureFactory.getFactory(getContext())
+ .getSlicesFeatureProvider()
+ .getNewWifiCallingSliceHelper(getContext())
+ .createWifiCallingPreferenceSlice(sliceUri);
+ } else if (FlashlightSliceBuilder.FLASHLIGHT_URI.equals(sliceUri)) {
+ return FlashlightSliceBuilder.getSlice(getContext());
+ }
SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
if (cachedSliceData == null) {
@@ -381,7 +389,8 @@
private List<Uri> getSpecialCaseOemUris() {
return Arrays.asList(
- ZenModeSliceBuilder.ZEN_MODE_URI
+ ZenModeSliceBuilder.ZEN_MODE_URI,
+ FlashlightSliceBuilder.FLASHLIGHT_URI
);
}
diff --git a/src/com/android/settings/slices/SliceBroadcastReceiver.java b/src/com/android/settings/slices/SliceBroadcastReceiver.java
index 9f1ef76..95f0538 100644
--- a/src/com/android/settings/slices/SliceBroadcastReceiver.java
+++ b/src/com/android/settings/slices/SliceBroadcastReceiver.java
@@ -17,6 +17,7 @@
package com.android.settings.slices;
import static com.android.settings.bluetooth.BluetoothSliceBuilder.ACTION_BLUETOOTH_SLICE_CHANGED;
+import static com.android.settings.flashlight.FlashlightSliceBuilder.ACTION_FLASHLIGHT_SLICE_CHANGED;
import static com.android.settings.notification.ZenModeSliceBuilder.ACTION_ZEN_MODE_SLICE_CHANGED;
import static com.android.settings.slices.SettingsSliceProvider.ACTION_SLIDER_CHANGED;
import static com.android.settings.slices.SettingsSliceProvider.ACTION_TOGGLE_CHANGED;
@@ -45,6 +46,7 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.SliderPreferenceController;
import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.flashlight.FlashlightSliceBuilder;
import com.android.settings.notification.ZenModeSliceBuilder;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wifi.WifiSliceBuilder;
@@ -102,6 +104,9 @@
.getNewWifiCallingSliceHelper(context)
.handleWifiCallingPreferenceChanged(intent);
break;
+ case ACTION_FLASHLIGHT_SLICE_CHANGED:
+ FlashlightSliceBuilder.handleUriChange(context, intent);
+ break;
default:
final String uriString = intent.getStringExtra(SliceBroadcastRelay.EXTRA_URI);
if (!TextUtils.isEmpty(uriString)) {
diff --git a/src/com/android/settings/sound/AudioSwitchPreferenceController.java b/src/com/android/settings/sound/AudioSwitchPreferenceController.java
index f35fd60..274819c 100644
--- a/src/com/android/settings/sound/AudioSwitchPreferenceController.java
+++ b/src/com/android/settings/sound/AudioSwitchPreferenceController.java
@@ -37,9 +37,6 @@
import android.media.MediaRouter.Callback;
import android.os.Handler;
import android.os.Looper;
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
import android.text.TextUtils;
import android.util.FeatureFlagUtils;
import android.util.Log;
@@ -64,6 +61,10 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
/**
* Abstract class for audio switcher controller to notify subclass
* updating the current status of switcher entry. Subclasses must overwrite
@@ -74,7 +75,7 @@
implements Preference.OnPreferenceChangeListener, BluetoothCallback,
LifecycleObserver, OnStart, OnStop {
- private static final String TAG = "AudioSwitchPreferenceController";
+ private static final String TAG = "AudioSwitchPrefCtrl";
private static final int INVALID_INDEX = -1;
protected final List<BluetoothDevice> mConnectedDevices;
@@ -118,7 +119,6 @@
Log.e(TAG, "Bluetooth is not supported on this device");
return;
}
- mLocalBluetoothManager.setForegroundActivity(mContext);
mProfileManager = mLocalBluetoothManager.getProfileManager();
}
@@ -171,11 +171,21 @@
@Override
public void onStart() {
+ if (mLocalBluetoothManager == null) {
+ Log.e(TAG, "Bluetooth is not supported on this device");
+ return;
+ }
+ mLocalBluetoothManager.setForegroundActivity(mContext);
register();
}
@Override
public void onStop() {
+ if (mLocalBluetoothManager == null) {
+ Log.e(TAG, "Bluetooth is not supported on this device");
+ return;
+ }
+ mLocalBluetoothManager.setForegroundActivity(null);
unregister();
}
diff --git a/src/com/android/settings/widget/HotspotApBandSelectionPreference.java b/src/com/android/settings/widget/HotspotApBandSelectionPreference.java
deleted file mode 100644
index b249b99..0000000
--- a/src/com/android/settings/widget/HotspotApBandSelectionPreference.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.widget;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.net.wifi.WifiConfiguration;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import androidx.annotation.VisibleForTesting;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.LinearLayout;
-
-import com.android.settings.R;
-import com.android.settingslib.CustomDialogPreference;
-
-import java.util.ArrayList;
-
-public class HotspotApBandSelectionPreference extends CustomDialogPreference implements
- CompoundButton.OnCheckedChangeListener, DialogInterface.OnShowListener {
- private static final int UNSET = Integer.MIN_VALUE;
-
- @VisibleForTesting
- static final String KEY_CHECKED_BANDS = "checked_bands";
- @VisibleForTesting
- static final String KEY_HOTSPOT_SUPER_STATE = "hotspot_super_state";
-
- @VisibleForTesting
- CheckBox mBox2G;
- @VisibleForTesting
- CheckBox mBox5G;
- @VisibleForTesting
- ArrayList<Integer> mRestoredBands;
- @VisibleForTesting
- boolean mShouldRestore;
-
- private String[] mBandEntries;
- private int mExistingConfigValue = UNSET;
-
- public HotspotApBandSelectionPreference(Context context) {
- super(context);
- }
-
- public HotspotApBandSelectionPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public HotspotApBandSelectionPreference(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- public HotspotApBandSelectionPreference(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
-
- @Override
- protected void onRestoreInstanceState(Parcelable state) {
- SavedState myState = (SavedState) state;
-
- super.onRestoreInstanceState(myState.getSuperState());
-
- mShouldRestore = myState.shouldRestore;
- if (mShouldRestore) {
- mRestoredBands = new ArrayList<>();
- if (myState.enabled2G) {
- mRestoredBands.add(WifiConfiguration.AP_BAND_2GHZ);
- }
- if (myState.enabled5G) {
- mRestoredBands.add(WifiConfiguration.AP_BAND_5GHZ);
- }
- } else {
- mRestoredBands = null;
- }
- updatePositiveButton();
- }
-
- @Override
- protected void onBindDialogView(View view) {
- super.onBindDialogView(view);
- final Context context = getContext();
-
- // Register so we can adjust the buttons if needed once the dialog is available.
- setOnShowListener(this);
-
- mBandEntries = context.getResources().getStringArray(R.array.wifi_ap_band_config_full);
- // add a checkbox for every band entry.
- addApBandViews((LinearLayout) view);
- // try to update the button just in case we already missed the onShow call.
- updatePositiveButton();
- // clear any saved state so it doesn't leak across multiple rotations/dialog closings
- mRestoredBands = null;
- mShouldRestore = false;
- }
-
- @Override
- protected Parcelable onSaveInstanceState() {
- final Parcelable superState = super.onSaveInstanceState();
-
- SavedState myState = new SavedState(superState);
- myState.shouldRestore = getDialog() != null;
- myState.enabled2G = mBox2G != null && mBox2G.isChecked();
- myState.enabled5G = mBox5G != null && mBox5G.isChecked();
- return myState;
- }
-
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (!(buttonView instanceof CheckBox)) {
- return;
- }
- updatePositiveButton();
- }
-
- @Override
- protected void onClick(DialogInterface dialog, int which) {
- // we only want to persist our enabled bands if apply is clicked
- if (which == DialogInterface.BUTTON_POSITIVE) {
- if (mBox2G.isChecked() || mBox5G.isChecked()) {
- int wifiBand = getWifiBand();
- mExistingConfigValue = wifiBand;
- callChangeListener(wifiBand);
- }
- }
- }
-
- /**
- * Used to set the band selection for the preference if one already exists
- * @param band the band to set it to from {@link WifiConfiguration}
- */
- public void setExistingConfigValue(int band) {
- mExistingConfigValue = band;
- }
-
- private void addApBandViews(LinearLayout view) {
- mBox2G = view.findViewById(R.id.box_2g);
- mBox2G.setText(mBandEntries[WifiConfiguration.AP_BAND_2GHZ]);
- mBox2G.setChecked(restoreBandIfNeeded(WifiConfiguration.AP_BAND_2GHZ));
- mBox2G.setOnCheckedChangeListener(this);
-
- mBox5G = view.findViewById(R.id.box_5g);
- mBox5G.setText(mBandEntries[WifiConfiguration.AP_BAND_5GHZ]);
- mBox5G.setChecked(restoreBandIfNeeded(WifiConfiguration.AP_BAND_5GHZ));
- mBox5G.setOnCheckedChangeListener(this);
- }
-
- private boolean restoreBandIfNeeded(int band) {
- // Only use the provided config if we aren't restoring, restore if state available
- return (isBandPreviouslySelected(band) && !mShouldRestore)
- || (mShouldRestore && mRestoredBands.contains(band));
- }
-
- private void updatePositiveButton() {
- AlertDialog dialog = (AlertDialog) getDialog();
- Button button = dialog == null ? null : dialog.getButton(DialogInterface.BUTTON_POSITIVE);
- if (button != null && mBox5G != null && mBox2G != null) {
- button.setEnabled(mBox2G.isChecked() || mBox5G.isChecked());
- }
- }
-
- @VisibleForTesting
- int getWifiBand() {
- final boolean checked_2g = mBox2G.isChecked();
- final boolean checked_5g = mBox5G.isChecked();
- if (checked_2g && checked_5g) {
- return WifiConfiguration.AP_BAND_ANY;
- } else if (checked_2g && !checked_5g) {
- return WifiConfiguration.AP_BAND_2GHZ;
- } else if (checked_5g && !checked_2g) {
- return WifiConfiguration.AP_BAND_5GHZ;
- } else {
- throw new IllegalStateException("Wifi Config only supports selecting one or all bands");
- }
- }
-
- private boolean isBandPreviouslySelected(int bandIndex) {
- switch(mExistingConfigValue) {
- case WifiConfiguration.AP_BAND_ANY:
- return true;
- case WifiConfiguration.AP_BAND_2GHZ:
- return bandIndex == 0;
- case WifiConfiguration.AP_BAND_5GHZ:
- return bandIndex == 1;
- case UNSET:
- default:
- return false;
- }
- }
-
- @Override
- public void onShow(DialogInterface dialog) {
- updatePositiveButton();
- }
-
- private static class SavedState extends BaseSavedState {
- boolean shouldRestore;
- boolean enabled2G;
- boolean enabled5G;
-
- public SavedState(Parcelable source) {
- super(source);
- }
-
- private SavedState(Parcel in) {
- super(in);
- shouldRestore = in.readByte() == 1;
- enabled2G = in.readByte() == 1;
- enabled5G = in.readByte() == 1;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
- dest.writeByte((byte) (shouldRestore ? 1 : 0));
- dest.writeByte((byte) (enabled2G ? 1: 0));
- dest.writeByte((byte) (enabled5G ? 1 : 0));
- }
-
- @Override
- public String toString() {
- return "HotspotApBandSelectionPreference.SavedState{"
- + Integer.toHexString(System.identityHashCode(this))
- + " shouldRestore=" + shouldRestore
- + " enabled2G=" + enabled2G
- + " enabled5G=" + enabled5G + "}";
- }
-
- public static final Parcelable.Creator<SavedState> CREATOR
- = new Parcelable.Creator<SavedState>() {
- public SavedState createFromParcel(Parcel in) {
- return new SavedState(in);
- }
-
- public SavedState[] newArray(int size) {
- return new SavedState[size];
- }
- };
- }
-}
diff --git a/src/com/android/settings/wifi/WifiUtils.java b/src/com/android/settings/wifi/WifiUtils.java
index 1e8308b..ff8570e 100644
--- a/src/com/android/settings/wifi/WifiUtils.java
+++ b/src/com/android/settings/wifi/WifiUtils.java
@@ -26,6 +26,8 @@
import android.provider.Settings;
import android.text.TextUtils;
+import java.nio.charset.StandardCharsets;
+
public class WifiUtils {
private static final int SSID_ASCII_MIN_LENGTH = 1;
@@ -38,7 +40,7 @@
if (TextUtils.isEmpty(ssid)) {
return false;
}
- return ssid.length() > SSID_ASCII_MAX_LENGTH;
+ return ssid.getBytes(StandardCharsets.UTF_8).length > SSID_ASCII_MAX_LENGTH;
}
public static boolean isSSIDTooShort(String ssid) {
@@ -59,8 +61,9 @@
/**
* This method is a stripped and negated version of WifiConfigStore.canModifyNetwork.
+ *
* @param context Context of caller
- * @param config The WiFi config.
+ * @param config The WiFi config.
* @return true if Settings cannot modify the config due to lockDown.
*/
public static boolean isNetworkLockedDown(Context context, WifiConfiguration config) {
diff --git a/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java
index 8dde24b..b1f171b 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java
@@ -16,36 +16,32 @@
package com.android.settings.wifi.tether;
-import static android.net.wifi.WifiConfiguration.AP_BAND_2GHZ;
-import static android.net.wifi.WifiConfiguration.AP_BAND_5GHZ;
-
import android.content.Context;
import android.content.res.Resources;
-import android.icu.text.ListFormatter;
import android.net.wifi.WifiConfiguration;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.ListPreference;
import androidx.preference.Preference;
import android.util.Log;
import com.android.settings.R;
-import com.android.settings.widget.HotspotApBandSelectionPreference;
public class WifiTetherApBandPreferenceController extends WifiTetherBasePreferenceController {
private static final String TAG = "WifiTetherApBandPref";
private static final String PREF_KEY = "wifi_tether_network_ap_band";
- public static final String[] BAND_VALUES =
- {String.valueOf(AP_BAND_2GHZ), String.valueOf(AP_BAND_5GHZ)};
- private final String[] mBandEntries;
- private final String[] mBandSummaries;
+ private String[] mBandEntries;
+ private String[] mBandSummaries;
private int mBandIndex;
+ private boolean isDualMode;
public WifiTetherApBandPreferenceController(Context context,
OnTetherConfigUpdateListener listener) {
super(context, listener);
- Resources res = mContext.getResources();
- mBandEntries = res.getStringArray(R.array.wifi_ap_band_config_full);
- mBandSummaries = res.getStringArray(R.array.wifi_ap_band_summary_full);
+ isDualMode = mWifiManager.isDualModeSupported();
+ updatePreferenceEntries();
}
@Override
@@ -55,7 +51,7 @@
mBandIndex = 0;
Log.d(TAG, "Updating band index to 0 because no config");
} else if (is5GhzBandSupported()) {
- mBandIndex = config.apBand;
+ mBandIndex = validateSelection(config.apBand);
Log.d(TAG, "Updating band index to " + mBandIndex);
} else {
config.apBand = 0;
@@ -63,21 +59,23 @@
mBandIndex = config.apBand;
Log.d(TAG, "5Ghz not supported, updating band index to " + mBandIndex);
}
- HotspotApBandSelectionPreference preference =
- (HotspotApBandSelectionPreference) mPreference;
+ ListPreference preference =
+ (ListPreference) mPreference;
+ preference.setEntries(mBandSummaries);
+ preference.setEntryValues(mBandEntries);
if (!is5GhzBandSupported()) {
preference.setEnabled(false);
preference.setSummary(R.string.wifi_ap_choose_2G);
} else {
- preference.setExistingConfigValue(config.apBand);
+ preference.setValue(Integer.toString(config.apBand));
preference.setSummary(getConfigSummary());
}
}
String getConfigSummary() {
if (mBandIndex == WifiConfiguration.AP_BAND_ANY) {
- return ListFormatter.getInstance().format((Object[]) mBandSummaries);
+ return mContext.getString(R.string.wifi_ap_prefer_5G);
}
return mBandSummaries[mBandIndex];
}
@@ -89,13 +87,46 @@
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
- mBandIndex = (Integer) newValue;
+ mBandIndex = validateSelection(Integer.parseInt((String) newValue));
Log.d(TAG, "Band preference changed, updating band index to " + mBandIndex);
preference.setSummary(getConfigSummary());
mListener.onTetherConfigUpdated();
return true;
}
+ private int validateSelection(int band) {
+ // Reset the band to 2.4 GHz if we get a weird config back to avoid a crash.
+ final boolean isDualMode = mWifiManager.isDualModeSupported();
+
+ // unsupported states:
+ // 1: no dual mode means we can't have AP_BAND_ANY - default to 5GHZ
+ // 2: no 5 GHZ support means we can't have AP_BAND_5GHZ - default to 2GHZ
+ // 3: With Dual mode support we can't have AP_BAND_5GHZ - default to ANY
+ if (!isDualMode && WifiConfiguration.AP_BAND_ANY == band) {
+ return WifiConfiguration.AP_BAND_5GHZ;
+ } else if (!mWifiManager.is5GHzBandSupported() && WifiConfiguration.AP_BAND_5GHZ == band) {
+ return WifiConfiguration.AP_BAND_2GHZ;
+ } else if (isDualMode && WifiConfiguration.AP_BAND_5GHZ == band) {
+ return WifiConfiguration.AP_BAND_ANY;
+ }
+
+ return band;
+ }
+
+ @VisibleForTesting
+ void updatePreferenceEntries() {
+ Resources res = mContext.getResources();
+ int entriesRes = R.array.wifi_ap_band_config_full;
+ int summariesRes = R.array.wifi_ap_band_summary_full;
+ // change the list options if this is a dual mode device
+ if (isDualMode) {
+ entriesRes = R.array.wifi_ap_band_dual_mode;
+ summariesRes = R.array.wifi_ap_band_dual_mode_summary;
+ }
+ mBandEntries = res.getStringArray(entriesRes);
+ mBandSummaries = res.getStringArray(summariesRes);
+ }
+
private boolean is5GhzBandSupported() {
final String countryCode = mWifiManager.getCountryCode();
if (!mWifiManager.isDualBandSupported() || countryCode == null) {
diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider
index a55f024..655346b 100644
--- a/tests/robotests/assets/grandfather_not_implementing_index_provider
+++ b/tests/robotests/assets/grandfather_not_implementing_index_provider
@@ -7,6 +7,7 @@
com.android.settings.accounts.ManagedProfileSettings
com.android.settings.fuelgauge.PowerUsageAnomalyDetails
com.android.settings.fuelgauge.AdvancedPowerUsageDetail
+com.android.settings.datausage.DataUsageSummaryLegacy
com.android.settings.development.featureflags.FeatureFlagsDashboard
com.android.settings.development.qstile.DevelopmentTileConfigFragment
com.android.settings.deviceinfo.StorageProfileFragment
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountSyncSettingsTest.java b/tests/robotests/src/com/android/settings/accounts/AccountSyncSettingsTest.java
new file mode 100644
index 0000000..da36185
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accounts/AccountSyncSettingsTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.accounts;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.accounts.Account;
+import android.app.Activity;
+import android.content.Context;
+import android.os.UserHandle;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowContentResolver;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowContentResolver.class})
+public class AccountSyncSettingsTest {
+
+ @After
+ public void tearDown() {
+ ShadowContentResolver.reset();
+ }
+
+ @Test
+ public void onPreferenceTreeClick_nullAuthority_shouldNotCrash() {
+ final Context context = RuntimeEnvironment.application;
+ final AccountSyncSettings settings = spy(new AccountSyncSettings());
+ when(settings.getActivity()).thenReturn(mock(Activity.class));
+ final SyncStateSwitchPreference preference = new SyncStateSwitchPreference(context,
+ new Account("acct1", "type1"), "" /* authority */, "testPackage", 1 /* uid */);
+ preference.setOneTimeSyncMode(false);
+ ReflectionHelpers.setField(settings, "mUserHandle", UserHandle.CURRENT);
+
+ settings.onPreferenceTreeClick(preference);
+ // no crash
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java
index fd2ff0d..6e69e67 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java
@@ -20,6 +20,7 @@
import androidx.preference.Preference;
import com.android.settings.bluetooth.BluetoothDeviceUpdater;
+import com.android.settings.connecteddevice.dock.DockUpdater;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -45,6 +46,8 @@
@Mock
private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
@Mock
+ private DockUpdater mDockUpdater;
+ @Mock
private PackageManager mPackageManager;
private Context mContext;
@@ -60,6 +63,7 @@
mPreConnectedDeviceController =
new PreviouslyConnectedDevicePreferenceController(mContext, KEY);
mPreConnectedDeviceController.setBluetoothDeviceUpdater(mBluetoothDeviceUpdater);
+ mPreConnectedDeviceController.setSavedDockUpdater(mDockUpdater);
mPreference = new Preference(mContext);
mPreConnectedDeviceController.setPreference(mPreference);
@@ -70,10 +74,12 @@
// register the callback in onStart()
mPreConnectedDeviceController.onStart();
verify(mBluetoothDeviceUpdater).registerCallback();
+ verify(mDockUpdater).registerCallback();
// unregister the callback in onStop()
mPreConnectedDeviceController.onStop();
verify(mBluetoothDeviceUpdater).unregisterCallback();
+ verify(mDockUpdater).unregisterCallback();
}
@Test
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogControllerTest.java
index 658a60a..349eddc 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogControllerTest.java
@@ -128,4 +128,19 @@
verify(mDialog).setText(eq(ID_IMEI_SV_VALUE), any());
verify(mDialog).removeViewFromScreen(ID_CDMA_SETTINGS);
}
+
+ @Test
+ public void populateImeiInfo_emptyImei_shouldSetMeid_imeiSetToEmptyString() {
+ doReturn(true).when(mController).isCdmaLteEnabled();
+ when(mTelephonyManager.getPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_CDMA);
+ when(mTelephonyManager.getImei(anyInt())).thenReturn(null);
+
+ mController.populateImeiInfo();
+
+ verify(mDialog).setText(ID_MEID_NUMBER_VALUE, MEID_NUMBER);
+ verify(mDialog).setText(ID_MIN_NUMBER_VALUE, MIN_NUMBER);
+ verify(mDialog).setText(ID_PRL_VERSION_VALUE, PRL_VERSION);
+ verify(mDialog).setText(eq(ID_IMEI_VALUE), eq(""));
+ verify(mDialog).setText(eq(ID_IMEI_SV_VALUE), any());
+ }
}
diff --git a/tests/robotests/src/com/android/settings/display/ColorModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/ColorModePreferenceControllerTest.java
index c7b6535..83343fe 100644
--- a/tests/robotests/src/com/android/settings/display/ColorModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/ColorModePreferenceControllerTest.java
@@ -16,13 +16,12 @@
package com.android.settings.display;
+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.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
-import androidx.preference.Preference;
import com.android.internal.app.ColorDisplayController;
import com.android.settings.R;
@@ -35,63 +34,69 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
+import androidx.preference.Preference;
+
@RunWith(SettingsRobolectricTestRunner.class)
public class ColorModePreferenceControllerTest {
@Mock
- private Preference mPreference;
- @Mock
private ColorDisplayController mColorDisplayController;
private Context mContext;
+ private Preference mPreference;
private ColorModePreferenceController mController;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- mController = spy(new ColorModePreferenceController(mContext));
+ mController = spy(new ColorModePreferenceController(mContext, "test"));
+ mPreference = new Preference(mContext);
doReturn(mColorDisplayController).when(mController).getColorDisplayController();
}
@Test
public void updateState_colorModeAutomatic_shouldSetSummaryToAutomatic() {
when(mColorDisplayController.getColorMode())
- .thenReturn(ColorDisplayController.COLOR_MODE_AUTOMATIC);
+ .thenReturn(ColorDisplayController.COLOR_MODE_AUTOMATIC);
mController.updateState(mPreference);
- verify(mPreference).setSummary(mContext.getString(R.string.color_mode_option_automatic));
+ assertThat(mPreference.getSummary())
+ .isEqualTo(mContext.getText(R.string.color_mode_option_automatic));
}
@Test
public void updateState_colorModeSaturated_shouldSetSummaryToSaturated() {
when(mColorDisplayController.getColorMode())
- .thenReturn(ColorDisplayController.COLOR_MODE_SATURATED);
+ .thenReturn(ColorDisplayController.COLOR_MODE_SATURATED);
mController.updateState(mPreference);
- verify(mPreference).setSummary(mContext.getString(R.string.color_mode_option_saturated));
+ assertThat(mPreference.getSummary())
+ .isEqualTo(mContext.getText(R.string.color_mode_option_saturated));
}
@Test
public void updateState_colorModeBoosted_shouldSetSummaryToBoosted() {
when(mColorDisplayController.getColorMode())
- .thenReturn(ColorDisplayController.COLOR_MODE_BOOSTED);
+ .thenReturn(ColorDisplayController.COLOR_MODE_BOOSTED);
mController.updateState(mPreference);
- verify(mPreference).setSummary(mContext.getString(R.string.color_mode_option_boosted));
+ assertThat(mPreference.getSummary())
+ .isEqualTo(mContext.getText(R.string.color_mode_option_boosted));
}
@Test
public void updateState_colorModeNatural_shouldSetSummaryToNatural() {
when(mColorDisplayController.getColorMode())
- .thenReturn(ColorDisplayController.COLOR_MODE_NATURAL);
+ .thenReturn(ColorDisplayController.COLOR_MODE_NATURAL);
mController.updateState(mPreference);
- verify(mPreference).setSummary(mContext.getString(R.string.color_mode_option_natural));
+ assertThat(mPreference.getSummary())
+ .isEqualTo(mContext.getText(R.string.color_mode_option_natural));
}
}
diff --git a/tests/robotests/src/com/android/settings/flashlight/FlashlightSliceBuilderTest.java b/tests/robotests/src/com/android/settings/flashlight/FlashlightSliceBuilderTest.java
new file mode 100644
index 0000000..5862ab3
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/flashlight/FlashlightSliceBuilderTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.flashlight;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.SliceTester;
+
+import android.content.res.Resources;
+import android.provider.Settings;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.List;
+
+import androidx.slice.Slice;
+import androidx.slice.SliceItem;
+import androidx.slice.SliceMetadata;
+import androidx.slice.SliceProvider;
+import androidx.slice.core.SliceAction;
+import androidx.slice.widget.SliceLiveData;
+
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class FlashlightSliceBuilderTest {
+
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = spy(RuntimeEnvironment.application);
+
+ // Prevent crash in SliceMetadata.
+ Resources resources = spy(mContext.getResources());
+ doReturn(60).when(resources).getDimensionPixelSize(anyInt());
+ doReturn(resources).when(mContext).getResources();
+
+ // Set-up specs for SliceMetadata.
+ SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
+ }
+
+ @Test
+ public void getFlashlightSlice_correctData() {
+ Settings.Secure.putInt(
+ mContext.getContentResolver(), Settings.Secure.FLASHLIGHT_AVAILABLE, 1);
+ final Slice slice = FlashlightSliceBuilder.getSlice(mContext);
+ final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+
+ final List<SliceAction> toggles = metadata.getToggles();
+ assertThat(toggles).hasSize(1);
+
+ final List<SliceItem> sliceItems = slice.getItems();
+ SliceTester.assertTitle(sliceItems, mContext.getString(R.string.power_flashlight));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
index d5f3e2b..3dee0a6 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
@@ -32,7 +32,6 @@
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.UserManager;
-import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -50,6 +49,8 @@
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import androidx.preference.Preference;
+
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {SettingsShadowResources.SettingsShadowTheme.class, ShadowFragment.class})
public class BackgroundActivityPreferenceControllerTest {
@@ -89,6 +90,7 @@
mShadowContext = RuntimeEnvironment.application;
FakeFeatureFactory.setupForTest();
+ when(mContext.getApplicationContext()).thenReturn(mContext);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
@@ -118,7 +120,7 @@
@Test
public void testHandlePreferenceTreeClick_restrictApp_showDialog() {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
- .checkOpNoThrow(anyInt(), anyInt(), anyString());
+ .checkOpNoThrow(anyInt(), anyInt(), anyString());
mController.handlePreferenceTreeClick(mPreference);
@@ -128,7 +130,7 @@
@Test
public void testHandlePreferenceTreeClick_unRestrictApp_showDialog() {
doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager)
- .checkOpNoThrow(anyInt(), anyInt(), anyString());
+ .checkOpNoThrow(anyInt(), anyInt(), anyString());
mController.handlePreferenceTreeClick(mPreference);
diff --git a/tests/robotests/src/com/android/settings/location/LocationServicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationServicePreferenceControllerTest.java
index f3958f4..a6059a9 100644
--- a/tests/robotests/src/com/android/settings/location/LocationServicePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/location/LocationServicePreferenceControllerTest.java
@@ -16,6 +16,7 @@
package com.android.settings.location;
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
@@ -25,24 +26,17 @@
import static org.mockito.Mockito.when;
import android.app.admin.DevicePolicyManager;
-import androidx.lifecycle.LifecycleOwner;
import android.content.ComponentName;
import android.content.Context;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settings.widget.RestrictedAppPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
-import java.util.ArrayList;
-import java.util.List;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -52,6 +46,14 @@
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import java.util.ArrayList;
+import java.util.List;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+
@RunWith(SettingsRobolectricTestRunner.class)
@Config(
shadows = {
@@ -133,6 +135,8 @@
doReturn(preferences)
.when(mSettingsInjector).getInjectedSettings(any(Context.class), anyInt());
when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
+ ShadowUserManager.getShadow().setProfileIdsWithDisabled(new int[]{UserHandle.myUserId()});
+
mController.displayPreference(mScreen);
mController.updateState(mCategory);
@@ -143,6 +147,50 @@
}
@Test
+ public void workProfileDisallowShareLocationOn_getParentUserLocationServicesOnly() {
+ final int fakeWorkProfileId = 123;
+ ShadowUserManager.getShadow().setProfileIdsWithDisabled(
+ new int[]{UserHandle.myUserId(), fakeWorkProfileId});
+
+ // Mock RestrictedLockUtils.checkIfRestrictionEnforced and let it return non-null.
+ final List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
+ enforcingUsers.add(new UserManager.EnforcingUser(fakeWorkProfileId,
+ UserManager.RESTRICTION_SOURCE_DEVICE_OWNER));
+ final ComponentName componentName = new ComponentName("test", "test");
+ // Ensure that RestrictedLockUtils.checkIfRestrictionEnforced doesn't return null.
+ ShadowUserManager.getShadow().setUserRestrictionSources(
+ UserManager.DISALLOW_SHARE_LOCATION,
+ UserHandle.of(fakeWorkProfileId),
+ enforcingUsers);
+ when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(componentName);
+
+ mController.displayPreference(mScreen);
+ mController.updateState(mCategory);
+ verify(mSettingsInjector).getInjectedSettings(
+ any(Context.class), eq(UserHandle.myUserId()));
+ }
+
+ @Test
+ public void workProfileDisallowShareLocationOff_getAllUserLocationServices() {
+ final int fakeWorkProfileId = 123;
+ ShadowUserManager.getShadow().setProfileIdsWithDisabled(
+ new int[]{UserHandle.myUserId(), fakeWorkProfileId});
+
+ // Mock RestrictedLockUtils.checkIfRestrictionEnforced and let it return null.
+ // Empty enforcing users.
+ final List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
+ ShadowUserManager.getShadow().setUserRestrictionSources(
+ UserManager.DISALLOW_SHARE_LOCATION,
+ UserHandle.of(fakeWorkProfileId),
+ enforcingUsers);
+
+ mController.displayPreference(mScreen);
+ mController.updateState(mCategory);
+ verify(mSettingsInjector).getInjectedSettings(
+ any(Context.class), eq(UserHandle.USER_CURRENT));
+ }
+
+ @Test
public void onLocationModeChanged_shouldRequestReloadInjectedSettigns() {
mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
@@ -158,8 +206,9 @@
preferences.add(pref);
doReturn(preferences).when(mSettingsInjector)
.getInjectedSettings(any(Context.class), anyInt());
+ ShadowUserManager.getShadow().setProfileIdsWithDisabled(new int[]{UserHandle.myUserId()});
- int userId = UserHandle.myUserId();
+ final int userId = UserHandle.myUserId();
List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
enforcingUsers.add(new UserManager.EnforcingUser(userId,
UserManager.RESTRICTION_SOURCE_DEVICE_OWNER));
diff --git a/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
index a13946e..bdc7d69 100644
--- a/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/BlockPreferenceControllerTest.java
@@ -138,6 +138,7 @@
public void testIsAvailable_nonSystemApp() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = false;
+ appRow.lockedChannelId = "not this";
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java
index 7eeee98..38790b3 100644
--- a/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java
@@ -262,6 +262,34 @@
}
@Test
+ public void testIsChannelBlockable_notConfigurable() {
+ String sameId = "apples";
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = false;
+ appRow.lockedChannelId = sameId;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(sameId);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_DEFAULT);
+
+ mController.onResume(appRow, channel, null, null);
+ assertFalse(mController.isChannelBlockable());
+ }
+
+ @Test
+ public void testIsChannelBlockable_notConfigurableButBlocked() {
+ String sameId = "apples";
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.systemApp = false;
+ appRow.lockedChannelId = sameId;
+ NotificationChannel channel = mock(NotificationChannel.class);
+ when(channel.getId()).thenReturn(sameId);
+ when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
+
+ mController.onResume(appRow, channel, null, null);
+ assertTrue(mController.isChannelBlockable());
+ }
+
+ @Test
public void testIsChannelGroupBlockable_nonSystemBlockable() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = false;
diff --git a/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java b/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java
index e09dc0d..3ca9fda 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java
@@ -51,6 +51,7 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
public class ZenOnboardingActivityTest {
@@ -68,6 +69,8 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
mActivity = Robolectric.buildActivity(ZenOnboardingActivity.class)
.create()
@@ -124,6 +127,9 @@
@Test
public void isSuggestionComplete_zenUpdated() {
+ Policy policy = new Policy(0, 0, 0, 0);
+ when(mNm.getNotificationPolicy()).thenReturn(policy);
+
setZenUpdated(true);
setShowSettingsSuggestion(false);
setWithinTimeThreshold(true);
@@ -132,6 +138,9 @@
@Test
public void isSuggestionComplete_withinTimeThreshold() {
+ Policy policy = new Policy(0, 0, 0, 0);
+ when(mNm.getNotificationPolicy()).thenReturn(policy);
+
setZenUpdated(false);
setShowSettingsSuggestion(false);
setWithinTimeThreshold(true);
@@ -140,6 +149,9 @@
@Test
public void isSuggestionComplete_showSettingsSuggestionTrue() {
+ Policy policy = new Policy(0, 0, 0, 0);
+ when(mNm.getNotificationPolicy()).thenReturn(policy);
+
setZenUpdated(false);
setShowSettingsSuggestion(true);
setWithinTimeThreshold(false);
@@ -148,17 +160,33 @@
@Test
public void isSuggestionComplete_showSettingsSuggestionFalse_notWithinTimeThreshold() {
+ Policy policy = new Policy(0, 0, 0, 0);
+ when(mNm.getNotificationPolicy()).thenReturn(policy);
+
setZenUpdated(false);
setShowSettingsSuggestion(false);
setWithinTimeThreshold(false);
assertThat(isSuggestionComplete(mContext)).isTrue();
}
+
+ @Test
+ public void isSuggestionComplete_visualEffectsUpdated() {
+ // all values suppressed
+ Policy policy = new Policy(0, 0, 0, 511);
+ when(mNm.getNotificationPolicy()).thenReturn(policy);
+
+ setZenUpdated(false);
+ setShowSettingsSuggestion(true);
+ setWithinTimeThreshold(true);
+ assertThat(isSuggestionComplete(mContext)).isTrue();
+ assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.ZEN_SETTINGS_UPDATED, -1)).isEqualTo(1);
+ }
+
+
private void setZenUpdated(boolean updated) {
- int zenUpdated = 0;
- if (updated) {
- zenUpdated = 1;
- }
+ int zenUpdated = updated ? 1 : 0;
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.ZEN_SETTINGS_UPDATED, zenUpdated);
diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
index 6b1262a..c72e9f6 100644
--- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
@@ -33,10 +33,12 @@
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.StrictMode;
+import android.provider.Settings;
import android.provider.SettingsSlicesContract;
import android.util.ArraySet;
import com.android.settings.bluetooth.BluetoothSliceBuilder;
+import com.android.settings.flashlight.FlashlightSliceBuilder;
import com.android.settings.location.LocationSliceBuilder;
import com.android.settings.notification.ZenModeSliceBuilder;
import com.android.settings.testutils.DatabaseTestUtils;
@@ -95,7 +97,8 @@
);
private static final List<Uri> SPECIAL_CASE_OEM_URIS = Arrays.asList(
- ZenModeSliceBuilder.ZEN_MODE_URI
+ ZenModeSliceBuilder.ZEN_MODE_URI,
+ FlashlightSliceBuilder.FLASHLIGHT_URI
);
@Before
@@ -445,6 +448,16 @@
}
@Test
+ public void bindSlice_flashlightSlice_returnsFlashlightSlice() {
+ Settings.Secure.putInt(
+ mContext.getContentResolver(), Settings.Secure.FLASHLIGHT_AVAILABLE, 1);
+
+ final Slice flashlightSlice = mProvider.onBindSlice(FlashlightSliceBuilder.FLASHLIGHT_URI);
+
+ assertThat(flashlightSlice.getUri()).isEqualTo(FlashlightSliceBuilder.FLASHLIGHT_URI);
+ }
+
+ @Test
public void onSlicePinned_noIntentRegistered_specialCaseUri_doesNotCrash() {
final Uri uri = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
diff --git a/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java
index 56a5aa7..ebcf4c1 100644
--- a/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java
@@ -186,6 +186,8 @@
AudioSwitchPreferenceController controller = new AudioSwitchPreferenceControllerTestable(
mContext, TEST_KEY);
+ controller.onStart();
+ controller.onStop();
assertThat(mLocalBluetoothManager).isNull();
}
@@ -230,6 +232,7 @@
verify(mLocalBluetoothManager.getEventManager()).registerCallback(
any(BluetoothCallback.class));
verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class));
+ verify(mLocalBluetoothManager).setForegroundActivity(mContext);
}
@Test
@@ -240,6 +243,7 @@
verify(mLocalBluetoothManager.getEventManager()).unregisterCallback(
any(BluetoothCallback.class));
verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
+ verify(mLocalBluetoothManager).setForegroundActivity(null);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java b/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
index f071f17..0b29af5 100644
--- a/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
+++ b/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
@@ -84,9 +84,9 @@
paths.add(new ResourcePath(null,
Fs.fromURL(new URL("file:frameworks/opt/setupwizard/library/recyclerview/res")), null));
paths.add(new ResourcePath(null,
- Fs.fromURL(new URL("file:frameworks/support/v7/appcompat/res")), null));
+ Fs.fromURL(new URL("file:frameworks/support/appcompat/res")), null));
paths.add(new ResourcePath(null,
- Fs.fromURL(new URL("file:frameworks/support/v7/cardview/res")), null));
+ Fs.fromURL(new URL("file:frameworks/support/cardview/res")), null));
} catch (MalformedURLException e) {
throw new RuntimeException("SettingsRobolectricTestRunner failure", e);
}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContentResolver.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContentResolver.java
index 50c0330..928779b 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContentResolver.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContentResolver.java
@@ -24,6 +24,7 @@
import android.database.MatrixCursor;
import android.net.Uri;
import android.provider.SearchIndexablesContract;
+import android.text.TextUtils;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.Resetter;
@@ -67,6 +68,14 @@
}
@Implementation
+ public static void setSyncAutomaticallyAsUser(Account account, String authority, boolean sync,
+ int userId) {
+ if (TextUtils.isEmpty(authority)) {
+ throw new IllegalArgumentException("Authority must be non-empty");
+ }
+ }
+
+ @Implementation
public static boolean getMasterSyncAutomaticallyAsUser(int userId) {
return sMasterSyncAutomatically.containsKey(userId)
? sMasterSyncAutomatically.get(userId) : true;
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
index d83c814..df87536 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
@@ -30,6 +30,7 @@
import org.robolectric.shadow.api.Shadow;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -45,6 +46,7 @@
private final List<UserInfo> mUserProfileInfos = new ArrayList<>();
private final Set<Integer> mManagedProfiles = new HashSet<>();
private boolean mIsQuietModeEnabled = false;
+ private int[] profileIdsForUser;
@Resetter
public void reset() {
@@ -96,7 +98,11 @@
@Implementation
public List<EnforcingUser> getUserRestrictionSources(
String restrictionKey, UserHandle userHandle) {
- return mRestrictionSources.get(restrictionKey + userHandle.getIdentifier());
+ // Return empty list when there is no enforcing user, otherwise might trigger
+ // NullPointer Exception in RestrictedLockUtils.checkIfRestrictionEnforced.
+ List<EnforcingUser> enforcingUsers =
+ mRestrictionSources.get(restrictionKey + userHandle.getIdentifier());
+ return enforcingUsers == null ? Collections.emptyList() : enforcingUsers;
}
public void setUserRestrictionSources(
@@ -121,4 +127,13 @@
public void setQuietModeEnabled(boolean enabled) {
mIsQuietModeEnabled = enabled;
}
+
+ @Implementation
+ public int[] getProfileIdsWithDisabled(@UserIdInt int userId) {
+ return profileIdsForUser;
+ }
+
+ public void setProfileIdsWithDisabled(int[] profileIds) {
+ profileIdsForUser = profileIds;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/widget/HotspotApBandSelectionPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/HotspotApBandSelectionPreferenceTest.java
deleted file mode 100644
index 0ffda3b..0000000
--- a/tests/robotests/src/com/android/settings/widget/HotspotApBandSelectionPreferenceTest.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.widget;
-
-import static com.android.settingslib.CustomDialogPreference.CustomPreferenceDialogFragment;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.net.wifi.WifiConfiguration;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.LinearLayout;
-
-import com.android.settings.R;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.util.ReflectionHelpers;
-
-import java.util.List;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-public class HotspotApBandSelectionPreferenceTest {
- private HotspotApBandSelectionPreference mPreference;
- private Context mContext;
- private Button mSaveButton;
- private View mLayout;
-
- @Before
- public void setUp() {
- mContext = RuntimeEnvironment.application;
- mSaveButton = spy(new Button(mContext));
-
- final CustomPreferenceDialogFragment fragment = mock(CustomPreferenceDialogFragment.class);
- final AlertDialog dialog = mock(AlertDialog.class);
- when(fragment.getDialog()).thenReturn(dialog);
- when(dialog.getButton(anyInt())).thenReturn(mSaveButton);
-
- mPreference = new HotspotApBandSelectionPreference(mContext);
- ReflectionHelpers.setField(mPreference, "mFragment", fragment);
-
- final LayoutInflater inflater = LayoutInflater.from(mContext);
- mLayout = inflater.inflate(R.layout.hotspot_ap_band_selection_dialog,
- new LinearLayout(mContext), false);
- }
-
- @Test
- public void getWifiBand_updatesBandPresetConfigProvided() {
- mPreference.setExistingConfigValue(WifiConfiguration.AP_BAND_ANY);
- mPreference.onBindDialogView(mLayout);
-
- // check that the boxes are set correctly when a pre-existing config is set
- assertThat(mPreference.getWifiBand()).isEqualTo(WifiConfiguration.AP_BAND_ANY);
- }
-
- @Test
- public void getWifiBand_updatesBandWhenBoxesToggled() {
- mPreference.setExistingConfigValue(WifiConfiguration.AP_BAND_ANY);
- mPreference.onBindDialogView(mLayout);
-
- assertThat(mPreference.getWifiBand()).isEqualTo(WifiConfiguration.AP_BAND_ANY);
-
- // make sure we have the expected box then toggle it
- mPreference.mBox2G.setChecked(false);
-
- // check that band is updated
- assertThat(mPreference.getWifiBand()).isEqualTo(WifiConfiguration.AP_BAND_5GHZ);
- }
-
- @Test
- public void onSaveInstanceState_skipWhenDialogGone() {
- mPreference.setExistingConfigValue(WifiConfiguration.AP_BAND_2GHZ);
- mPreference.onBindDialogView(mLayout);
- // remove the fragment to make the dialog unavailable
- ReflectionHelpers.setField(mPreference, "mFragment", null);
-
- mPreference.setExistingConfigValue(WifiConfiguration.AP_BAND_ANY);
- mPreference.onBindDialogView(mLayout);
-
- // state should only be saved when the dialog is available
- Parcelable parcelable = mPreference.onSaveInstanceState();
- mPreference.onRestoreInstanceState(parcelable);
- assertThat(mPreference.mShouldRestore).isFalse();
- }
-
- @Test
- public void onSaveInstanceState_doesNotCrashWhenViewGone() {
- mPreference.setExistingConfigValue(WifiConfiguration.AP_BAND_2GHZ);
- mPreference.onBindDialogView(mLayout);
- // When the device dozes the view and dialog can become null
- mPreference.mBox5G = null;
- mPreference.mBox2G = null;
- ReflectionHelpers.setField(mPreference, "mFragment", null);
-
- // make sure it does not crash and state is not restored
- Parcelable parcelable = mPreference.onSaveInstanceState();
- mPreference.onRestoreInstanceState(parcelable);
- assertThat(mPreference.mShouldRestore).isFalse();
- }
-
- @Test
- public void onSaveInstanceState_presentWhenDialogPresent() {
- mPreference.setExistingConfigValue(WifiConfiguration.AP_BAND_2GHZ);
- mPreference.onBindDialogView(mLayout);
-
- Parcelable parcelable = mPreference.onSaveInstanceState();
- mPreference.onRestoreInstanceState(parcelable);
- assertThat(mPreference.mShouldRestore).isTrue();
- }
-
- @Test
- public void positiveButton_updatedCorrectly() {
- mPreference.setExistingConfigValue(WifiConfiguration.AP_BAND_ANY);
- mPreference.onBindDialogView(mLayout);
-
- // button is enabled whole time so far since we have a pre-existing selection
- verify(mSaveButton, never()).setEnabled(false);
-
- // clear all boxes and make sure it stays enabled until empty
- mPreference.mBox2G.setChecked(false);
- mPreference.mBox5G.setChecked(false);
-
- // button should be disabled now
- verify(mSaveButton, times(1)).setEnabled(false);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java b/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java
index 1f49654..806399d 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java
@@ -29,7 +29,7 @@
@Test
public void testSSID() {
assertThat(WifiUtils.isSSIDTooLong("123")).isFalse();
- assertThat(WifiUtils.isSSIDTooLong("☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎")).isTrue();
+ assertThat(WifiUtils.isSSIDTooLong("☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎")).isTrue();
assertThat(WifiUtils.isSSIDTooShort("123")).isFalse();
assertThat(WifiUtils.isSSIDTooShort("")).isTrue();
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java
index 4b81b34..4b2aa1c 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java
@@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -26,16 +27,16 @@
import android.net.ConnectivityManager;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
+
+import androidx.preference.ListPreference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.widget.HotspotApBandSelectionPreference;
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;
@@ -43,8 +44,9 @@
@RunWith(SettingsRobolectricTestRunner.class)
public class WifiTetherApBandPreferenceControllerTest {
- private static final String ALL_BANDS = "2.4 GHz and 5.0 GHz";
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private static final String ALL_BANDS = "5.0 GHz Band preferred";
+ private static final String TWO_GHZ_STRING = "2.4 GHz Band";
+ private static final String FIVE_GHZ_STRING = "5.0 GHz Band";
private Context mContext;
@Mock
private ConnectivityManager mConnectivityManager;
@@ -56,12 +58,13 @@
private PreferenceScreen mScreen;
private WifiTetherApBandPreferenceController mController;
- private HotspotApBandSelectionPreference mPreference;
+ private ListPreference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mPreference = new HotspotApBandSelectionPreference(RuntimeEnvironment.application);
+ mContext = spy(RuntimeEnvironment.application);
+ mPreference = new ListPreference(RuntimeEnvironment.application);
when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
.thenReturn(mConnectivityManager);
@@ -71,6 +74,7 @@
WifiConfiguration config = new WifiConfiguration();
config.apBand = WifiConfiguration.AP_BAND_ANY;
when(mWifiManager.getWifiApConfiguration()).thenReturn(new WifiConfiguration());
+ when(mWifiManager.isDualModeSupported()).thenReturn(false);
mController = new WifiTetherApBandPreferenceController(mContext, mListener);
}
@@ -79,9 +83,10 @@
public void display_5GhzSupported_shouldDisplayFullList() {
when(mWifiManager.getCountryCode()).thenReturn("US");
when(mWifiManager.isDualBandSupported()).thenReturn(true);
+ when(mWifiManager.isDualModeSupported()).thenReturn(true);
mController.displayPreference(mScreen);
- mController.onPreferenceChange(mPreference, -1);
+ mController.onPreferenceChange(mPreference, "-1");
assertThat(mPreference.getSummary()).isEqualTo(ALL_BANDS);
}
@@ -110,24 +115,54 @@
}
@Test
- public void changePreference_shouldUpdateValue() {
+ public void changePreference_noDualModeWith5G_shouldUpdateValue() {
when(mWifiManager.is5GHzBandSupported()).thenReturn(true);
mController.displayPreference(mScreen);
+ // -1 is WifiConfiguration.AP_BAND_ANY, for 'Auto' option. This should be prevented from
+ // being set since it is invalid for this configuration
+ mController.onPreferenceChange(mPreference, "-1");
+ assertThat(mController.getBandIndex()).isEqualTo(1);
+ assertThat(mPreference.getSummary()).isEqualTo(FIVE_GHZ_STRING);
+ verify(mListener, times(1)).onTetherConfigUpdated();
+
+ // set to 5 Ghz
+ mController.onPreferenceChange(mPreference, "1");
+ assertThat(mController.getBandIndex()).isEqualTo(1);
+ assertThat(mPreference.getSummary()).isEqualTo(FIVE_GHZ_STRING);
+ verify(mListener, times(2)).onTetherConfigUpdated();
+
+ // set to 2 Ghz
+ mController.onPreferenceChange(mPreference, "0");
+ assertThat(mController.getBandIndex()).isEqualTo(0);
+ assertThat(mPreference.getSummary()).isEqualTo(TWO_GHZ_STRING);
+ verify(mListener, times(3)).onTetherConfigUpdated();
+ }
+
+ @Test
+ public void changePreference_dualModeWith5G_shouldUpdateValue() {
+ when(mWifiManager.is5GHzBandSupported()).thenReturn(true);
+ when(mWifiManager.isDualModeSupported()).thenReturn(true);
+
+ mController.displayPreference(mScreen);
+
// -1 is WifiConfiguration.AP_BAND_ANY, for 'Auto' option.
- mController.onPreferenceChange(mPreference, -1);
+ mController.onPreferenceChange(mPreference, "-1");
assertThat(mController.getBandIndex()).isEqualTo(-1);
assertThat(mPreference.getSummary()).isEqualTo(ALL_BANDS);
+ verify(mListener, times(1)).onTetherConfigUpdated();
- mController.onPreferenceChange(mPreference, 1);
- assertThat(mController.getBandIndex()).isEqualTo(1);
- assertThat(mPreference.getSummary()).isEqualTo("5.0 GHz");
+ // should revert to the default for 5 Ghz only since this is not supported with this config
+ mController.onPreferenceChange(mPreference, "1");
+ assertThat(mController.getBandIndex()).isEqualTo(-1);
+ assertThat(mPreference.getSummary()).isEqualTo(ALL_BANDS);
+ verify(mListener, times(2)).onTetherConfigUpdated();
- mController.onPreferenceChange(mPreference, 0);
+ // set to 2 Ghz
+ mController.onPreferenceChange(mPreference, "0");
assertThat(mController.getBandIndex()).isEqualTo(0);
- assertThat(mPreference.getSummary()).isEqualTo("2.4 GHz");
-
+ assertThat(mPreference.getSummary()).isEqualTo(TWO_GHZ_STRING);
verify(mListener, times(3)).onTetherConfigUpdated();
}
@@ -136,7 +171,7 @@
// Set controller band index to 1 and verify is set.
when(mWifiManager.is5GHzBandSupported()).thenReturn(true);
mController.displayPreference(mScreen);
- mController.onPreferenceChange(mPreference, 1);
+ mController.onPreferenceChange(mPreference, "1");
assertThat(mController.getBandIndex()).isEqualTo(1);
// Disable 5Ghz band