Snap for 9754537 from 5b5da43ef8
to udc-release
Change-Id: I6e42b7caf0be232206900c179f44174d663c9d7b
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
android:id="@+id/panel_container"
|
||||
android:layout_width="@dimen/settings_panel_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:background="@drawable/settings_panel_rounded_top_corner_background" >
|
||||
|
||||
|
@@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2020 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<RelativeLayout android:id="@+id/zen_mode_settings_senders_overlay_view"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/zen_conversations_image_margin_vertical"
|
||||
android:layout_marginBottom="@dimen/zen_conversations_image_margin_vertical">
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
@@ -51,9 +51,6 @@
|
||||
<dimen name="conversation_icon_size">32dp</dimen>
|
||||
|
||||
<dimen name="zen_mode_settings_button_margin_vertical">24dp</dimen>
|
||||
<dimen name="zen_conversations_image_margin_vertical">24dp</dimen>
|
||||
<dimen name="zen_conversations_icon_offset">32dp</dimen>
|
||||
<dimen name="zen_conversations_icon_size">50dp</dimen>
|
||||
<dimen name="zen_schedule_rule_checkbox_padding">7dp</dimen>
|
||||
<dimen name="zen_schedule_day_margin">17dp</dimen>
|
||||
|
||||
|
@@ -8177,8 +8177,6 @@
|
||||
|
||||
<!-- [CHAR LIMIT=120] Zen mode settings: Title for conversations settings page -->
|
||||
<string name="zen_mode_conversations_title">Conversations</string>
|
||||
<!-- [CHAR LIMIT=120] Zen mode settings: Header for conversations settings page -->
|
||||
<string name="zen_mode_conversations_section_title">Conversations that can interrupt</string>
|
||||
<string name="zen_mode_from_all_conversations">All conversations</string>
|
||||
<string name="zen_mode_from_important_conversations">Priority conversations</string>
|
||||
<!-- [CHAR LIMIT=40] Version of the above for "priority conversations" when it is a non-first member of a list -->
|
||||
@@ -11698,6 +11696,10 @@
|
||||
<string name="dream_complications_toggle_title">Show additional information</string>
|
||||
<!-- The summary of what overlays this toggle controls [CHAR LIMIT=none] -->
|
||||
<string name="dream_complications_toggle_summary">Display things like the time, weather, or other information on the screen saver</string>
|
||||
<!-- The title of the toggle which enables/disables the home controls button on top of the screen saver [CHAR LIMIT=none] -->
|
||||
<string name="dream_home_controls_toggle_title">Show home controls</string>
|
||||
<!-- The summary of the home controls toggle [CHAR LIMIT=none] -->
|
||||
<string name="dream_home_controls_toggle_summary">Show home controls button from the screen saver</string>
|
||||
<!-- The title of the category to show for the screensaver miscellaneous settings [CHAR LIMIT=none] -->
|
||||
<string name="dream_more_settings_category">More settings</string>
|
||||
<!-- The title of the screen saver setup page [CHAR LIMIT=none] -->
|
||||
|
@@ -220,6 +220,7 @@
|
||||
<!-- Note that Dialog themes do not set list dividers -->
|
||||
<style name="Theme.Panel" parent="@*android:style/Theme.DeviceDefault.Settings.Dialog">
|
||||
<item name="android:windowBackground">@null</item>
|
||||
<item name="android:windowTranslucentNavigation">true</item>
|
||||
<item name="android:dividerHorizontal">@*android:drawable/list_divider_material</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:listDivider">@*android:drawable/list_divider_material</item>
|
||||
|
@@ -26,17 +26,15 @@
|
||||
<com.android.settings.widget.SettingsMainSwitchPreference
|
||||
android:key="block" />
|
||||
|
||||
<com.android.settingslib.widget.FooterPreference
|
||||
<Preference
|
||||
android:key="block_desc" />
|
||||
|
||||
|
||||
<!-- Conversations added here -->
|
||||
<PreferenceCategory
|
||||
android:title="@string/conversations_category_title"
|
||||
android:key="conversations"
|
||||
android:visibility="gone"
|
||||
settings:allowDividerAbove="false"
|
||||
settings:allowDividerBelow="false">
|
||||
android:visibility="gone">
|
||||
|
||||
</PreferenceCategory>
|
||||
<com.android.settingslib.RestrictedSwitchPreference
|
||||
android:key="invalid_conversation_switch"
|
||||
@@ -49,25 +47,13 @@
|
||||
android:key="bubble_pref_link"
|
||||
android:title="@string/notification_bubbles_title"
|
||||
android:icon="@drawable/ic_create_bubble"
|
||||
settings:allowDividerAbove="false"
|
||||
settings:controller="com.android.settings.notification.app.BubbleSummaryPreferenceController">
|
||||
</Preference>
|
||||
|
||||
<!-- Channels/Channel groups added here -->
|
||||
<PreferenceCategory
|
||||
android:key="channels"
|
||||
android:layout="@layout/empty_view"
|
||||
settings:allowDividerAbove="true"
|
||||
settings:allowDividerBelow="true" />
|
||||
|
||||
<!-- Show badge -->
|
||||
<com.android.settingslib.RestrictedSwitchPreference
|
||||
android:key="badge"
|
||||
android:title="@string/notification_badge_title"
|
||||
settings:useAdditionalSummary="true"
|
||||
android:order="1001"
|
||||
settings:allowDividerAbove="true"
|
||||
settings:restrictedSwitchSummary="@string/enabled_by_admin" />
|
||||
android:layout="@layout/empty_view" />
|
||||
|
||||
<!-- Importance toggle -->
|
||||
<com.android.settingslib.RestrictedSwitchPreference
|
||||
@@ -86,18 +72,25 @@
|
||||
android:title="@string/app_notification_override_dnd_title"
|
||||
android:summary="@string/app_notification_override_dnd_summary"/>
|
||||
|
||||
<Preference
|
||||
android:key="app_link"
|
||||
android:order="1003"
|
||||
android:icon="@drawable/ic_settings_24dp"
|
||||
android:title="@string/app_settings_link" />
|
||||
<!-- Show badge -->
|
||||
<com.android.settingslib.RestrictedSwitchPreference
|
||||
android:key="badge"
|
||||
android:title="@string/notification_badge_title"
|
||||
settings:useAdditionalSummary="true"
|
||||
android:order="1001"
|
||||
android:icon="@drawable/ic_notification_dot"
|
||||
settings:allowDividerAbove="true"
|
||||
settings:restrictedSwitchSummary="@string/enabled_by_admin" />
|
||||
|
||||
<com.android.settingslib.widget.FooterPreference
|
||||
android:key="desc"
|
||||
android:order="5000" />
|
||||
<Preference
|
||||
android:key="app_link"
|
||||
android:order="1003"
|
||||
android:icon="@drawable/ic_settings_24dp"
|
||||
android:title="@string/app_settings_link" />
|
||||
|
||||
<com.android.settingslib.widget.FooterPreference
|
||||
android:key="deleted"
|
||||
android:icon="@drawable/ic_trash_can"
|
||||
android:order="8000" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
@@ -46,6 +46,12 @@
|
||||
android:summary="@string/dream_complications_toggle_summary"
|
||||
settings:controller="com.android.settings.dream.DreamComplicationPreferenceController"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="dream_home_controls_toggle"
|
||||
android:title="@string/dream_home_controls_toggle_title"
|
||||
android:summary="@string/dream_home_controls_toggle_summary"
|
||||
settings:controller="com.android.settings.dream.DreamHomeControlsPreferenceController"/>
|
||||
|
||||
<com.android.settings.applications.SpacePreference
|
||||
android:layout_height="16dp" />
|
||||
|
||||
|
@@ -37,5 +37,13 @@
|
||||
android:name="classname"
|
||||
android:value="com.android.settings.applications.appinfo.AppLocaleDetails" />
|
||||
</Preference>
|
||||
|
||||
<Preference
|
||||
android:key="regional_preferences"
|
||||
android:title="@string/regional_preferences_title"
|
||||
android:summary="@string/regional_preferences_summary"
|
||||
android:fragment="com.android.settings.regionalpreferences.RegionalPreferencesEntriesFragment"
|
||||
settings:controller="com.android.settings.regionalpreferences.RegionalPreferencesController" />
|
||||
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2020 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:key="zen_mode_conversations_settings"
|
||||
android:title="@string/zen_mode_conversations_title">
|
||||
<!-- Conversations -->
|
||||
<PreferenceCategory
|
||||
android:key="zen_mode_conversations_radio_buttons"
|
||||
android:title="@string/zen_mode_conversations_section_title">
|
||||
|
||||
<!-- Senders image -->
|
||||
<com.android.settingslib.widget.LayoutPreference
|
||||
android:key="zen_mode_conversations_image"
|
||||
android:layout="@layout/zen_mode_senders_overlay_image"
|
||||
android:selectable="false"/>
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
@@ -18,6 +18,7 @@ package com.android.settings.accessibility;
|
||||
|
||||
import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
@@ -72,8 +73,7 @@ public class AccessibilityHearingAidsFragment extends AccessibilityShortcutPrefe
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
// TODO(b/262839191): To be updated settings_enums.proto
|
||||
return 0;
|
||||
return SettingsEnums.ACCESSIBILITY_HEARING_AID_SETTINGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -41,8 +42,7 @@ public class FlashNotificationsPreferenceFragment extends DashboardFragment {
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
// TODO: Flash notifications have to add SettingsEnums.
|
||||
return 0;
|
||||
return SettingsEnums.FLASH_NOTIFICATION_SETTINGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothUuid;
|
||||
import android.bluetooth.le.ScanFilter;
|
||||
@@ -61,8 +62,7 @@ public class HearingDevicePairingDetail extends BluetoothDevicePairingDetailBase
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
// TODO(b/262839191): To be updated settings_enums.proto
|
||||
return 0;
|
||||
return SettingsEnums.HEARING_AID_PAIRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -24,7 +24,9 @@ import android.app.Dialog;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.credentials.CredentialManager;
|
||||
import android.credentials.CredentialProviderInfo;
|
||||
import android.credentials.SetEnabledProvidersException;
|
||||
@@ -32,6 +34,7 @@ import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.OutcomeReceiver;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.IconDrawableFactory;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -162,10 +165,54 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
|
||||
PreferenceGroup group = screen.findPreference(getPreferenceKey());
|
||||
Context context = screen.getContext();
|
||||
mPrefs.putAll(buildPreferenceList(context, group));
|
||||
}
|
||||
|
||||
for (CredentialProviderInfo service : mServices) {
|
||||
group.addPreference(createPreference(context, service));
|
||||
/** Aggregates the list of services and builds a list of UI prefs to show. */
|
||||
@VisibleForTesting
|
||||
public Map<String, SwitchPreference> buildPreferenceList(
|
||||
Context context, PreferenceGroup group) {
|
||||
// Group the services by package name.
|
||||
Map<String, List<CredentialProviderInfo>> groupedInfos = new HashMap<>();
|
||||
for (CredentialProviderInfo cpi : mServices) {
|
||||
String packageName = cpi.getServiceInfo().packageName;
|
||||
if (!groupedInfos.containsKey(packageName)) {
|
||||
groupedInfos.put(packageName, new ArrayList<>());
|
||||
}
|
||||
|
||||
groupedInfos.get(packageName).add(cpi);
|
||||
}
|
||||
|
||||
// Build the pref list.
|
||||
Map<String, SwitchPreference> output = new HashMap<>();
|
||||
for (String packageName : groupedInfos.keySet()) {
|
||||
List<CredentialProviderInfo> infos = groupedInfos.get(packageName);
|
||||
CredentialProviderInfo firstInfo = infos.get(0);
|
||||
ServiceInfo firstServiceInfo = firstInfo.getServiceInfo();
|
||||
CharSequence title = firstInfo.getLabel(context);
|
||||
Drawable icon = firstInfo.getServiceIcon(context);
|
||||
|
||||
if (infos.size() > 1) {
|
||||
// If there is more than one then group them under the package.
|
||||
ApplicationInfo appInfo = firstServiceInfo.applicationInfo;
|
||||
if (appInfo.nonLocalizedLabel != null) {
|
||||
title = appInfo.loadLabel(mPm);
|
||||
}
|
||||
icon = mIconFactory.getBadgedIcon(appInfo, getUser());
|
||||
}
|
||||
|
||||
// If there is no title then don't show anything.
|
||||
if (TextUtils.isEmpty(title)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Build the pref and add it to the output & group.
|
||||
SwitchPreference pref = addProviderPreference(context, title, icon, packageName);
|
||||
output.put(packageName, pref);
|
||||
group.addPreference(pref);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/** Creates a preference object based on the provider info. */
|
||||
@@ -238,7 +285,6 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
final SwitchPreference pref = new SwitchPreference(prefContext);
|
||||
pref.setTitle(title);
|
||||
pref.setChecked(mEnabledPackageNames.contains(packageName));
|
||||
mPrefs.put(packageName, pref);
|
||||
|
||||
if (icon != null) {
|
||||
pref.setIcon(Utils.getSafeIcon(icon));
|
||||
|
@@ -20,6 +20,7 @@ import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
|
||||
|
||||
import static com.android.settings.bluetooth.BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
@@ -32,10 +33,8 @@ import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
|
||||
/** Settings fragment containing bluetooth audio routing. */
|
||||
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
|
||||
public class BluetoothDetailsAudioRoutingFragment extends RestrictedDashboardFragment {
|
||||
|
||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
@@ -73,8 +72,7 @@ public class BluetoothDetailsAudioRoutingFragment extends RestrictedDashboardFra
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
// TODO(b/262839191): To be updated settings_enums.proto
|
||||
return 0;
|
||||
return SettingsEnums.BLUETOOTH_AUDIO_ROUTING;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.dream;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
import com.android.settingslib.dream.DreamBackend;
|
||||
|
||||
/**
|
||||
* Controller for the {@link androidx.preference.SwitchPreference} which controls if dream
|
||||
* overlays should be enabled.
|
||||
*/
|
||||
public class DreamHomeControlsPreferenceController extends TogglePreferenceController {
|
||||
private final DreamBackend mBackend;
|
||||
|
||||
public DreamHomeControlsPreferenceController(Context context, String key) {
|
||||
this(context, key, DreamBackend.getInstance(context));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public DreamHomeControlsPreferenceController(Context context, String key,
|
||||
DreamBackend dreamBackend) {
|
||||
super(context, key);
|
||||
mBackend = dreamBackend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
final boolean supported =
|
||||
mBackend.getSupportedComplications()
|
||||
.contains(DreamBackend.COMPLICATION_TYPE_HOME_CONTROLS);
|
||||
return supported ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return mBackend.getEnabledComplications().contains(
|
||||
DreamBackend.COMPLICATION_TYPE_HOME_CONTROLS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setChecked(boolean isChecked) {
|
||||
mBackend.setHomeControlsEnabled(isChecked);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSliceHighlightMenuRes() {
|
||||
return R.string.menu_key_display;
|
||||
}
|
||||
}
|
@@ -37,10 +37,10 @@ import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.inputmethod.NewKeyboardSettingsUtils.KeyboardInfo;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
|
||||
implements InputManager.InputDeviceListener {
|
||||
@@ -53,7 +53,7 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
|
||||
private int mUserId;
|
||||
private int mInputDeviceId;
|
||||
private Context mContext;
|
||||
private Map<String, KeyboardInfo> mKeyboardLanguageLayouts = new HashMap<>();
|
||||
private ArrayList<KeyboardInfo> mKeyboardInfoList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle icicle) {
|
||||
@@ -74,8 +74,16 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
|
||||
PreferenceScreen preferenceScreen = getPreferenceScreen();
|
||||
preferenceScreen.removeAll();
|
||||
List<InputMethodInfo> infoList = mImm.getEnabledInputMethodListAsUser(mUserId);
|
||||
Collections.sort(infoList, new Comparator<InputMethodInfo>() {
|
||||
public int compare(InputMethodInfo o1, InputMethodInfo o2) {
|
||||
String s1 = o1.loadLabel(mContext.getPackageManager()).toString();
|
||||
String s2 = o2.loadLabel(mContext.getPackageManager()).toString();
|
||||
return s1.compareTo(s2);
|
||||
}
|
||||
});
|
||||
|
||||
for (InputMethodInfo info : infoList) {
|
||||
mKeyboardLanguageLayouts.clear();
|
||||
mKeyboardInfoList.clear();
|
||||
List<InputMethodSubtype> subtypes =
|
||||
mImm.getEnabledInputMethodSubtypeList(info, true);
|
||||
for (InputMethodSubtype subtype : subtypes) {
|
||||
@@ -88,51 +96,58 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
|
||||
}
|
||||
|
||||
private void mapLanguageWithLayout(InputMethodInfo info, InputMethodSubtype subtype) {
|
||||
CharSequence subtypeLabel = getSubtypeLabel(mContext, info, subtype);
|
||||
KeyboardLayout[] keyboardLayouts = getKeyboardLayouts(info, subtype);
|
||||
String layout = getKeyboardLayout(info, subtype);
|
||||
String language = getLanguage(info, subtype);
|
||||
|
||||
if (layout != null) {
|
||||
for (int i = 0; i < keyboardLayouts.length; i++) {
|
||||
if (keyboardLayouts[i].getDescriptor().equals(layout)) {
|
||||
KeyboardInfo keyboardInfo = new KeyboardInfo(
|
||||
language,
|
||||
subtypeLabel,
|
||||
keyboardLayouts[i].getLabel(),
|
||||
info,
|
||||
subtype);
|
||||
mKeyboardLanguageLayouts.put(subtype.getLanguageTag(), keyboardInfo);
|
||||
mKeyboardInfoList.add(keyboardInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if there is no auto-selected layout, we should show "Default"
|
||||
KeyboardInfo keyboardInfo = new KeyboardInfo(
|
||||
language,
|
||||
subtypeLabel,
|
||||
mContext.getString(R.string.keyboard_default_layout),
|
||||
info,
|
||||
subtype);
|
||||
mKeyboardLanguageLayouts.put(subtype.getLanguageTag(), keyboardInfo);
|
||||
mKeyboardInfoList.add(keyboardInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePreferenceLayout(PreferenceScreen preferenceScreen, InputMethodInfo info) {
|
||||
if (mKeyboardLanguageLayouts.isEmpty()) {
|
||||
if (mKeyboardInfoList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
PreferenceCategory preferenceCategory = new PreferenceCategory(mContext);
|
||||
preferenceCategory.setTitle(info.loadLabel(mContext.getPackageManager()).toString());
|
||||
preferenceCategory.setTitle(info.loadLabel(mContext.getPackageManager()));
|
||||
preferenceCategory.setKey(info.getPackageName());
|
||||
preferenceScreen.addPreference(preferenceCategory);
|
||||
for (Map.Entry<String, KeyboardInfo> entry : mKeyboardLanguageLayouts.entrySet()) {
|
||||
Collections.sort(mKeyboardInfoList, new Comparator<KeyboardInfo>() {
|
||||
public int compare(KeyboardInfo o1, KeyboardInfo o2) {
|
||||
String s1 = o1.getSubtypeLabel().toString();
|
||||
String s2 = o2.getSubtypeLabel().toString();
|
||||
return s1.compareTo(s2);
|
||||
}
|
||||
});
|
||||
|
||||
for (KeyboardInfo keyboardInfo : mKeyboardInfoList) {
|
||||
final Preference pref = new Preference(mContext);
|
||||
String key = "keyboard_language_" + entry.getKey();
|
||||
NewKeyboardSettingsUtils.KeyboardInfo keyboardInfo = entry.getValue();
|
||||
pref.setKey(key);
|
||||
pref.setTitle(keyboardInfo.getLanguage());
|
||||
pref.setKey(keyboardInfo.getPrefId());
|
||||
pref.setTitle(keyboardInfo.getSubtypeLabel());
|
||||
pref.setSummary(keyboardInfo.getLayout());
|
||||
pref.setOnPreferenceClickListener(
|
||||
preference -> {
|
||||
showKeyboardLayoutPicker(
|
||||
keyboardInfo.getLanguage(),
|
||||
keyboardInfo.getSubtypeLabel(),
|
||||
keyboardInfo.getLayout(),
|
||||
mInputDeviceIdentifier,
|
||||
mUserId,
|
||||
@@ -215,7 +230,7 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
|
||||
}
|
||||
|
||||
private void showKeyboardLayoutPicker(
|
||||
String language,
|
||||
CharSequence subtypeLabel,
|
||||
String layout,
|
||||
InputDeviceIdentifier inputDeviceIdentifier,
|
||||
int userId,
|
||||
@@ -229,7 +244,7 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
|
||||
arguments.putParcelable(
|
||||
NewKeyboardSettingsUtils.EXTRA_INPUT_METHOD_SUBTYPE, inputMethodSubtype);
|
||||
arguments.putInt(NewKeyboardSettingsUtils.EXTRA_USER_ID, userId);
|
||||
arguments.putString(NewKeyboardSettingsUtils.EXTRA_TITLE, language);
|
||||
arguments.putCharSequence(NewKeyboardSettingsUtils.EXTRA_TITLE, subtypeLabel);
|
||||
arguments.putString(NewKeyboardSettingsUtils.EXTRA_KEYBOARD_LAYOUT, layout);
|
||||
new SubSettingLauncher(mContext)
|
||||
.setSourceMetricsCategory(getMetricsCategory())
|
||||
@@ -248,16 +263,9 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
|
||||
mInputDeviceIdentifier, mUserId, info, subtype);
|
||||
}
|
||||
|
||||
private String getLanguage(InputMethodInfo info, InputMethodSubtype subtype) {
|
||||
String language;
|
||||
if (subtype.getLanguageTag().isEmpty()) {
|
||||
language = subtype.getDisplayName(
|
||||
mContext,
|
||||
info.getPackageName(),
|
||||
info.getServiceInfo().applicationInfo).toString();
|
||||
} else {
|
||||
language = Locale.forLanguageTag(subtype.getLanguageTag()).getDisplayName();
|
||||
}
|
||||
return language;
|
||||
private CharSequence getSubtypeLabel(
|
||||
Context context, InputMethodInfo info, InputMethodSubtype subtype) {
|
||||
return subtype.getDisplayName(
|
||||
context, info.getPackageName(), info.getServiceInfo().applicationInfo);
|
||||
}
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@ public class NewKeyboardLayoutPickerContent extends DashboardFragment {
|
||||
super.onAttach(context);
|
||||
InputManager inputManager = getContext().getSystemService(InputManager.class);
|
||||
Bundle arguments = getArguments();
|
||||
final String title = arguments.getString(NewKeyboardSettingsUtils.EXTRA_TITLE);
|
||||
final CharSequence title = arguments.getCharSequence(NewKeyboardSettingsUtils.EXTRA_TITLE);
|
||||
final String layout = arguments.getString(NewKeyboardSettingsUtils.EXTRA_KEYBOARD_LAYOUT);
|
||||
final int userId = arguments.getInt(NewKeyboardSettingsUtils.EXTRA_USER_ID);
|
||||
final InputDeviceIdentifier identifier =
|
||||
|
@@ -72,24 +72,28 @@ public class NewKeyboardSettingsUtils {
|
||||
}
|
||||
|
||||
static class KeyboardInfo {
|
||||
String mLanguage;
|
||||
CharSequence mSubtypeLabel;
|
||||
String mLayout;
|
||||
InputMethodInfo mInputMethodInfo;
|
||||
InputMethodSubtype mInputMethodSubtype;
|
||||
|
||||
KeyboardInfo(
|
||||
String language,
|
||||
CharSequence subtypeLabel,
|
||||
String layout,
|
||||
InputMethodInfo inputMethodInfo,
|
||||
InputMethodSubtype inputMethodSubtype) {
|
||||
mLanguage = language;
|
||||
mSubtypeLabel = subtypeLabel;
|
||||
mLayout = layout;
|
||||
mInputMethodInfo = inputMethodInfo;
|
||||
mInputMethodSubtype = inputMethodSubtype;
|
||||
}
|
||||
|
||||
String getLanguage() {
|
||||
return mLanguage;
|
||||
String getPrefId() {
|
||||
return mInputMethodInfo.getId() + "_" + mInputMethodSubtype.hashCode();
|
||||
}
|
||||
|
||||
CharSequence getSubtypeLabel() {
|
||||
return mSubtypeLabel;
|
||||
}
|
||||
|
||||
String getLayout() {
|
||||
|
@@ -16,12 +16,22 @@
|
||||
|
||||
package com.android.settings.language;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import com.android.settings.Settings;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
/**
|
||||
* This is a display controller for new language activity entry.
|
||||
* TODO(b/273642892): When new layout is on board, this class shall be removed.
|
||||
*/
|
||||
public class LanguagePreferenceController extends BasePreferenceController {
|
||||
private static final String TAG = LanguagePreferenceController.class.getSimpleName();
|
||||
|
||||
private boolean mCacheIsFeatureOn = false;
|
||||
|
||||
public LanguagePreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
@@ -31,6 +41,27 @@ public class LanguagePreferenceController extends BasePreferenceController {
|
||||
public int getAvailabilityStatus() {
|
||||
boolean isFeatureOn = FeatureFlagUtils
|
||||
.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
|
||||
|
||||
// LanguageSettingsActivity is a new entry page for new language layout.
|
||||
// LanguageAndInputSettingsActivity is existed entry page for current language layout.
|
||||
if (mCacheIsFeatureOn != isFeatureOn) {
|
||||
setActivityEnabled(
|
||||
mContext, Settings.LanguageAndInputSettingsActivity.class, !isFeatureOn);
|
||||
setActivityEnabled(mContext, Settings.LanguageSettingsActivity.class, isFeatureOn);
|
||||
mCacheIsFeatureOn = isFeatureOn;
|
||||
}
|
||||
return isFeatureOn ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
private static void setActivityEnabled(Context context, Class klass, final boolean isEnabled) {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
|
||||
ComponentName componentName =
|
||||
new ComponentName(context, klass);
|
||||
final int flag = isEnabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
|
||||
|
||||
packageManager.setComponentEnabledSetting(
|
||||
componentName, flag, PackageManager.DONT_KILL_APP);
|
||||
}
|
||||
}
|
@@ -272,7 +272,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme
|
||||
use(OpenNetworkSelectPagePreferenceController.class).init(mSubId);
|
||||
final AutoSelectPreferenceController autoSelectPreferenceController =
|
||||
use(AutoSelectPreferenceController.class)
|
||||
.init(mSubId)
|
||||
.init(getLifecycle(), mSubId)
|
||||
.addListener(openNetworkSelectPagePreferenceController);
|
||||
use(NetworkPreferenceCategoryController.class).init(mSubId)
|
||||
.setChildren(Arrays.asList(autoSelectPreferenceController));
|
||||
|
@@ -34,8 +34,10 @@ import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
import androidx.preference.Preference;
|
||||
@@ -45,6 +47,7 @@ import androidx.preference.SwitchPreference;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.network.AllowedNetworkTypesListener;
|
||||
import com.android.settings.network.CarrierConfigCache;
|
||||
import com.android.settings.network.helper.ServiceStateStatus;
|
||||
import com.android.settings.network.telephony.MobileNetworkUtils;
|
||||
import com.android.settings.network.telephony.TelephonyTogglePreferenceController;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
@@ -62,6 +65,9 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
public class AutoSelectPreferenceController extends TelephonyTogglePreferenceController
|
||||
implements LifecycleObserver{
|
||||
private static final long MINIMUM_DIALOG_TIME_MILLIS = TimeUnit.SECONDS.toMillis(1);
|
||||
private static final String LOG_TAG = "AutoSelectPreferenceController";
|
||||
private static final String INTERNAL_LOG_TAG_INIT = "Init";
|
||||
private static final String INTERNAL_LOG_TAG_AFTERSET = "AfterSet";
|
||||
|
||||
private final Handler mUiHandler;
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
@@ -76,6 +82,7 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
private AtomicBoolean mUpdatingConfig;
|
||||
private int mCacheOfModeStatus;
|
||||
private AtomicLong mRecursiveUpdate;
|
||||
ServiceStateStatus mServiceStateStatus;
|
||||
|
||||
public AutoSelectPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
@@ -129,12 +136,6 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
if (!mUpdatingConfig.get()) {
|
||||
mCacheOfModeStatus = mTelephonyManager.getNetworkSelectionMode();
|
||||
for (OnNetworkSelectModeListener lsn : mListeners) {
|
||||
lsn.onNetworkSelectModeUpdated(mCacheOfModeStatus);
|
||||
}
|
||||
}
|
||||
return mCacheOfModeStatus == TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
|
||||
}
|
||||
|
||||
@@ -197,12 +198,22 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
|
||||
//Update UI in UI thread
|
||||
final long durationMillis = SystemClock.elapsedRealtime() - startMillis;
|
||||
|
||||
mUiHandler.postDelayed(() -> {
|
||||
mRecursiveUpdate.getAndIncrement();
|
||||
mSwitchPreference.setEnabled(true);
|
||||
mSwitchPreference.setChecked(isChecked());
|
||||
mRecursiveUpdate.decrementAndGet();
|
||||
dismissProgressBar();
|
||||
ThreadUtils.postOnBackgroundThread(() -> {
|
||||
queryNetworkSelectionMode(INTERNAL_LOG_TAG_AFTERSET);
|
||||
|
||||
//Update UI in UI thread
|
||||
mUiHandler.post(() -> {
|
||||
mRecursiveUpdate.getAndIncrement();
|
||||
if (mSwitchPreference != null) {
|
||||
mSwitchPreference.setEnabled(true);
|
||||
mSwitchPreference.setChecked(isChecked());
|
||||
}
|
||||
mRecursiveUpdate.decrementAndGet();
|
||||
dismissProgressBar();
|
||||
});
|
||||
});
|
||||
}, Math.max(MINIMUM_DIALOG_TIME_MILLIS - durationMillis, 0));
|
||||
});
|
||||
}
|
||||
@@ -210,7 +221,7 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
/**
|
||||
* Initialization based on given subscription id.
|
||||
**/
|
||||
public AutoSelectPreferenceController init(int subId) {
|
||||
public AutoSelectPreferenceController init(Lifecycle lifecycle, int subId) {
|
||||
mSubId = subId;
|
||||
mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
|
||||
.createForSubscriptionId(mSubId);
|
||||
@@ -221,6 +232,29 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
CarrierConfigManager.KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL)
|
||||
: false;
|
||||
|
||||
mServiceStateStatus = new ServiceStateStatus(lifecycle, mTelephonyManager,
|
||||
new HandlerExecutor(mUiHandler)) {
|
||||
@Override
|
||||
protected void setValue(ServiceState status) {
|
||||
if (status == null) {
|
||||
return;
|
||||
}
|
||||
updateUiAutoSelectValue(status);
|
||||
}
|
||||
};
|
||||
|
||||
ThreadUtils.postOnBackgroundThread(() -> {
|
||||
queryNetworkSelectionMode(INTERNAL_LOG_TAG_INIT);
|
||||
|
||||
//Update UI in UI thread
|
||||
mUiHandler.post(() -> {
|
||||
if (mSwitchPreference != null) {
|
||||
mRecursiveUpdate.getAndIncrement();
|
||||
mSwitchPreference.setChecked(isChecked());
|
||||
mRecursiveUpdate.decrementAndGet();
|
||||
}
|
||||
});
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -230,6 +264,41 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
return this;
|
||||
}
|
||||
|
||||
private void queryNetworkSelectionMode(String tag) {
|
||||
mCacheOfModeStatus = mTelephonyManager.getNetworkSelectionMode();
|
||||
Log.d(LOG_TAG, tag + ": query commend done. mCacheOfModeStatus: " + mCacheOfModeStatus);
|
||||
updateListenerValue();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void updateUiAutoSelectValue(ServiceState status) {
|
||||
if (status == null) {
|
||||
return;
|
||||
}
|
||||
if (!mUpdatingConfig.get()) {
|
||||
int networkSelectionMode = status.getIsManualSelection()
|
||||
? TelephonyManager.NETWORK_SELECTION_MODE_MANUAL
|
||||
: TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
|
||||
if (mCacheOfModeStatus == networkSelectionMode) {
|
||||
return;
|
||||
}
|
||||
mCacheOfModeStatus = networkSelectionMode;
|
||||
Log.d(LOG_TAG, "updateUiAutoSelectValue: mCacheOfModeStatus: " + mCacheOfModeStatus);
|
||||
updateListenerValue();
|
||||
|
||||
mRecursiveUpdate.getAndIncrement();
|
||||
updateState(mSwitchPreference);
|
||||
mRecursiveUpdate.decrementAndGet();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void updateListenerValue() {
|
||||
for (OnNetworkSelectModeListener lsn : mListeners) {
|
||||
lsn.onNetworkSelectModeUpdated(mCacheOfModeStatus);
|
||||
}
|
||||
}
|
||||
|
||||
private void showAutoSelectProgressBar() {
|
||||
if (mProgressDialog == null) {
|
||||
mProgressDialog = new ProgressDialog(mContext);
|
||||
|
@@ -19,6 +19,8 @@ package com.android.settings.notification;
|
||||
import static com.android.settings.notification.SettingPref.TYPE_GLOBAL;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.provider.Settings.Global;
|
||||
|
||||
@@ -41,7 +43,7 @@ public class DockAudioMediaPreferenceController extends SettingPrefController {
|
||||
DEFAULT_DOCK_AUDIO_MEDIA, DOCK_AUDIO_MEDIA_DISABLED, DOCK_AUDIO_MEDIA_ENABLED) {
|
||||
@Override
|
||||
public boolean isApplicable(Context context) {
|
||||
return context.getResources().getBoolean(
|
||||
return isLeDesk() && context.getResources().getBoolean(
|
||||
com.android.settings.R.bool.has_dock_settings);
|
||||
}
|
||||
|
||||
@@ -60,4 +62,18 @@ public class DockAudioMediaPreferenceController extends SettingPrefController {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the state of docking type
|
||||
* @return true if it is low-end dock types
|
||||
*/
|
||||
private boolean isLeDesk() {
|
||||
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
|
||||
Intent dockStatus = mContext.registerReceiver(null, intentFilter);
|
||||
if (dockStatus == null) {
|
||||
return false;
|
||||
}
|
||||
int dockState = dockStatus.getIntExtra(Intent.EXTRA_DOCK_STATE, -1);
|
||||
return dockState == Intent.EXTRA_DOCK_STATE_LE_DESK;
|
||||
}
|
||||
}
|
||||
|
@@ -98,14 +98,13 @@ public class AppNotificationSettings extends NotificationSettings {
|
||||
mBackend));
|
||||
mControllers.add(new DndPreferenceController(context, mBackend));
|
||||
mControllers.add(new AppLinkPreferenceController(context));
|
||||
mControllers.add(new DescriptionPreferenceController(context));
|
||||
mControllers.add(new NotificationsOffPreferenceController(context));
|
||||
mControllers.add(new DeletedChannelsPreferenceController(context, mBackend));
|
||||
mControllers.add(new ChannelListPreferenceController(context, mBackend));
|
||||
mControllers.add(new AppConversationListPreferenceController(context, mBackend));
|
||||
mControllers.add(new InvalidConversationInfoPreferenceController(context, mBackend));
|
||||
mControllers.add(new InvalidConversationPreferenceController(context, mBackend));
|
||||
mControllers.add(new BubbleSummaryPreferenceController(context, mBackend));
|
||||
mControllers.add(new NotificationsOffPreferenceController(context));
|
||||
mControllers.add(new DeletedChannelsPreferenceController(context, mBackend));
|
||||
return new ArrayList<>(mControllers);
|
||||
}
|
||||
}
|
||||
|
@@ -62,9 +62,16 @@ public class BadgePreferenceController extends NotificationPreferenceController
|
||||
if (isDefaultChannel()) {
|
||||
return true;
|
||||
} else {
|
||||
return mAppRow == null ? false : mAppRow.showBadge;
|
||||
return mAppRow == null
|
||||
? false
|
||||
: mAppRow.channelCount == 0
|
||||
? false
|
||||
: mAppRow.showBadge;
|
||||
}
|
||||
}
|
||||
if (mAppRow.channelCount == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.notification.app;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
|
||||
public class DescriptionPreferenceController extends NotificationPreferenceController
|
||||
implements PreferenceControllerMixin {
|
||||
|
||||
private static final String KEY_DESC = "desc";
|
||||
|
||||
public DescriptionPreferenceController(Context context) {
|
||||
super(context, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_DESC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
if (!super.isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
if (mChannel == null && !hasValidGroup()) {
|
||||
return false;
|
||||
}
|
||||
if (mChannel != null && !TextUtils.isEmpty(mChannel.getDescription())) {
|
||||
return true;
|
||||
}
|
||||
if (hasValidGroup() && !TextUtils.isEmpty(mChannelGroup.getDescription())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isIncludedInFilter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void updateState(Preference preference) {
|
||||
if (mAppRow != null) {
|
||||
if (mChannel != null) {
|
||||
preference.setTitle(mChannel.getDescription());
|
||||
} else if (hasValidGroup()) {
|
||||
preference.setTitle(mChannelGroup.getDescription());
|
||||
}
|
||||
}
|
||||
preference.setEnabled(false);
|
||||
preference.setSelectable(false);
|
||||
}
|
||||
}
|
@@ -312,21 +312,6 @@ public class ZenModeBackend {
|
||||
return R.string.zen_mode_from_no_conversations;
|
||||
}
|
||||
|
||||
protected int getConversationSummary() {
|
||||
int conversationType = getPriorityConversationSenders();
|
||||
|
||||
switch (conversationType) {
|
||||
case NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE:
|
||||
return R.string.zen_mode_from_all_conversations;
|
||||
case NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT:
|
||||
return R.string.zen_mode_from_important_conversations;
|
||||
case NotificationManager.Policy.CONVERSATION_SENDERS_NONE:
|
||||
return R.string.zen_mode_from_no_conversations;
|
||||
default:
|
||||
return R.string.zen_mode_from_no_conversations;
|
||||
}
|
||||
}
|
||||
|
||||
protected int getContactsCallsSummary(ZenPolicy policy) {
|
||||
int peopleType = policy.getPriorityCallSenders();
|
||||
switch (peopleType) {
|
||||
|
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.notification.zen;
|
||||
|
||||
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
|
||||
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
|
||||
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_NONE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.widget.LayoutPreference;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Updates the DND Settings conversations image resource based on the conversations channels.
|
||||
*/
|
||||
public class ZenModeConversationsImagePreferenceController
|
||||
extends AbstractZenModePreferenceController {
|
||||
private static final int MAX_CONVERSATIONS_SHOWN = 5;
|
||||
private final int mIconSizePx;
|
||||
private final int mIconOffsetPx;
|
||||
private final ArrayList<Drawable> mConversationDrawables = new ArrayList<>();
|
||||
private final NotificationBackend mNotificationBackend;
|
||||
|
||||
private ViewGroup mViewGroup;
|
||||
private LayoutPreference mPreference;
|
||||
|
||||
public ZenModeConversationsImagePreferenceController(Context context, String key,
|
||||
Lifecycle lifecycle, NotificationBackend notificationBackend) {
|
||||
super(context, key, lifecycle);
|
||||
mNotificationBackend = notificationBackend;
|
||||
mIconSizePx =
|
||||
mContext.getResources().getDimensionPixelSize(R.dimen.zen_conversations_icon_size);
|
||||
mIconOffsetPx = mContext.getResources()
|
||||
.getDimensionPixelSize(R.dimen.zen_conversations_icon_offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = (LayoutPreference) screen.findPreference(KEY);
|
||||
mViewGroup =
|
||||
(ViewGroup) mPreference.findViewById(R.id.zen_mode_settings_senders_overlay_view);
|
||||
loadConversations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
loadConversations();
|
||||
|
||||
mViewGroup.removeAllViews();
|
||||
final int conversationSenders = mBackend.getPriorityConversationSenders();
|
||||
if (conversationSenders == CONVERSATION_SENDERS_ANYONE) {
|
||||
mViewGroup.setContentDescription(
|
||||
mContext.getResources().getString(R.string.zen_mode_from_all_conversations));
|
||||
} else if (conversationSenders == CONVERSATION_SENDERS_IMPORTANT) {
|
||||
mViewGroup.setContentDescription(
|
||||
mContext.getResources().getString(
|
||||
R.string.zen_mode_from_important_conversations));
|
||||
} else {
|
||||
mViewGroup.setContentDescription(null);
|
||||
mViewGroup.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
final int numDrawablesToShow = Math.min(MAX_CONVERSATIONS_SHOWN,
|
||||
mConversationDrawables.size());
|
||||
for (int i = 0; i < numDrawablesToShow; i++) {
|
||||
ImageView iv = new ImageView(mContext);
|
||||
iv.setImageDrawable(mConversationDrawables.get(i));
|
||||
iv.setLayoutParams(new ViewGroup.LayoutParams(mIconSizePx, mIconSizePx));
|
||||
|
||||
FrameLayout fl = new FrameLayout(mContext);
|
||||
fl.addView(iv);
|
||||
fl.setPadding((numDrawablesToShow - i - 1) * mIconOffsetPx, 0, 0, 0);
|
||||
mViewGroup.addView(fl);
|
||||
}
|
||||
|
||||
mViewGroup.setVisibility(numDrawablesToShow > 0 ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
private void loadConversations() {
|
||||
// Load conversations
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
private List<Drawable> mDrawables = new ArrayList<>();
|
||||
@Override
|
||||
protected Void doInBackground(Void... unused) {
|
||||
mDrawables.clear();
|
||||
final int conversationSenders = mBackend.getPriorityConversationSenders();
|
||||
if (conversationSenders == CONVERSATION_SENDERS_NONE) {
|
||||
return null;
|
||||
}
|
||||
ParceledListSlice<ConversationChannelWrapper> conversations =
|
||||
mNotificationBackend.getConversations(
|
||||
conversationSenders == CONVERSATION_SENDERS_IMPORTANT);
|
||||
if (conversations != null) {
|
||||
for (ConversationChannelWrapper conversation : conversations.getList()) {
|
||||
if (!conversation.getNotificationChannel().isDemoted()) {
|
||||
Drawable drawable = mNotificationBackend.getConversationDrawable(
|
||||
mContext,
|
||||
conversation.getShortcutInfo(),
|
||||
conversation.getPkg(),
|
||||
conversation.getUid(),
|
||||
conversation.getNotificationChannel()
|
||||
.isImportantConversation());
|
||||
if (drawable != null) {
|
||||
mDrawables.add(drawable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void unused) {
|
||||
if (mContext == null) {
|
||||
return;
|
||||
}
|
||||
mConversationDrawables.clear();
|
||||
mConversationDrawables.addAll(mDrawables);
|
||||
updateState(mPreference);
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.notification.zen;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
/**
|
||||
* Controls the summary for preference found at:
|
||||
* Settings > Sound > Do Not Disturb > People > Conversations
|
||||
*/
|
||||
public class ZenModeConversationsPreferenceController extends AbstractZenModePreferenceController {
|
||||
private final ZenModeBackend mBackend;
|
||||
private Preference mPreference;
|
||||
|
||||
public ZenModeConversationsPreferenceController(Context context,
|
||||
String key, Lifecycle lifecycle) {
|
||||
super(context, key, lifecycle);
|
||||
mBackend = ZenModeBackend.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = screen.findPreference(KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
switch (getZenMode()) {
|
||||
case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
|
||||
case Settings.Global.ZEN_MODE_ALARMS:
|
||||
mPreference.setEnabled(false);
|
||||
mPreference.setSummary(mBackend.getAlarmsTotalSilencePeopleSummary(
|
||||
NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS));
|
||||
break;
|
||||
default:
|
||||
preference.setEnabled(true);
|
||||
preference.setSummary(mBackend.getConversationSummary());
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.notification.zen;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Settings > Sound > Do Not Disturb > Conversations
|
||||
*/
|
||||
@SearchIndexable
|
||||
public class ZenModeConversationsSettings extends ZenModeSettingsBase {
|
||||
private final NotificationBackend mNotificationBackend = new NotificationBackend();
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
return buildPreferenceControllers(context, getSettingsLifecycle(), mNotificationBackend);
|
||||
}
|
||||
|
||||
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
||||
Lifecycle lifecycle, NotificationBackend notificationBackend) {
|
||||
List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new ZenModeConversationsImagePreferenceController(context,
|
||||
"zen_mode_conversations_image", lifecycle, notificationBackend));
|
||||
controllers.add(new ZenModePriorityConversationsPreferenceController(context,
|
||||
"zen_mode_conversations_radio_buttons", lifecycle, notificationBackend));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.zen_mode_conversations_settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.DND_CONVERSATIONS;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Search.
|
||||
*/
|
||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider(R.xml.zen_mode_conversations_settings) {
|
||||
|
||||
@Override
|
||||
public List<AbstractPreferenceController> createPreferenceControllers(
|
||||
Context context) {
|
||||
return buildPreferenceControllers(context, null, null);
|
||||
}
|
||||
};
|
||||
}
|
@@ -1,219 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.notification.zen;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.icu.text.MessageFormat;
|
||||
import android.os.AsyncTask;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settings.notification.app.ConversationListSettings;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Options to choose the priority conversations that are allowed to bypass DND.
|
||||
*/
|
||||
public class ZenModePriorityConversationsPreferenceController
|
||||
extends AbstractZenModePreferenceController {
|
||||
private static final int UNSET = -1;
|
||||
@VisibleForTesting static final String KEY_ALL = "conversations_all";
|
||||
@VisibleForTesting static final String KEY_IMPORTANT = "conversations_important";
|
||||
@VisibleForTesting static final String KEY_NONE = "conversations_none";
|
||||
|
||||
private final NotificationBackend mNotificationBackend;
|
||||
|
||||
private int mNumImportantConversations = UNSET;
|
||||
private int mNumConversations = UNSET;
|
||||
private PreferenceCategory mPreferenceCategory;
|
||||
private List<SelectorWithWidgetPreference> mSelectorWithWidgetPreferences = new ArrayList<>();
|
||||
private Context mPreferenceScreenContext;
|
||||
|
||||
public ZenModePriorityConversationsPreferenceController(Context context, String key,
|
||||
Lifecycle lifecycle, NotificationBackend notificationBackend) {
|
||||
super(context, key, lifecycle);
|
||||
mNotificationBackend = notificationBackend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
mPreferenceScreenContext = screen.getContext();
|
||||
mPreferenceCategory = screen.findPreference(getPreferenceKey());
|
||||
if (mPreferenceCategory.findPreference(KEY_ALL) == null) {
|
||||
makeRadioPreference(KEY_ALL, R.string.zen_mode_from_all_conversations);
|
||||
makeRadioPreference(KEY_IMPORTANT, R.string.zen_mode_from_important_conversations);
|
||||
makeRadioPreference(KEY_NONE, R.string.zen_mode_from_no_conversations);
|
||||
updateChannelCounts();
|
||||
}
|
||||
|
||||
super.displayPreference(screen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
updateChannelCounts();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
final int currSetting = mBackend.getPriorityConversationSenders();
|
||||
|
||||
for (SelectorWithWidgetPreference pref : mSelectorWithWidgetPreferences) {
|
||||
pref.setChecked(keyToSetting(pref.getKey()) == currSetting);
|
||||
pref.setSummary(getSummary(pref.getKey()));
|
||||
}
|
||||
}
|
||||
|
||||
private static int keyToSetting(String key) {
|
||||
switch (key) {
|
||||
case KEY_ALL:
|
||||
return NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
|
||||
case KEY_IMPORTANT:
|
||||
return NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
|
||||
default:
|
||||
return NotificationManager.Policy.CONVERSATION_SENDERS_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
private String getSummary(String key) {
|
||||
int numConversations;
|
||||
if (KEY_ALL.equals(key)) {
|
||||
numConversations = mNumConversations;
|
||||
} else if (KEY_IMPORTANT.equals(key)) {
|
||||
numConversations = mNumImportantConversations;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (numConversations == UNSET) {
|
||||
return null;
|
||||
} else {
|
||||
MessageFormat msgFormat = new MessageFormat(
|
||||
mContext.getString(R.string.zen_mode_conversations_count),
|
||||
Locale.getDefault());
|
||||
Map<String, Object> args = new HashMap<>();
|
||||
args.put("count", numConversations);
|
||||
return msgFormat.format(args);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateChannelCounts() {
|
||||
// Load conversations
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... unused) {
|
||||
ParceledListSlice<ConversationChannelWrapper> allConversations =
|
||||
mNotificationBackend.getConversations(false);
|
||||
int numConversations = 0;
|
||||
if (allConversations != null) {
|
||||
for (ConversationChannelWrapper conversation : allConversations.getList()) {
|
||||
if (!conversation.getNotificationChannel().isDemoted()) {
|
||||
numConversations++;
|
||||
}
|
||||
}
|
||||
}
|
||||
mNumConversations = numConversations;
|
||||
|
||||
ParceledListSlice<ConversationChannelWrapper> impConversations =
|
||||
mNotificationBackend.getConversations(true);
|
||||
int numImportantConversations = 0;
|
||||
if (impConversations != null) {
|
||||
for (ConversationChannelWrapper conversation : impConversations.getList()) {
|
||||
if (!conversation.getNotificationChannel().isDemoted()) {
|
||||
numImportantConversations++;
|
||||
}
|
||||
}
|
||||
}
|
||||
mNumImportantConversations = numImportantConversations;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void unused) {
|
||||
if (mContext == null) {
|
||||
return;
|
||||
}
|
||||
updateState(mPreferenceCategory);
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
private SelectorWithWidgetPreference makeRadioPreference(String key, int titleId) {
|
||||
final SelectorWithWidgetPreference pref =
|
||||
new SelectorWithWidgetPreference(mPreferenceCategory.getContext());
|
||||
if (KEY_ALL.equals(key) || KEY_IMPORTANT.equals(key)) {
|
||||
pref.setExtraWidgetOnClickListener(mConversationSettingsWidgetClickListener);
|
||||
}
|
||||
pref.setKey(key);
|
||||
pref.setTitle(titleId);
|
||||
pref.setOnClickListener(mRadioButtonClickListener);
|
||||
mPreferenceCategory.addPreference(pref);
|
||||
mSelectorWithWidgetPreferences.add(pref);
|
||||
return pref;
|
||||
}
|
||||
|
||||
private View.OnClickListener mConversationSettingsWidgetClickListener =
|
||||
new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
new SubSettingLauncher(mPreferenceScreenContext)
|
||||
.setDestination(ConversationListSettings.class.getName())
|
||||
.setSourceMetricsCategory(SettingsEnums.DND_CONVERSATIONS)
|
||||
.launch();
|
||||
}
|
||||
};
|
||||
|
||||
private SelectorWithWidgetPreference.OnClickListener mRadioButtonClickListener =
|
||||
new SelectorWithWidgetPreference.OnClickListener() {
|
||||
@Override
|
||||
public void onRadioButtonClicked(SelectorWithWidgetPreference preference) {
|
||||
int selectedConversationSetting = keyToSetting(preference.getKey());
|
||||
if (selectedConversationSetting != mBackend.getPriorityConversationSenders()) {
|
||||
mBackend.saveConversationSenders(selectedConversationSetting);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@@ -29,12 +29,15 @@ import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsControllerCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
|
||||
|
||||
/**
|
||||
@@ -144,9 +147,33 @@ public class SettingsPanelActivity extends FragmentActivity {
|
||||
window.setGravity(Gravity.BOTTOM);
|
||||
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
|
||||
WindowManager.LayoutParams.WRAP_CONTENT);
|
||||
setupNavigationBar();
|
||||
mPanelFragment = new PanelFragment();
|
||||
mPanelFragment.setArguments(new Bundle(mBundle));
|
||||
fragmentManager.beginTransaction().add(R.id.main_content, mPanelFragment).commit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust bottom edge and color.
|
||||
*/
|
||||
private void setupNavigationBar() {
|
||||
// Extend the panel all the way to the bottom of the screen, as opposed to sitting on top of
|
||||
// the navigation bar.
|
||||
ViewCompat.setOnApplyWindowInsetsListener(getWindow().getDecorView(),
|
||||
(v, windowInsets) -> {
|
||||
v.setPadding(v.getPaddingLeft(), v.getPaddingTop(), v.getPaddingRight(), 0);
|
||||
return windowInsets; // propagate down to panel layout root element
|
||||
});
|
||||
|
||||
// When using 3-button navigation in light mode, the system picks white navigation buttons
|
||||
// which are not sufficiently contrasted from the panel background.
|
||||
WindowInsetsControllerCompat windowInsetsController =
|
||||
ViewCompat.getWindowInsetsController(getWindow().getDecorView());
|
||||
|
||||
if (windowInsetsController != null) {
|
||||
boolean forceNavigationButtonsDark = !Utils.isNightMode(this);
|
||||
windowInsetsController.setAppearanceLightNavigationBars(forceNavigationButtonsDark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.app.LocaleHelper;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
@@ -53,9 +54,8 @@ public class NumberingPreferencesFragment extends DashboardFragment {
|
||||
Log.w(getLogTag(), "No selected language.");
|
||||
return "";
|
||||
}
|
||||
return Locale.forLanguageTag(selectedLanguage)
|
||||
.stripExtensions()
|
||||
.getDisplayName(Locale.forLanguageTag(selectedLanguage));
|
||||
Locale locale = Locale.forLanguageTag(selectedLanguage);
|
||||
return LocaleHelper.getDisplayName(locale.stripExtensions(), locale, true);
|
||||
}
|
||||
Log.w(getLogTag(), "Incorrect option : " + option);
|
||||
return "";
|
||||
|
@@ -26,8 +26,6 @@ import android.os.Bundle;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.XmlTestUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
@@ -44,8 +42,6 @@ import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Tests for {@link BluetoothDetailsAudioRoutingFragment}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowBluetoothUtils.class})
|
||||
@@ -92,17 +88,6 @@ public class BluetoothDetailsAudioRoutingFragmentTest {
|
||||
assertThat(mFragment.mCachedDevice.getAddress()).isEqualTo(TEST_ADDRESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNonIndexableKeys_existInXmlLayout() {
|
||||
final List<String> niks = BluetoothDetailsAudioRoutingFragment.SEARCH_INDEX_DATA_PROVIDER
|
||||
.getNonIndexableKeys(mContext);
|
||||
final List<String> keys =
|
||||
XmlTestUtils.getKeysFromPreferenceXml(mContext,
|
||||
R.xml.bluetooth_audio_routing_fragment);
|
||||
|
||||
assertThat(keys).containsAtLeastElementsIn(niks);
|
||||
}
|
||||
|
||||
private void setupEnvironment() {
|
||||
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
|
||||
when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
|
||||
|
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.dream;
|
||||
|
||||
import static com.android.settingslib.dream.DreamBackend.COMPLICATION_TYPE_HOME_CONTROLS;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settingslib.dream.DreamBackend;
|
||||
|
||||
import org.junit.After;
|
||||
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.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowContentResolver;
|
||||
import org.robolectric.shadows.ShadowSettings;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowSettings.ShadowSecure.class})
|
||||
public class DreamHomeControlsPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private PreferenceScreen mScreen;
|
||||
private DreamHomeControlsPreferenceController mController;
|
||||
private SwitchPreference mPreference;
|
||||
private DreamBackend mBackend;
|
||||
private ShadowContentResolver mShadowContentResolver;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
mShadowContentResolver = Shadow.extract(mContext.getContentResolver());
|
||||
mBackend = new DreamBackend(mContext);
|
||||
mController = new DreamHomeControlsPreferenceController(mContext, "key", mBackend);
|
||||
mPreference = new SwitchPreference(mContext);
|
||||
mPreference.setKey(mController.getPreferenceKey());
|
||||
when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
// Make home controls supported by default
|
||||
mBackend.setSupportedComplications(
|
||||
new ArraySet<>(new Integer[]{COMPLICATION_TYPE_HOME_CONTROLS}));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ShadowSettings.ShadowSecure.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetChecked_setTrue_enablesSetting() {
|
||||
mBackend.setHomeControlsEnabled(false);
|
||||
assertThat(mBackend.getEnabledComplications())
|
||||
.doesNotContain(COMPLICATION_TYPE_HOME_CONTROLS);
|
||||
|
||||
mController.setChecked(true);
|
||||
assertThat(mBackend.getEnabledComplications())
|
||||
.contains(COMPLICATION_TYPE_HOME_CONTROLS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetChecked_setFalse_disablesSetting() {
|
||||
mBackend.setHomeControlsEnabled(true);
|
||||
assertThat(mBackend.getEnabledComplications())
|
||||
.contains(COMPLICATION_TYPE_HOME_CONTROLS);
|
||||
|
||||
mController.setChecked(false);
|
||||
assertThat(mBackend.getEnabledComplications())
|
||||
.doesNotContain(COMPLICATION_TYPE_HOME_CONTROLS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsChecked_returnsFalse() {
|
||||
mBackend.setHomeControlsEnabled(false);
|
||||
assertThat(mController.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsChecked_returnsTrue() {
|
||||
mBackend.setHomeControlsEnabled(true);
|
||||
assertThat(mBackend.getEnabledComplications())
|
||||
.contains(COMPLICATION_TYPE_HOME_CONTROLS);
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
}
|
||||
}
|
@@ -19,14 +19,19 @@ package com.android.settings.notification;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.provider.Settings.Global;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
@@ -72,6 +77,7 @@ public class DockAudioMediaPreferenceControllerTest {
|
||||
mController = new DockAudioMediaPreferenceController(mContext, mSetting, null);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
doReturn(mScreen).when(mSetting).getPreferenceScreen();
|
||||
fakeDockState(Intent.EXTRA_DOCK_STATE_LE_DESK);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -90,6 +96,34 @@ public class DockAudioMediaPreferenceControllerTest {
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_undocked_shouldReturnFalse() {
|
||||
when(mContext.registerReceiver(nullable(BroadcastReceiver.class),
|
||||
any(IntentFilter.class))).thenReturn(null);
|
||||
when(mContext.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings))
|
||||
.thenReturn(true);
|
||||
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_highEndDock_shouldReturnFalse() {
|
||||
fakeDockState(Intent.EXTRA_DOCK_STATE_HE_DESK);
|
||||
when(mContext.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings))
|
||||
.thenReturn(true);
|
||||
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_lowEndDock_shouldReturnTrue() {
|
||||
fakeDockState(Intent.EXTRA_DOCK_STATE_LE_DESK);
|
||||
when(mContext.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings))
|
||||
.thenReturn(true);
|
||||
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_dockAudioDisabled_shouldSelectFirstItem() {
|
||||
Global.putInt(mContentResolver, Global.DOCK_AUDIO_MEDIA_ENABLED, 0);
|
||||
@@ -127,4 +161,11 @@ public class DockAudioMediaPreferenceControllerTest {
|
||||
assertThat(Global.getInt(mContentResolver, Global.DOCK_AUDIO_MEDIA_ENABLED, 0))
|
||||
.isEqualTo(1);
|
||||
}
|
||||
|
||||
private void fakeDockState(int dockState) {
|
||||
Intent intent = new Intent(Intent.ACTION_DOCK_EVENT);
|
||||
intent.putExtra(Intent.EXTRA_DOCK_STATE, dockState);
|
||||
when(mContext.registerReceiver(nullable(BroadcastReceiver.class),
|
||||
any(IntentFilter.class))).thenReturn(intent);
|
||||
}
|
||||
}
|
||||
|
@@ -97,6 +97,7 @@ public class BadgePreferenceControllerTest {
|
||||
@Test
|
||||
public void testIsAvailable_notIfAppBlocked() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.channelCount = 1;
|
||||
appRow.banned = true;
|
||||
mController.onResume(appRow, mock(NotificationChannel.class), null, null, null, null, null);
|
||||
assertFalse(mController.isAvailable());
|
||||
@@ -105,6 +106,7 @@ public class BadgePreferenceControllerTest {
|
||||
@Test
|
||||
public void testIsAvailable_notIfChannelBlocked() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.channelCount = 1;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
|
||||
mController.onResume(appRow, channel, null, null, null, null, null);
|
||||
@@ -114,6 +116,7 @@ public class BadgePreferenceControllerTest {
|
||||
@Test
|
||||
public void testIsAvailable_channel_notIfAppOff() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.channelCount = 1;
|
||||
appRow.showBadge = false;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
||||
@@ -125,6 +128,7 @@ public class BadgePreferenceControllerTest {
|
||||
@Test
|
||||
public void testIsAvailable_notIfOffGlobally() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.channelCount = 1;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
||||
mController.onResume(appRow, channel, null, null, null, null, null);
|
||||
@@ -136,16 +140,28 @@ public class BadgePreferenceControllerTest {
|
||||
@Test
|
||||
public void testIsAvailable_app() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.channelCount = 1;
|
||||
mController.onResume(appRow, null, null, null, null, null, null);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BADGING, 1);
|
||||
|
||||
assertTrue(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_appNoChannels() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.channelCount = 0;
|
||||
mController.onResume(appRow, null, null, null, null, null, null);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BADGING, 1);
|
||||
|
||||
assertFalse(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_defaultChannel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.showBadge = true;
|
||||
appRow.channelCount = 1;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
||||
when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
|
||||
@@ -159,6 +175,7 @@ public class BadgePreferenceControllerTest {
|
||||
public void testIsAvailable_channel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.showBadge = true;
|
||||
appRow.channelCount = 1;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
||||
mController.onResume(appRow, channel, null, null, null, null, null);
|
||||
@@ -183,6 +200,7 @@ public class BadgePreferenceControllerTest {
|
||||
public void testIsAvailable_filteredOut() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.showBadge = true;
|
||||
appRow.channelCount = 1;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
||||
mController.onResume(appRow, channel, null, null, null, null, new ArrayList<>());
|
||||
@@ -195,6 +213,7 @@ public class BadgePreferenceControllerTest {
|
||||
public void testIsAvailable_filteredIn() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.showBadge = true;
|
||||
appRow.channelCount = 1;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
||||
mController.onResume(appRow, channel, null, null, null, null,
|
||||
@@ -206,9 +225,11 @@ public class BadgePreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void testUpdateState_disabledByAdmin() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.channelCount = 1;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getId()).thenReturn("something");
|
||||
mController.onResume(new NotificationBackend.AppRow(), channel, null,
|
||||
mController.onResume(appRow, channel, null,
|
||||
null, null, mock(RestrictedLockUtils.EnforcedAdmin.class), null);
|
||||
|
||||
Preference pref = new RestrictedSwitchPreference(mContext);
|
||||
@@ -220,6 +241,7 @@ public class BadgePreferenceControllerTest {
|
||||
@Test
|
||||
public void testUpdateState_channel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.channelCount = 1;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.canShowBadge()).thenReturn(true);
|
||||
mController.onResume(appRow, channel, null, null, null, null, null);
|
||||
@@ -240,6 +262,7 @@ public class BadgePreferenceControllerTest {
|
||||
public void testUpdateState_app() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.showBadge = true;
|
||||
appRow.channelCount = 1;
|
||||
mController.onResume(appRow, null, null, null, null, null, null);
|
||||
|
||||
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
|
||||
@@ -257,6 +280,7 @@ public class BadgePreferenceControllerTest {
|
||||
public void testOnPreferenceChange_on_channel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.showBadge = true;
|
||||
appRow.channelCount = 1;
|
||||
NotificationChannel channel =
|
||||
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
|
||||
channel.setShowBadge(false);
|
||||
@@ -276,6 +300,7 @@ public class BadgePreferenceControllerTest {
|
||||
public void testOnPreferenceChange_off_channel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.showBadge = true;
|
||||
appRow.channelCount = 1;
|
||||
NotificationChannel channel =
|
||||
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
|
||||
channel.setShowBadge(true);
|
||||
@@ -295,6 +320,7 @@ public class BadgePreferenceControllerTest {
|
||||
public void testOnPreferenceChange_on_app() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.showBadge = false;
|
||||
appRow.channelCount = 1;
|
||||
mController.onResume(appRow, null, null, null, null, null, null);
|
||||
|
||||
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
|
||||
@@ -312,6 +338,7 @@ public class BadgePreferenceControllerTest {
|
||||
public void testOnPreferenceChange_off_app() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.showBadge = true;
|
||||
appRow.channelCount = 1;
|
||||
mController.onResume(appRow, null, null, null, null, null, null);
|
||||
|
||||
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
|
||||
|
@@ -1,170 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.notification.app;
|
||||
|
||||
import static android.app.NotificationManager.IMPORTANCE_LOW;
|
||||
import static android.app.NotificationManager.IMPORTANCE_NONE;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationChannelGroup;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.os.UserManager;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class DescriptionPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private NotificationManager mNm;
|
||||
@Mock
|
||||
private UserManager mUm;
|
||||
|
||||
private DescriptionPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
ShadowApplication shadowApplication = ShadowApplication.getInstance();
|
||||
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
|
||||
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mController = spy(new DescriptionPreferenceController(mContext));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoCrashIfNoOnResume() {
|
||||
mController.isAvailable();
|
||||
mController.updateState(mock(Preference.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_notIfNull() {
|
||||
mController.onResume(null, null, null, null, null, null, null);
|
||||
assertFalse(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_notIfChannelGroupBlocked() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannelGroup group = mock(NotificationChannelGroup.class);
|
||||
mController.onResume(appRow, null, group, null, null, null, null);
|
||||
assertFalse(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_notIfChannelBlocked() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
|
||||
mController.onResume(appRow, channel, null, null, null, null, null);
|
||||
assertFalse(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_notIfNoChannelDesc() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
|
||||
mController.onResume(appRow, channel, null, null, null, null, null);
|
||||
assertFalse(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_notIfNoChannelGroupDesc() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannelGroup group = mock(NotificationChannelGroup.class);
|
||||
mController.onResume(appRow, null, group, null, null, null, null);
|
||||
assertFalse(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_channel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
|
||||
when(channel.getDescription()).thenReturn("AAA");
|
||||
mController.onResume(appRow, channel, null, null, null, null, null);
|
||||
assertTrue(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_channelGroup() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannelGroup group = mock(NotificationChannelGroup.class);
|
||||
when(group.getDescription()).thenReturn("something");
|
||||
when(group.isBlocked()).thenReturn(false);
|
||||
mController.onResume(appRow, null, group, null, null, null, null);
|
||||
assertTrue(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_alwaysFiltered() {
|
||||
assertFalse(mController.isIncludedInFilter());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_channel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
|
||||
when(channel.getDescription()).thenReturn("AAA");
|
||||
mController.onResume(appRow, channel, null, null, null, null, null);
|
||||
|
||||
Preference pref = new Preference(RuntimeEnvironment.application);
|
||||
mController.updateState(pref);
|
||||
|
||||
assertEquals("AAA", pref.getTitle());
|
||||
assertFalse(pref.isEnabled());
|
||||
assertFalse(pref.isSelectable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_channelGroup() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannelGroup group = mock(NotificationChannelGroup.class);
|
||||
when(group.getDescription()).thenReturn("something");
|
||||
mController.onResume(appRow, null, group, null, null, null, null);
|
||||
|
||||
Preference pref = new Preference(RuntimeEnvironment.application);
|
||||
mController.updateState(pref);
|
||||
|
||||
assertEquals("something", pref.getTitle());
|
||||
assertFalse(pref.isEnabled());
|
||||
assertFalse(pref.isSelectable());
|
||||
}
|
||||
}
|
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.notification.zen;
|
||||
|
||||
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
|
||||
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
|
||||
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_NONE;
|
||||
|
||||
import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_ALL;
|
||||
import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_IMPORTANT;
|
||||
import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_NONE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class ZenModePriorityConversationsPreferenceControllerTest {
|
||||
|
||||
private ZenModePriorityConversationsPreferenceController mController;
|
||||
|
||||
@Mock
|
||||
private ZenModeBackend mZenBackend;
|
||||
@Mock
|
||||
private PreferenceCategory mMockPrefCategory;
|
||||
@Mock
|
||||
private NotificationManager.Policy mPolicy;
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
@Mock
|
||||
private NotificationBackend mNotifBackend;
|
||||
|
||||
private List<SelectorWithWidgetPreference> mSelectorWithWidgetPreferences;
|
||||
private ContentResolver mContentResolver;
|
||||
private Context mContext;
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mController = new ZenModePriorityConversationsPreferenceController(
|
||||
mContext, "test_key", mock(Lifecycle.class), mNotifBackend);
|
||||
ReflectionHelpers.setField(mController, "mBackend", mZenBackend);
|
||||
|
||||
when(mMockPrefCategory.getContext()).thenReturn(mContext);
|
||||
when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
|
||||
.thenReturn(mMockPrefCategory);
|
||||
captureRadioButtons();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_radioButtonsCreatedOnlyOnce() {
|
||||
when(mMockPrefCategory.findPreference(any())).thenReturn(mock(Preference.class));
|
||||
|
||||
// radio buttons were already created, so don't re-create them
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
verify(mMockPrefCategory, never()).addPreference(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickAllConversations() {
|
||||
SelectorWithWidgetPreference allConversationsRb = getButton(KEY_ALL);
|
||||
allConversationsRb.onClick();
|
||||
|
||||
verify(mZenBackend).saveConversationSenders(CONVERSATION_SENDERS_ANYONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickImportantConversations() {
|
||||
SelectorWithWidgetPreference importantConversationsRb = getButton(KEY_IMPORTANT);
|
||||
importantConversationsRb.onClick();
|
||||
|
||||
verify(mZenBackend).saveConversationSenders(CONVERSATION_SENDERS_IMPORTANT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickNoConversations() {
|
||||
SelectorWithWidgetPreference noConversationsRb = getButton(KEY_NONE);
|
||||
noConversationsRb.onClick();
|
||||
|
||||
verify(mZenBackend)
|
||||
.saveConversationSenders(CONVERSATION_SENDERS_NONE);
|
||||
}
|
||||
|
||||
private void captureRadioButtons() {
|
||||
ArgumentCaptor<SelectorWithWidgetPreference> rbCaptor =
|
||||
ArgumentCaptor.forClass(SelectorWithWidgetPreference.class);
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
|
||||
// verifies 3 buttons were added
|
||||
verify(mMockPrefCategory, times(3)).addPreference(rbCaptor.capture());
|
||||
mSelectorWithWidgetPreferences = rbCaptor.getAllValues();
|
||||
assertThat(mSelectorWithWidgetPreferences.size()).isEqualTo(3);
|
||||
|
||||
reset(mMockPrefCategory);
|
||||
}
|
||||
|
||||
private SelectorWithWidgetPreference getButton(String key) {
|
||||
for (SelectorWithWidgetPreference pref : mSelectorWithWidgetPreferences) {
|
||||
if (key.equals(pref.getKey())) {
|
||||
return pref;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -16,11 +16,13 @@
|
||||
|
||||
package com.android.settings.panel;
|
||||
|
||||
import static android.content.res.Configuration.UI_MODE_NIGHT_NO;
|
||||
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
@@ -30,15 +32,20 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsControllerCompat;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -61,6 +68,9 @@ public class SettingsPanelActivityTest {
|
||||
private PanelFragment mPanelFragment;
|
||||
@Mock
|
||||
private FragmentManager mFragmentManager;
|
||||
@Mock
|
||||
private FragmentTransaction mTransaction;
|
||||
private int mOriginalUiMode;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -76,6 +86,15 @@ public class SettingsPanelActivityTest {
|
||||
mSettingsPanelActivity.mPanelFragment = mPanelFragment;
|
||||
when(mFragmentManager.findFragmentById(R.id.main_content)).thenReturn(mPanelFragment);
|
||||
when(mSettingsPanelActivity.getSupportFragmentManager()).thenReturn(mFragmentManager);
|
||||
mOriginalUiMode = mSettingsPanelActivity.getResources().getConfiguration().uiMode;
|
||||
when(mFragmentManager.beginTransaction()).thenReturn(mTransaction);
|
||||
when(mTransaction.add(anyInt(), any())).thenReturn(mTransaction);
|
||||
when(mTransaction.commit()).thenReturn(0); // don't care about return value
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mSettingsPanelActivity.getResources().getConfiguration().uiMode = mOriginalUiMode;
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -179,4 +198,24 @@ public class SettingsPanelActivityTest {
|
||||
|
||||
verify(mPanelFragment, never()).updatePanelWithAnimation();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreated_isWindowBottomPaddingZero() {
|
||||
int paddingBottom = mSettingsPanelActivity.getWindow().getDecorView().getPaddingBottom();
|
||||
assertThat(paddingBottom).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notInNightMode_lightNavigationBarAppearance() {
|
||||
Configuration config = mSettingsPanelActivity.getResources().getConfiguration();
|
||||
config.uiMode = UI_MODE_NIGHT_NO;
|
||||
mSettingsPanelActivity.onConfigurationChanged(config); // forces creation
|
||||
|
||||
mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent());
|
||||
verify(mFragmentManager).beginTransaction();
|
||||
|
||||
View decorView = mSettingsPanelActivity.getWindow().getDecorView();
|
||||
WindowInsetsControllerCompat controller = ViewCompat.getWindowInsetsController(decorView);
|
||||
assertThat(controller.isAppearanceLightNavigationBars()).isTrue();
|
||||
}
|
||||
}
|
||||
|
@@ -46,6 +46,7 @@ import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@@ -55,6 +56,13 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
private PreferenceScreen mScreen;
|
||||
private PreferenceCategory mCredentialsPreferenceCategory;
|
||||
|
||||
private static final String TEST_PACKAGE_NAME_A = "com.android.providerA";
|
||||
private static final String TEST_PACKAGE_NAME_B = "com.android.providerB";
|
||||
private static final String TEST_PACKAGE_NAME_C = "com.android.providerC";
|
||||
private static final String TEST_TITLE_APP_A = "test app A";
|
||||
private static final String TEST_TITLE_APP_B = "test app B";
|
||||
private static final String TEST_TITLE_SERVICE_C = "test service C1";
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
@@ -114,10 +122,10 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
@Test
|
||||
public void buildSwitchPreference() {
|
||||
CredentialProviderInfo providerInfo1 =
|
||||
createCredentialProviderInfo(
|
||||
createCredentialProviderInfoWithIsEnabled(
|
||||
"com.android.provider1", "ClassA", "Service Title", false);
|
||||
CredentialProviderInfo providerInfo2 =
|
||||
createCredentialProviderInfo(
|
||||
createCredentialProviderInfoWithIsEnabled(
|
||||
"com.android.provider2", "ClassA", "Service Title", false);
|
||||
CredentialManagerPreferenceController controller =
|
||||
createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2));
|
||||
@@ -217,10 +225,10 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
@Test
|
||||
public void handlesCredentialProviderInfoEnabledDisabled() {
|
||||
CredentialProviderInfo providerInfo1 =
|
||||
createCredentialProviderInfo(
|
||||
createCredentialProviderInfoWithIsEnabled(
|
||||
"com.android.provider1", "ClassA", "Service Title", false);
|
||||
CredentialProviderInfo providerInfo2 =
|
||||
createCredentialProviderInfo(
|
||||
createCredentialProviderInfoWithIsEnabled(
|
||||
"com.android.provider2", "ClassA", "Service Title", true);
|
||||
CredentialManagerPreferenceController controller =
|
||||
createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2));
|
||||
@@ -244,6 +252,63 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
assertThat(enabledServices.contains("com.android.provider2/ClassA")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_withServices_preferencesAdded_sameAppShouldBeMerged() {
|
||||
CredentialProviderInfo serviceA1 =
|
||||
createCredentialProviderInfoWithAppLabel(
|
||||
TEST_PACKAGE_NAME_A,
|
||||
"CredManProviderA1",
|
||||
TEST_TITLE_APP_A,
|
||||
"test service A1");
|
||||
CredentialProviderInfo serviceB1 =
|
||||
createCredentialProviderInfoWithAppLabel(
|
||||
TEST_PACKAGE_NAME_B,
|
||||
"CredManProviderB1",
|
||||
TEST_TITLE_APP_B,
|
||||
"test service B");
|
||||
CredentialProviderInfo serviceC1 =
|
||||
createCredentialProviderInfoWithAppLabel(
|
||||
TEST_PACKAGE_NAME_C,
|
||||
"CredManProviderC1",
|
||||
"test app C1",
|
||||
TEST_TITLE_SERVICE_C);
|
||||
CredentialProviderInfo serviceC2 =
|
||||
createCredentialProviderInfoWithAppLabel(
|
||||
TEST_PACKAGE_NAME_C,
|
||||
"CredManProviderC2",
|
||||
"test app C2",
|
||||
TEST_TITLE_SERVICE_C);
|
||||
CredentialProviderInfo serviceC3 =
|
||||
createCredentialProviderInfoBuilder(
|
||||
TEST_PACKAGE_NAME_C,
|
||||
"CredManProviderC3",
|
||||
"test app C3",
|
||||
TEST_TITLE_SERVICE_C)
|
||||
.setEnabled(true)
|
||||
.build();
|
||||
|
||||
CredentialManagerPreferenceController controller =
|
||||
createControllerWithServices(
|
||||
Lists.newArrayList(serviceA1, serviceB1, serviceC1, serviceC2, serviceC3));
|
||||
controller.displayPreference(mScreen);
|
||||
|
||||
assertThat(controller.isConnected()).isFalse();
|
||||
assertThat(mCredentialsPreferenceCategory.getPreferenceCount()).isEqualTo(3);
|
||||
|
||||
Map<String, SwitchPreference> prefs =
|
||||
controller.buildPreferenceList(mContext, mCredentialsPreferenceCategory);
|
||||
assertThat(prefs.size()).isEqualTo(3);
|
||||
assertThat(prefs.containsKey(TEST_PACKAGE_NAME_A)).isTrue();
|
||||
assertThat(prefs.get(TEST_PACKAGE_NAME_A).getTitle()).isEqualTo(TEST_TITLE_APP_A);
|
||||
assertThat(prefs.get(TEST_PACKAGE_NAME_A).isChecked()).isFalse();
|
||||
assertThat(prefs.containsKey(TEST_PACKAGE_NAME_B)).isTrue();
|
||||
assertThat(prefs.get(TEST_PACKAGE_NAME_B).getTitle()).isEqualTo(TEST_TITLE_APP_B);
|
||||
assertThat(prefs.get(TEST_PACKAGE_NAME_B).isChecked()).isFalse();
|
||||
assertThat(prefs.containsKey(TEST_PACKAGE_NAME_C)).isTrue();
|
||||
assertThat(prefs.get(TEST_PACKAGE_NAME_C).getTitle()).isEqualTo(TEST_TITLE_SERVICE_C);
|
||||
assertThat(prefs.get(TEST_PACKAGE_NAME_C).isChecked()).isTrue();
|
||||
}
|
||||
|
||||
private CredentialManagerPreferenceController createControllerWithServices(
|
||||
List<CredentialProviderInfo> availableServices) {
|
||||
CredentialManagerPreferenceController controller =
|
||||
@@ -259,23 +324,34 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
|
||||
private CredentialProviderInfo createCredentialProviderInfo(
|
||||
String packageName, String className) {
|
||||
return createCredentialProviderInfo(packageName, className, null, false);
|
||||
return createCredentialProviderInfoBuilder(packageName, className, null, "App Name")
|
||||
.build();
|
||||
}
|
||||
|
||||
private CredentialProviderInfo createCredentialProviderInfo(
|
||||
String packageName, String className, CharSequence label, boolean isEnabled) {
|
||||
ServiceInfo si = new ServiceInfo();
|
||||
si.packageName = packageName;
|
||||
si.name = className;
|
||||
si.nonLocalizedLabel = "test";
|
||||
|
||||
si.applicationInfo = new ApplicationInfo();
|
||||
si.applicationInfo.packageName = packageName;
|
||||
si.applicationInfo.nonLocalizedLabel = "test";
|
||||
|
||||
return new CredentialProviderInfo.Builder(si)
|
||||
.setOverrideLabel(label)
|
||||
private CredentialProviderInfo createCredentialProviderInfoWithIsEnabled(
|
||||
String packageName, String className, CharSequence serviceLabel, boolean isEnabled) {
|
||||
return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, "App Name")
|
||||
.setEnabled(isEnabled)
|
||||
.build();
|
||||
}
|
||||
|
||||
private CredentialProviderInfo createCredentialProviderInfoWithAppLabel(
|
||||
String packageName, String className, CharSequence serviceLabel, String appLabel) {
|
||||
return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, appLabel)
|
||||
.build();
|
||||
}
|
||||
|
||||
private CredentialProviderInfo.Builder createCredentialProviderInfoBuilder(
|
||||
String packageName, String className, CharSequence serviceLabel, String appLabel) {
|
||||
ServiceInfo si = new ServiceInfo();
|
||||
si.packageName = packageName;
|
||||
si.name = className;
|
||||
si.nonLocalizedLabel = serviceLabel;
|
||||
|
||||
si.applicationInfo = new ApplicationInfo();
|
||||
si.applicationInfo.packageName = packageName;
|
||||
si.applicationInfo.nonLocalizedLabel = appLabel;
|
||||
|
||||
return new CredentialProviderInfo.Builder(si).setOverrideLabel(serviceLabel);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.language;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.Settings;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class LanguagePreferenceControllerTest {
|
||||
private boolean mCacheFeatureFlagSwitch = false;
|
||||
private Context mContext;
|
||||
private LanguagePreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
mCacheFeatureFlagSwitch =
|
||||
FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
|
||||
mController = new LanguagePreferenceController(mContext, "key");
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
FeatureFlagUtils.setEnabled(
|
||||
mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI, mCacheFeatureFlagSwitch);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_featureFlagOff_returnUnavailable() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI,
|
||||
false);
|
||||
|
||||
int result = mController.getAvailabilityStatus();
|
||||
|
||||
assertEquals(CONDITIONALLY_UNAVAILABLE, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_featureFlagOff_LanguageAndInputSettingsActivityEnabled() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI,
|
||||
false);
|
||||
|
||||
mController.getAvailabilityStatus();
|
||||
|
||||
assertTrue(isActivityEnable(mContext, Settings.LanguageAndInputSettingsActivity.class));
|
||||
assertFalse(isActivityEnable(mContext, Settings.LanguageSettingsActivity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_featureFlagOff_LanguageAndInputSettingsActivitydisabled() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI,
|
||||
true);
|
||||
|
||||
mController.getAvailabilityStatus();
|
||||
|
||||
assertFalse(isActivityEnable(mContext, Settings.LanguageAndInputSettingsActivity.class));
|
||||
assertTrue(isActivityEnable(mContext, Settings.LanguageSettingsActivity.class));
|
||||
}
|
||||
|
||||
private static boolean isActivityEnable(Context context, Class klazz) {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
ComponentName componentName =
|
||||
new ComponentName(context, klazz);
|
||||
int flag = packageManager.getComponentEnabledSetting(componentName);
|
||||
return flag == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
|
||||
}
|
||||
}
|
@@ -28,9 +28,11 @@ import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.os.PersistableBundle;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
@@ -61,6 +63,10 @@ public class AutoSelectPreferenceControllerTest {
|
||||
private CarrierConfigCache mCarrierConfigCache;
|
||||
@Mock
|
||||
private ProgressDialog mProgressDialog;
|
||||
@Mock
|
||||
private ServiceState mTestServiceState;
|
||||
@Mock
|
||||
private Lifecycle mLifecycle;
|
||||
|
||||
private PersistableBundle mCarrierConfig;
|
||||
private AutoSelectPreferenceController mController;
|
||||
@@ -88,7 +94,16 @@ public class AutoSelectPreferenceControllerTest {
|
||||
mController = new AutoSelectPreferenceController(mContext, "auto_select");
|
||||
mController.mProgressDialog = mProgressDialog;
|
||||
mController.mSwitchPreference = mSwitchPreference;
|
||||
mController.init(SUB_ID);
|
||||
mController.init(mLifecycle, SUB_ID);
|
||||
sleepAfterInit();
|
||||
}
|
||||
|
||||
private void sleepAfterInit() {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (Exception e) {
|
||||
fail("Sleep timeout " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -111,7 +126,8 @@ public class AutoSelectPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void updateState_isRoaming_enabled() {
|
||||
when(mTelephonyManager.getServiceState().getRoaming()).thenReturn(true);
|
||||
when(mTelephonyManager.getServiceState()).thenReturn(mTestServiceState);
|
||||
when(mTestServiceState.getRoaming()).thenReturn(true);
|
||||
|
||||
mController.updateState(mSwitchPreference);
|
||||
|
||||
@@ -120,7 +136,8 @@ public class AutoSelectPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void updateState_notRoamingWithAutoSelectOn_disabled() {
|
||||
when(mTelephonyManager.getServiceState().getRoaming()).thenReturn(false);
|
||||
when(mTelephonyManager.getServiceState()).thenReturn(mTestServiceState);
|
||||
when(mTestServiceState.getRoaming()).thenReturn(false);
|
||||
doReturn(OPERATOR_NAME).when(mTelephonyManager).getSimOperatorName();
|
||||
|
||||
mController.updateState(mSwitchPreference);
|
||||
@@ -136,6 +153,34 @@ public class AutoSelectPreferenceControllerTest {
|
||||
when(mCarrierConfigCache.getConfigForSubId(SUB_ID)).thenReturn(null);
|
||||
|
||||
// Should not crash
|
||||
mController.init(SUB_ID);
|
||||
mController.init(mLifecycle, SUB_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUiAutoSelectValue_serviceStateGetIsManualSelection_isCheckedFalse() {
|
||||
when(mTelephonyManager.getNetworkSelectionMode()).thenReturn(
|
||||
TelephonyManager.NETWORK_SELECTION_MODE_AUTO);
|
||||
when(mTestServiceState.getIsManualSelection()).thenReturn(true);
|
||||
mController.init(mLifecycle, SUB_ID);
|
||||
sleepAfterInit();
|
||||
|
||||
mController.updateUiAutoSelectValue(mTestServiceState);
|
||||
|
||||
assertThat(mController.isChecked()).isFalse();
|
||||
assertThat(mSwitchPreference.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUiAutoSelectValue_serviceStateGetIsAutoSelection_isCheckedTrue() {
|
||||
when(mTelephonyManager.getNetworkSelectionMode()).thenReturn(
|
||||
TelephonyManager.NETWORK_SELECTION_MODE_MANUAL);
|
||||
when(mTestServiceState.getIsManualSelection()).thenReturn(false);
|
||||
mController.init(mLifecycle, SUB_ID);
|
||||
sleepAfterInit();
|
||||
|
||||
mController.updateUiAutoSelectValue(mTestServiceState);
|
||||
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
assertThat(mSwitchPreference.isChecked()).isTrue();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user