Snap for 6441286 from 8b4406dadb to mainline-release
Change-Id: Idbec9cdd4023fa93a66fb3ea889c51f2fb4d30fe
This commit is contained in:
25
res/drawable/ic_delete_x.xml
Normal file
25
res/drawable/ic_delete_x.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
|
||||
</vector>
|
||||
28
res/drawable/ic_lock_closed.xml
Normal file
28
res/drawable/ic_lock_closed.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<!--
|
||||
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
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,15m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M18,8h-1.5V5.5C16.5,3.01 14.49,1 12,1S7.5,3.01 7.5,5.5V8H6c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V10C20,8.9 19.1,8 18,8zM9.5,5.5C9.5,4.12 10.62,3 12,3c1.38,0 2.5,1.12 2.5,2.5V8h-5V5.5zM18,20H6V10h1.5h9H18V20z"/>
|
||||
</vector>
|
||||
24
res/layout/bubble_conversation_remove_button.xml
Normal file
24
res/layout/bubble_conversation_remove_button.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?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.
|
||||
-->
|
||||
<ImageButton
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:scaleType="centerInside"
|
||||
android:tint="?android:attr/textColorSecondary"
|
||||
android:src="@drawable/ic_delete_x"/>
|
||||
@@ -1148,14 +1148,14 @@
|
||||
<item>@string/zen_mode_from_anyone</item>
|
||||
<item>@string/zen_mode_from_contacts</item>
|
||||
<item>@string/zen_mode_from_starred</item>
|
||||
<item>@string/zen_mode_from_none_messages</item>
|
||||
<item>@string/zen_mode_none_messages</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="zen_mode_contacts_calls_entries" translatable="false">
|
||||
<item>@string/zen_mode_from_anyone</item>
|
||||
<item>@string/zen_mode_from_contacts</item>
|
||||
<item>@string/zen_mode_from_starred</item>
|
||||
<item>@string/zen_mode_from_none_calls</item>
|
||||
<item>@string/zen_mode_none_calls</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="zen_mode_contacts_values" translatable="false">
|
||||
|
||||
@@ -8465,6 +8465,8 @@
|
||||
<!-- [CHAR LIMIT=150] Notification Importance title: important conversation level summary -->
|
||||
<string name="notification_channel_summary_priority">Shows at top of conversation section and appears as a bubble.</string>
|
||||
|
||||
<string name="convo_not_supported_summary"><xliff:g id="app_name" example="Android Services">%1$s</xliff:g> does not support conversation-specific settings.</string>
|
||||
|
||||
<!-- Channel summaries for the app notification page -->
|
||||
|
||||
<!-- [CHAR LIMIT=150] Notification Importance title: min importance level summary -->
|
||||
@@ -8976,6 +8978,8 @@
|
||||
<item quantity="one">1 other</item>
|
||||
<item quantity="other"><xliff:g id="num_people" example="3">%d</xliff:g> others</item>
|
||||
</plurals>
|
||||
<!-- [CHAR LIMIT=40] Zen mode settings: Starred contacts summary when there are no starred contacts -->
|
||||
<string name="zen_mode_starred_contacts_summary_none">None</string>
|
||||
|
||||
<!-- [CHAR LIMIT=40] Zen mode settings: Messages option -->
|
||||
<string name="zen_mode_messages">Messages</string>
|
||||
@@ -8995,8 +8999,13 @@
|
||||
<!-- Zen mode settings: All calls can bypass DND summary [CHAR LIMIT=NONE -->
|
||||
<string name="zen_mode_all_calls_summary">All calls can reach you</string>
|
||||
|
||||
<!-- Zen mode settings: Senders in contacts can bypass DND summary summary [CHAR LIMIT=NONE -->
|
||||
<string name="zen_mode_contacts_senders_summary"><xliff:g id="num_contacts" example="120">%d</xliff:g> contacts</string>
|
||||
<!-- Zen mode settings: There are no contacts on the device [CHAR LIMIT=NONE] -->
|
||||
<string name="zen_mode_contacts_count_none">None</string>
|
||||
<!-- Zen mode settings: Senders in contacts can bypass DND summary summary [CHAR LIMIT=NONE] -->
|
||||
<plurals name="zen_mode_contacts_count">
|
||||
<item quantity="one">1 contact</item>
|
||||
<item quantity="other"><xliff:g id="num_contacts" example="120">%d</xliff:g> contacts</item>
|
||||
</plurals>
|
||||
|
||||
<!-- [CHAR LIMIT=40] Zen mode settings: Calls or messages option value: From anyone -->
|
||||
<string name="zen_mode_from_anyone">Anyone</string>
|
||||
@@ -9004,8 +9013,6 @@
|
||||
<string name="zen_mode_from_contacts">Contacts</string>
|
||||
<!-- [CHAR LIMIT=40] Zen mode settings: Calls or messages option value: From starred contacts only -->
|
||||
<string name="zen_mode_from_starred">Starred contacts</string>
|
||||
<!-- [CHAR LIMIT=40] Zen mode settings: Calls and/or messages from none-->
|
||||
<string name="zen_mode_from_none">None</string>
|
||||
|
||||
<!-- Do not disturb settings, calls summary [CHAR LIMIT=100]-->
|
||||
<string name="zen_calls_summary_starred_repeat">From starred contacts and repeat callers</string>
|
||||
@@ -9015,9 +9022,9 @@
|
||||
<string name="zen_calls_summary_repeat_only">From repeat callers only</string>
|
||||
|
||||
<!-- [CHAR LIMIT=40] Zen mode settings: Calls option value: No calls allowed -->
|
||||
<string name="zen_mode_from_none_calls">Don\u2019t allow any calls</string>
|
||||
<string name="zen_mode_none_calls">None</string>
|
||||
<!-- [CHAR LIMIT=40] Zen mode settings: Messages option value: No messages allowed -->
|
||||
<string name="zen_mode_from_none_messages">Don\u2019t allow any messages</string>
|
||||
<string name="zen_mode_none_messages">None</string>
|
||||
|
||||
<!-- [CHAR LIMIT=80] Zen mode settings: Allow alarms option -->
|
||||
<string name="zen_mode_alarms">Alarms</string>
|
||||
|
||||
@@ -27,4 +27,12 @@
|
||||
android:title="@string/notification_bubbles_title"
|
||||
settings:allowDividerBelow="false"/>
|
||||
|
||||
<!-- Selected or excluded conversations get added here -->
|
||||
<PreferenceCategory
|
||||
android:title="@string/bubble_app_setting_selected_conversation_title"
|
||||
android:key="bubble_conversations"
|
||||
android:visibility="gone"
|
||||
settings:allowDividerAbove="false"
|
||||
settings:allowDividerBelow="false" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -78,14 +78,14 @@
|
||||
android:key="ringtone"
|
||||
android:title="@string/notification_channel_sound_title"
|
||||
android:dialogTitle="@string/notification_channel_sound_title"
|
||||
android:icon="@drawable/ic_media_stream"
|
||||
android:icon="@drawable/ic_notifications"
|
||||
android:showSilent="true"
|
||||
android:showDefault="true"/>
|
||||
|
||||
<!-- Visibility Override -->
|
||||
<com.android.settings.RestrictedListPreference
|
||||
android:key="visibility_override"
|
||||
android:icon="@drawable/ic_lock"
|
||||
android:icon="@drawable/ic_lock_closed"
|
||||
android:title="@string/app_notification_visibility_override_title"/>
|
||||
|
||||
<!-- Show badge -->
|
||||
|
||||
@@ -57,6 +57,7 @@ import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
@@ -1089,4 +1090,15 @@ public final class Utils extends com.android.settingslib.Utils {
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if current binder uid is Settings Intelligence.
|
||||
*/
|
||||
public static boolean isSettingsIntelligence(Context context) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final String callingPackage = context.getPackageManager().getPackagesForUid(callingUid)[0];
|
||||
final boolean isSettingsIntelligence = TextUtils.equals(callingPackage,
|
||||
context.getString(R.string.config_settingsintelligence_package_name));
|
||||
return isSettingsIntelligence;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ public class AccessibilitySettings extends DashboardFragment {
|
||||
|
||||
final CharSequence serviceState;
|
||||
final int fragmentType = AccessibilityUtil.getAccessibilityServiceFragmentType(info);
|
||||
if (fragmentType == AccessibilityServiceFragmentType.INVISIBLE) {
|
||||
if (fragmentType == AccessibilityServiceFragmentType.INVISIBLE_TOGGLE) {
|
||||
final ComponentName componentName = new ComponentName(
|
||||
info.getResolveInfo().serviceInfo.packageName,
|
||||
info.getResolveInfo().serviceInfo.name);
|
||||
@@ -652,13 +652,16 @@ public class AccessibilitySettings extends DashboardFragment {
|
||||
}
|
||||
|
||||
private String getAccessibilityServiceFragmentTypeName(AccessibilityServiceInfo info) {
|
||||
switch (AccessibilityUtil.getAccessibilityServiceFragmentType(
|
||||
info)) {
|
||||
case AccessibilityServiceFragmentType.LEGACY:
|
||||
return LegacyAccessibilityServicePreferenceFragment.class.getName();
|
||||
case AccessibilityServiceFragmentType.INVISIBLE:
|
||||
// Shorten the name to avoid exceeding 100 characters in one line.
|
||||
final String volumeShortcutToggleAccessibilityServicePreferenceFragment =
|
||||
VolumeShortcutToggleAccessibilityServicePreferenceFragment.class.getName();
|
||||
|
||||
switch (AccessibilityUtil.getAccessibilityServiceFragmentType(info)) {
|
||||
case AccessibilityServiceFragmentType.VOLUME_SHORTCUT_TOGGLE:
|
||||
return volumeShortcutToggleAccessibilityServicePreferenceFragment;
|
||||
case AccessibilityServiceFragmentType.INVISIBLE_TOGGLE:
|
||||
return InvisibleToggleAccessibilityServicePreferenceFragment.class.getName();
|
||||
case AccessibilityServiceFragmentType.INTUITIVE:
|
||||
case AccessibilityServiceFragmentType.TOGGLE:
|
||||
return ToggleAccessibilityServicePreferenceFragment.class.getName();
|
||||
default:
|
||||
// impossible status
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.AccessibilityServiceFragmentType.LEGACY;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.AccessibilityServiceFragmentType.VOLUME_SHORTCUT_TOGGLE;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.app.settings.SettingsEnums;
|
||||
@@ -102,10 +102,10 @@ public class AccessibilitySettingsForSetupWizard extends SettingsPreferenceFragm
|
||||
super.onResume();
|
||||
updateAccessibilityServicePreference(mScreenReaderPreference,
|
||||
SCREEN_READER_PACKAGE_NAME, SCREEN_READER_SERVICE_NAME,
|
||||
LegacyToggleScreenReaderPreferenceFragmentForSetupWizard.class.getName());
|
||||
VolumeShortcutToggleScreenReaderPreferenceFragmentForSetupWizard.class.getName());
|
||||
updateAccessibilityServicePreference(mSelectToSpeakPreference,
|
||||
SELECT_TO_SPEAK_PACKAGE_NAME, SELECT_TO_SPEAK_SERVICE_NAME,
|
||||
LegacyToggleSelectToSpeakPreferenceFragmentForSetupWizard.class.getName());
|
||||
VolumeShortcutToggleSelectToSpeakPreferenceFragmentForSetupWizard.class.getName());
|
||||
configureMagnificationPreferenceIfNeeded(mDisplayMagnificationPreference);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ public class AccessibilitySettingsForSetupWizard extends SettingsPreferenceFragm
|
||||
}
|
||||
|
||||
private void updateAccessibilityServicePreference(Preference preference,
|
||||
String packageName, String serviceName, String targetLegacyFragment) {
|
||||
String packageName, String serviceName, String targetFragment) {
|
||||
final AccessibilityServiceInfo info = findService(packageName, serviceName);
|
||||
if (info == null) {
|
||||
getPreferenceScreen().removePreference(preference);
|
||||
@@ -159,8 +159,8 @@ public class AccessibilitySettingsForSetupWizard extends SettingsPreferenceFragm
|
||||
preference.setTitle(title);
|
||||
ComponentName componentName = new ComponentName(serviceInfo.packageName, serviceInfo.name);
|
||||
preference.setKey(componentName.flattenToString());
|
||||
if (AccessibilityUtil.getAccessibilityServiceFragmentType(info) == LEGACY) {
|
||||
preference.setFragment(targetLegacyFragment);
|
||||
if (AccessibilityUtil.getAccessibilityServiceFragmentType(info) == VOLUME_SHORTCUT_TOGGLE) {
|
||||
preference.setFragment(targetFragment);
|
||||
}
|
||||
|
||||
// Update the extras.
|
||||
|
||||
@@ -46,22 +46,23 @@ final class AccessibilityUtil {
|
||||
/**
|
||||
* Annotation for different accessibilityService fragment UI type.
|
||||
*
|
||||
* {@code LEGACY} for displaying appearance aligned with sdk version Q accessibility service
|
||||
* page, but only hardware shortcut allowed.
|
||||
* {@code INVISIBLE} for displaying appearance without switch bar.
|
||||
* {@code INTUITIVE} for displaying appearance with new design.
|
||||
* {@code VOLUME_SHORTCUT_TOGGLE} for displaying basic accessibility service fragment but
|
||||
* only hardware shortcut allowed.
|
||||
* {@code INVISIBLE_TOGGLE} for displaying basic accessibility service fragment without
|
||||
* switch bar.
|
||||
* {@code TOGGLE} for displaying basic accessibility service fragment.
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
AccessibilityServiceFragmentType.LEGACY,
|
||||
AccessibilityServiceFragmentType.INVISIBLE,
|
||||
AccessibilityServiceFragmentType.INTUITIVE,
|
||||
AccessibilityServiceFragmentType.VOLUME_SHORTCUT_TOGGLE,
|
||||
AccessibilityServiceFragmentType.INVISIBLE_TOGGLE,
|
||||
AccessibilityServiceFragmentType.TOGGLE,
|
||||
})
|
||||
|
||||
public @interface AccessibilityServiceFragmentType {
|
||||
int LEGACY = 0;
|
||||
int INVISIBLE = 1;
|
||||
int INTUITIVE = 2;
|
||||
int VOLUME_SHORTCUT_TOGGLE = 0;
|
||||
int INVISIBLE_TOGGLE = 1;
|
||||
int TOGGLE = 2;
|
||||
}
|
||||
|
||||
// TODO(b/147021230): Will move common functions and variables to
|
||||
@@ -162,11 +163,11 @@ final class AccessibilityUtil {
|
||||
& AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0;
|
||||
|
||||
if (targetSdk <= Build.VERSION_CODES.Q) {
|
||||
return AccessibilityServiceFragmentType.LEGACY;
|
||||
return AccessibilityServiceFragmentType.VOLUME_SHORTCUT_TOGGLE;
|
||||
}
|
||||
return requestA11yButton
|
||||
? AccessibilityServiceFragmentType.INVISIBLE
|
||||
: AccessibilityServiceFragmentType.INTUITIVE;
|
||||
? AccessibilityServiceFragmentType.INVISIBLE_TOGGLE
|
||||
: AccessibilityServiceFragmentType.TOGGLE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,7 +34,7 @@ import com.google.common.collect.ImmutableSet;
|
||||
*
|
||||
* <p>For accessibility services that target SDK <= Q.
|
||||
*/
|
||||
public class LegacyAccessibilityServicePreferenceFragment extends
|
||||
public class VolumeShortcutToggleAccessibilityServicePreferenceFragment extends
|
||||
ToggleAccessibilityServicePreferenceFragment {
|
||||
|
||||
@Override
|
||||
@@ -21,8 +21,8 @@ import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
/** For accessibility services that target SDK <= Q in setup wizard. */
|
||||
public class LegacyToggleScreenReaderPreferenceFragmentForSetupWizard
|
||||
extends LegacyAccessibilityServicePreferenceFragment {
|
||||
public class VolumeShortcutToggleScreenReaderPreferenceFragmentForSetupWizard
|
||||
extends VolumeShortcutToggleAccessibilityServicePreferenceFragment {
|
||||
|
||||
private boolean mToggleSwitchWasInitiallyChecked;
|
||||
|
||||
@@ -21,8 +21,8 @@ import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
/** For accessibility services that target SDK <= Q in setup wizard. */
|
||||
public class LegacyToggleSelectToSpeakPreferenceFragmentForSetupWizard
|
||||
extends LegacyAccessibilityServicePreferenceFragment {
|
||||
public class VolumeShortcutToggleSelectToSpeakPreferenceFragmentForSetupWizard
|
||||
extends VolumeShortcutToggleAccessibilityServicePreferenceFragment {
|
||||
|
||||
private boolean mToggleSwitchWasInitiallyChecked;
|
||||
|
||||
@@ -114,6 +114,7 @@ public class DataUsageSummaryPreferenceController extends TelephonyBasePreferenc
|
||||
*/
|
||||
public void init(int subscriptionId) {
|
||||
mSubId = subscriptionId;
|
||||
mHasMobileData = DataUsageUtils.hasMobileData(mContext);
|
||||
mDataUsageController = null;
|
||||
}
|
||||
|
||||
@@ -123,8 +124,6 @@ public class DataUsageSummaryPreferenceController extends TelephonyBasePreferenc
|
||||
context.getSystemService(NetworkPolicyManager.class);
|
||||
mPolicyEditor = new NetworkPolicyEditor(policyManager);
|
||||
|
||||
mHasMobileData = DataUsageUtils.hasMobileData(context);
|
||||
|
||||
mDataUsageController = new DataUsageController(context);
|
||||
mDataUsageController.setSubscriptionId(subscriptionId);
|
||||
mDataInfoController = new DataUsageInfoController();
|
||||
@@ -210,6 +209,11 @@ public class DataUsageSummaryPreferenceController extends TelephonyBasePreferenc
|
||||
final DataUsageController.DataUsageInfo info =
|
||||
mDataUsageController.getDataUsageInfo(mDefaultTemplate);
|
||||
|
||||
long usageLevel = info.usageLevel;
|
||||
if (usageLevel <= 0L) {
|
||||
usageLevel = mDataUsageController.getHistoricalUsageLevel(mDefaultTemplate);
|
||||
}
|
||||
|
||||
if (subInfo != null) {
|
||||
mDataInfoController.updateDataLimit(info, mPolicyEditor.getPolicy(mDefaultTemplate));
|
||||
summaryPreference.setWifiMode(/* isWifiMode */ false,
|
||||
@@ -218,7 +222,7 @@ public class DataUsageSummaryPreferenceController extends TelephonyBasePreferenc
|
||||
summaryPreference.setWifiMode(/* isWifiMode */ true, /* usagePeriod */
|
||||
info.period, /* isSingleWifi */ false);
|
||||
summaryPreference.setLimitInfo(null);
|
||||
summaryPreference.setUsageNumbers(info.usageLevel,
|
||||
summaryPreference.setUsageNumbers(usageLevel,
|
||||
/* dataPlanSize */ -1L,
|
||||
/* hasMobileData */ true);
|
||||
summaryPreference.setChartEnabled(false);
|
||||
@@ -231,6 +235,11 @@ public class DataUsageSummaryPreferenceController extends TelephonyBasePreferenc
|
||||
}
|
||||
|
||||
refreshDataplanInfo(info, subInfo);
|
||||
if ((mDataplanUse <= 0L) && (mSnapshotTime < 0)) {
|
||||
Log.d(TAG, "Display data usage from history");
|
||||
mDataplanUse = usageLevel;
|
||||
mSnapshotTime = -1L;
|
||||
}
|
||||
|
||||
if (info.warningLevel > 0 && info.limitLevel > 0) {
|
||||
summaryPreference.setLimitInfo(TextUtils.expandTemplate(
|
||||
|
||||
@@ -70,6 +70,16 @@ import java.util.List;
|
||||
public class StorageSettings extends SettingsPreferenceFragment implements Indexable {
|
||||
static final String TAG = "StorageSettings";
|
||||
|
||||
private static final String KEY_STORAGE_SETTINGS = "storage_settings";
|
||||
private static final String KEY_INTERNAL_STORAGE = "storage_settings_internal_storage";
|
||||
private static final String KEY_STORAGE_SETTINGS_VOLUME = "storage_settings_volume_";
|
||||
private static final String KEY_STORAGE_SETTINGS_MEMORY_SIZE = "storage_settings_memory_size";
|
||||
private static final String KEY_STORAGE_SETTINGS_MEMORY = "storage_settings_memory_available";
|
||||
private static final String KEY_STORAGE_SETTINGS_DCIM = "storage_settings_dcim_space";
|
||||
private static final String KEY_STORAGE_SETTINGS_MUSIC = "storage_settings_music_space";
|
||||
private static final String KEY_STORAGE_SETTINGS_MISC = "storage_settings_misc_space";
|
||||
private static final String KEY_STORAGE_SETTINGS_FREE_SPACE = "storage_settings_free_space";
|
||||
|
||||
private static final String TAG_VOLUME_UNMOUNTED = "volume_unmounted";
|
||||
private static final String TAG_DISK_INIT = "disk_init";
|
||||
private static final int METRICS_CATEGORY = SettingsEnums.DEVICEINFO_STORAGE;
|
||||
@@ -551,14 +561,14 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
|
||||
|
||||
SearchIndexableRaw data = new SearchIndexableRaw(context);
|
||||
data.title = context.getString(R.string.storage_settings);
|
||||
data.key = "storage_settings";
|
||||
data.key = KEY_STORAGE_SETTINGS;
|
||||
data.screenTitle = context.getString(R.string.storage_settings);
|
||||
data.keywords = context.getString(R.string.keywords_storage_settings);
|
||||
result.add(data);
|
||||
|
||||
data = new SearchIndexableRaw(context);
|
||||
data.title = context.getString(R.string.internal_storage);
|
||||
data.key = "storage_settings_internal_storage";
|
||||
data.key = KEY_INTERNAL_STORAGE;
|
||||
data.screenTitle = context.getString(R.string.storage_settings);
|
||||
result.add(data);
|
||||
|
||||
@@ -568,7 +578,7 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
|
||||
for (VolumeInfo vol : vols) {
|
||||
if (isInteresting(vol)) {
|
||||
data.title = storage.getBestVolumeDescription(vol);
|
||||
data.key = "storage_settings_volume_" + vol.id;
|
||||
data.key = KEY_STORAGE_SETTINGS_VOLUME + vol.id;
|
||||
data.screenTitle = context.getString(R.string.storage_settings);
|
||||
result.add(data);
|
||||
}
|
||||
@@ -576,37 +586,37 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
|
||||
|
||||
data = new SearchIndexableRaw(context);
|
||||
data.title = context.getString(R.string.memory_size);
|
||||
data.key = "storage_settings_memory_size";
|
||||
data.key = KEY_STORAGE_SETTINGS_MEMORY_SIZE;
|
||||
data.screenTitle = context.getString(R.string.storage_settings);
|
||||
result.add(data);
|
||||
|
||||
data = new SearchIndexableRaw(context);
|
||||
data.title = context.getString(R.string.memory_available);
|
||||
data.key = "storage_settings_memory_available";
|
||||
data.key = KEY_STORAGE_SETTINGS_MEMORY;
|
||||
data.screenTitle = context.getString(R.string.storage_settings);
|
||||
result.add(data);
|
||||
|
||||
data = new SearchIndexableRaw(context);
|
||||
data.title = context.getString(R.string.memory_dcim_usage);
|
||||
data.key = "storage_settings_dcim_space";
|
||||
data.key = KEY_STORAGE_SETTINGS_DCIM;
|
||||
data.screenTitle = context.getString(R.string.storage_settings);
|
||||
result.add(data);
|
||||
|
||||
data = new SearchIndexableRaw(context);
|
||||
data.title = context.getString(R.string.memory_music_usage);
|
||||
data.key = "storage_settings_music_space";
|
||||
data.key = KEY_STORAGE_SETTINGS_MUSIC;
|
||||
data.screenTitle = context.getString(R.string.storage_settings);
|
||||
result.add(data);
|
||||
|
||||
data = new SearchIndexableRaw(context);
|
||||
data.title = context.getString(R.string.memory_media_misc_usage);
|
||||
data.key = "storage_settings_misc_space";
|
||||
data.key = KEY_STORAGE_SETTINGS_MISC;
|
||||
data.screenTitle = context.getString(R.string.storage_settings);
|
||||
result.add(data);
|
||||
|
||||
data = new SearchIndexableRaw(context);
|
||||
data.title = context.getString(R.string.storage_menu_free);
|
||||
data.key = "storage_settings_free_space";
|
||||
data.key = KEY_STORAGE_SETTINGS_FREE_SPACE;
|
||||
data.screenTitle = context.getString(R.string.storage_menu_free);
|
||||
// We need to define all three in order for this to trigger properly.
|
||||
data.intentAction = StorageManager.ACTION_MANAGE_STORAGE;
|
||||
@@ -618,5 +628,69 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNonIndexableKeys(Context context) {
|
||||
final List<String> niks = super.getNonIndexableKeys(context);
|
||||
if (isExternalExist(context)) {
|
||||
niks.add(KEY_STORAGE_SETTINGS);
|
||||
niks.add(KEY_INTERNAL_STORAGE);
|
||||
niks.add(KEY_STORAGE_SETTINGS_MEMORY_SIZE);
|
||||
niks.add(KEY_STORAGE_SETTINGS_MEMORY);
|
||||
niks.add(KEY_STORAGE_SETTINGS_DCIM);
|
||||
niks.add(KEY_STORAGE_SETTINGS_MUSIC);
|
||||
niks.add(KEY_STORAGE_SETTINGS_MISC);
|
||||
niks.add(KEY_STORAGE_SETTINGS_FREE_SPACE);
|
||||
|
||||
final StorageManager storage = context.getSystemService(
|
||||
StorageManager.class);
|
||||
final List<VolumeInfo> vols = storage.getVolumes();
|
||||
for (VolumeInfo vol : vols) {
|
||||
if (isInteresting(vol)) {
|
||||
niks.add(KEY_STORAGE_SETTINGS_VOLUME + vol.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return niks;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isPageSearchEnabled(Context context) {
|
||||
return !isExternalExist(context);
|
||||
}
|
||||
|
||||
private boolean isExternalExist(Context context) {
|
||||
int internalCount = 0;
|
||||
StorageManager storageManager = context.getSystemService(StorageManager.class);
|
||||
final List<VolumeInfo> volumes = storageManager.getVolumes();
|
||||
for (VolumeInfo vol : volumes) {
|
||||
//External storage
|
||||
if (vol.getType() == VolumeInfo.TYPE_PUBLIC
|
||||
|| vol.getType() == VolumeInfo.TYPE_STUB) {
|
||||
return true;
|
||||
} else if (vol.getType() == VolumeInfo.TYPE_PRIVATE) {
|
||||
internalCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Unsupported disks
|
||||
final List<DiskInfo> disks = storageManager.getDisks();
|
||||
for (DiskInfo disk : disks) {
|
||||
if (disk.volumeCount == 0 && disk.size > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Missing private volumes
|
||||
final List<VolumeRecord> recs = storageManager.getVolumeRecords();
|
||||
for (VolumeRecord rec : recs) {
|
||||
if (rec.getType() == VolumeInfo.TYPE_PRIVATE
|
||||
&& storageManager.findVolumeByUuid(rec.getFsUuid()) == null) {
|
||||
internalCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return (internalCount != 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -20,8 +20,10 @@ import android.content.Context;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.widget.GearPreference;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
import com.android.settingslib.dream.DreamBackend;
|
||||
import com.android.settingslib.dream.DreamBackend.DreamInfo;
|
||||
|
||||
@@ -45,6 +47,7 @@ public class CurrentDreamPreferenceController extends BasePreferenceController {
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
setGearClickListenerForPreference(preference);
|
||||
setActiveDreamIcon(preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,4 +81,13 @@ public class CurrentDreamPreferenceController extends BasePreferenceController {
|
||||
.filter((info) -> info.isActive)
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
private void setActiveDreamIcon(Preference preference) {
|
||||
if (!(preference instanceof GearPreference)) {
|
||||
return;
|
||||
}
|
||||
final GearPreference gearPref = (GearPreference) preference;
|
||||
gearPref.setIconSize(RestrictedPreference.ICON_SIZE_SMALL);
|
||||
Utils.setSafeIcon(gearPref, mBackend.getActiveIcon());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,15 +96,18 @@ public class MobileDataSlice implements CustomSliceable {
|
||||
ListBuilder.ICON_IMAGE, title);
|
||||
final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction,
|
||||
null /* actionTitle */, isMobileDataEnabled());
|
||||
final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder()
|
||||
.setTitle(title)
|
||||
.addEndItem(toggleSliceAction)
|
||||
.setPrimaryAction(primarySliceAction);
|
||||
if (!Utils.isSettingsIntelligence(mContext)) {
|
||||
rowBuilder.setSubtitle(summary);
|
||||
}
|
||||
|
||||
final ListBuilder listBuilder = new ListBuilder(mContext, getUri(),
|
||||
ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addRow(new ListBuilder.RowBuilder()
|
||||
.setTitle(title)
|
||||
.setSubtitle(summary)
|
||||
.addEndItem(toggleSliceAction)
|
||||
.setPrimaryAction(primarySliceAction));
|
||||
.addRow(rowBuilder);
|
||||
return listBuilder.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static android.app.NotificationChannel.DEFAULT_ALLOW_BUBBLE;
|
||||
import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
|
||||
import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
|
||||
import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationChannelGroup;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.notification.app.AppConversationListPreferenceController;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Displays a list of conversations that have either been selected or excluded from bubbling.
|
||||
*/
|
||||
public class AppBubbleListPreferenceController extends AppConversationListPreferenceController {
|
||||
|
||||
private static final String KEY = "bubble_conversations";
|
||||
|
||||
public AppBubbleListPreferenceController(Context context, NotificationBackend backend) {
|
||||
super(context, backend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume(NotificationBackend.AppRow appRow,
|
||||
@Nullable NotificationChannel channel, @Nullable NotificationChannelGroup group,
|
||||
Drawable conversationDrawable,
|
||||
ShortcutInfo conversationInfo,
|
||||
RestrictedLockUtils.EnforcedAdmin admin) {
|
||||
super.onResume(appRow, channel, group, conversationDrawable, conversationInfo, admin);
|
||||
// In case something changed in the foreground (e.g. via bubble button on notification)
|
||||
loadConversationsAndPopulate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
if (!super.isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
if (mAppRow.bubblePreference == BUBBLE_PREFERENCE_NONE) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@Override
|
||||
public List<ConversationChannelWrapper> filterAndSortConversations(
|
||||
List<ConversationChannelWrapper> conversations) {
|
||||
return conversations.stream()
|
||||
.sorted(mConversationComparator)
|
||||
.filter((c) -> {
|
||||
if (mAppRow.bubblePreference == BUBBLE_PREFERENCE_SELECTED) {
|
||||
return c.getNotificationChannel().canBubble();
|
||||
} else if (mAppRow.bubblePreference == BUBBLE_PREFERENCE_ALL) {
|
||||
return c.getNotificationChannel().getAllowBubbles() == 0;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getTitleResId() {
|
||||
// TODO: possible to left align like mocks?
|
||||
return mAppRow.bubblePreference == BUBBLE_PREFERENCE_SELECTED
|
||||
? R.string.bubble_app_setting_selected_conversation_title
|
||||
: R.string.bubble_app_setting_excluded_conversation_title;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@Override
|
||||
public Preference createConversationPref(final ConversationChannelWrapper conversation) {
|
||||
final ConversationPreference pref = new ConversationPreference(mContext);
|
||||
populateConversationPreference(conversation, pref);
|
||||
pref.setOnClickListener((v) -> {
|
||||
conversation.getNotificationChannel().setAllowBubbles(DEFAULT_ALLOW_BUBBLE);
|
||||
mBackend.updateChannel(mAppRow.pkg, mAppRow.uid, conversation.getNotificationChannel());
|
||||
mPreference.removePreference(pref);
|
||||
if (mPreference.getPreferenceCount() == 0) {
|
||||
mPreference.setVisible(false);
|
||||
}
|
||||
});
|
||||
return pref;
|
||||
}
|
||||
|
||||
/** Simple preference with a 'x' button at the end. */
|
||||
@VisibleForTesting
|
||||
public static class ConversationPreference extends Preference implements View.OnClickListener {
|
||||
|
||||
View.OnClickListener mOnClickListener;
|
||||
|
||||
ConversationPreference(Context context) {
|
||||
super(context);
|
||||
setWidgetLayoutResource(R.layout.bubble_conversation_remove_button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final PreferenceViewHolder holder) {
|
||||
super.onBindViewHolder(holder);
|
||||
ImageView view = holder.itemView.findViewById(R.id.button);
|
||||
view.setOnClickListener(mOnClickListener);
|
||||
}
|
||||
|
||||
public void setOnClickListener(View.OnClickListener listener) {
|
||||
mOnClickListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mOnClickListener != null) {
|
||||
mOnClickListener.onClick(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -268,6 +268,15 @@ public class NotificationBackend {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasSentMessage(String pkg, int uid) {
|
||||
try {
|
||||
return sINM.hasSentMessage(pkg, uid);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Error calling NoMan", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all notification channels associated with the package and uid that will bypass DND
|
||||
*/
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.notification.AppBubbleListPreferenceController;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
@@ -56,18 +57,20 @@ public class AppBubbleNotificationSettings extends NotificationSettings implemen
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
mControllers = getPreferenceControllers(context, this);
|
||||
mControllers = getPreferenceControllers(context, this, mDependentFieldListener);
|
||||
return new ArrayList<>(mControllers);
|
||||
}
|
||||
|
||||
protected static List<NotificationPreferenceController> getPreferenceControllers(
|
||||
Context context, AppBubbleNotificationSettings fragment) {
|
||||
Context context, AppBubbleNotificationSettings fragment,
|
||||
DependentFieldListener listener) {
|
||||
List<NotificationPreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new HeaderPreferenceController(context, fragment));
|
||||
controllers.add(new BubblePreferenceController(context, fragment != null
|
||||
? fragment.getChildFragmentManager()
|
||||
: null,
|
||||
new NotificationBackend(), true /* isAppPage */));
|
||||
new NotificationBackend(), true /* isAppPage */, listener));
|
||||
controllers.add(new AppBubbleListPreferenceController(context, new NotificationBackend()));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@@ -114,7 +117,7 @@ public class AppBubbleNotificationSettings extends NotificationSettings implemen
|
||||
public List<AbstractPreferenceController> createPreferenceControllers(Context
|
||||
context) {
|
||||
return new ArrayList<>(AppBubbleNotificationSettings.getPreferenceControllers(
|
||||
context, null));
|
||||
context, null, null));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.settings.notification.app;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
@@ -33,6 +34,7 @@ import com.android.settings.applications.AppInfoBase;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
@@ -42,8 +44,9 @@ public class AppConversationListPreferenceController extends NotificationPrefere
|
||||
private static final String KEY = "conversations";
|
||||
public static final String ARG_FROM_SETTINGS = "fromSettings";
|
||||
|
||||
private List<ConversationChannelWrapper> mConversations;
|
||||
private PreferenceCategory mPreference;
|
||||
protected List<ConversationChannelWrapper> mConversations = new ArrayList<>();
|
||||
protected PreferenceCategory mPreference;
|
||||
private boolean mHasSentMsg;
|
||||
|
||||
public AppConversationListPreferenceController(Context context, NotificationBackend backend) {
|
||||
super(context, backend);
|
||||
@@ -74,12 +77,23 @@ public class AppConversationListPreferenceController extends NotificationPrefere
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
mPreference = (PreferenceCategory) preference;
|
||||
loadConversationsAndPopulate();
|
||||
}
|
||||
|
||||
protected void loadConversationsAndPopulate() {
|
||||
if (mAppRow == null) {
|
||||
return;
|
||||
}
|
||||
// Load channel settings
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... unused) {
|
||||
mConversations = mBackend.getConversations(mAppRow.pkg, mAppRow.uid).getList();
|
||||
Collections.sort(mConversations, mConversationComparator);
|
||||
mHasSentMsg = mBackend.hasSentMessage(mAppRow.pkg, mAppRow.uid);
|
||||
ParceledListSlice<ConversationChannelWrapper> list =
|
||||
mBackend.getConversations(mAppRow.pkg, mAppRow.uid);
|
||||
if (list != null) {
|
||||
mConversations = filterAndSortConversations(list.getList());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -93,15 +107,35 @@ public class AppConversationListPreferenceController extends NotificationPrefere
|
||||
}.execute();
|
||||
}
|
||||
|
||||
protected List<ConversationChannelWrapper> filterAndSortConversations(
|
||||
List<ConversationChannelWrapper> conversations) {
|
||||
Collections.sort(conversations, mConversationComparator);
|
||||
return conversations;
|
||||
}
|
||||
|
||||
protected int getTitleResId() {
|
||||
return R.string.conversations_category_title;
|
||||
}
|
||||
|
||||
private void populateList() {
|
||||
if (mPreference == null) {
|
||||
return;
|
||||
}
|
||||
// TODO: if preference has children, compare with newly loaded list
|
||||
mPreference.removeAll();
|
||||
mPreference.setTitle(R.string.conversations_category_title);
|
||||
|
||||
if (mConversations.isEmpty()) {
|
||||
if (mHasSentMsg) {
|
||||
mPreference.setVisible(true);
|
||||
Preference notSupportedPref = new Preference(mContext);
|
||||
notSupportedPref.setSummary(mContext.getString(
|
||||
R.string.convo_not_supported_summary, mAppRow.label));
|
||||
mPreference.addPreference(notSupportedPref);
|
||||
} else {
|
||||
mPreference.setVisible(false);
|
||||
}
|
||||
} else {
|
||||
mPreference.setVisible(true);
|
||||
mPreference.setTitle(getTitleResId());
|
||||
populateConversations();
|
||||
}
|
||||
}
|
||||
@@ -117,6 +151,12 @@ public class AppConversationListPreferenceController extends NotificationPrefere
|
||||
|
||||
protected Preference createConversationPref(final ConversationChannelWrapper conversation) {
|
||||
Preference pref = new Preference(mContext);
|
||||
populateConversationPreference(conversation, pref);
|
||||
return pref;
|
||||
}
|
||||
|
||||
protected void populateConversationPreference(final ConversationChannelWrapper conversation,
|
||||
final Preference pref) {
|
||||
ShortcutInfo si = conversation.getShortcutInfo();
|
||||
|
||||
pref.setTitle(si != null
|
||||
@@ -147,7 +187,6 @@ public class AppConversationListPreferenceController extends NotificationPrefere
|
||||
.setTitleText(pref.getTitle())
|
||||
.setSourceMetricsCategory(SettingsEnums.NOTIFICATION_APP_NOTIFICATION)
|
||||
.toIntent());
|
||||
return pref;
|
||||
}
|
||||
|
||||
protected Comparator<ConversationChannelWrapper> mConversationComparator =
|
||||
|
||||
@@ -52,6 +52,8 @@ public class BubblePreference extends Preference implements View.OnClickListener
|
||||
private ButtonViewHolder mBubbleSelectedButton;
|
||||
private ButtonViewHolder mBubbleNoneButton;
|
||||
|
||||
private boolean mSelectedVisible;
|
||||
|
||||
public BubblePreference(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -89,6 +91,11 @@ public class BubblePreference extends Preference implements View.OnClickListener
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectedVisibility(boolean visible) {
|
||||
mSelectedVisible = visible;
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final PreferenceViewHolder holder) {
|
||||
super.onBindViewHolder(holder);
|
||||
@@ -122,7 +129,8 @@ public class BubblePreference extends Preference implements View.OnClickListener
|
||||
mSelectedPreference == BUBBLE_PREFERENCE_SELECTED);
|
||||
bubbleSelected.setTag(BUBBLE_PREFERENCE_SELECTED);
|
||||
bubbleSelected.setOnClickListener(this);
|
||||
bubbleSelected.setVisibility(disabledByAdmin ? View.GONE : View.VISIBLE);
|
||||
bubbleSelected.setVisibility((!mSelectedVisible || disabledByAdmin)
|
||||
? View.GONE : View.VISIBLE);
|
||||
|
||||
View bubbleNone = holder.findViewById(R.id.bubble_none);
|
||||
ImageView bubbleNoneImage = (ImageView) holder.findViewById(R.id.bubble_none_icon);
|
||||
|
||||
@@ -47,12 +47,17 @@ public class BubblePreferenceController extends NotificationPreferenceController
|
||||
|
||||
private FragmentManager mFragmentManager;
|
||||
private boolean mIsAppPage;
|
||||
private boolean mHasSentInvalidMsg;
|
||||
private int mNumConversations;
|
||||
private NotificationSettings.DependentFieldListener mListener;
|
||||
|
||||
public BubblePreferenceController(Context context, @Nullable FragmentManager fragmentManager,
|
||||
NotificationBackend backend, boolean isAppPage) {
|
||||
NotificationBackend backend, boolean isAppPage,
|
||||
@Nullable NotificationSettings.DependentFieldListener listener) {
|
||||
super(context, backend);
|
||||
mFragmentManager = fragmentManager;
|
||||
mIsAppPage = isAppPage;
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,10 +86,14 @@ public class BubblePreferenceController extends NotificationPreferenceController
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
if (mIsAppPage && mAppRow != null) {
|
||||
mHasSentInvalidMsg = mBackend.hasSentMessage(mAppRow.pkg, mAppRow.uid);
|
||||
mNumConversations = mBackend.getConversations(
|
||||
mAppRow.pkg, mAppRow.uid).getList().size();
|
||||
// We're on the app specific bubble page which displays a tri-state
|
||||
int backEndPref = mAppRow.bubblePreference;
|
||||
BubblePreference pref = (BubblePreference) preference;
|
||||
pref.setDisabledByAdmin(mAdmin);
|
||||
pref.setSelectedVisibility(!mHasSentInvalidMsg || mNumConversations > 0);
|
||||
if (!isGloballyEnabled()) {
|
||||
pref.setSelectedPreference(BUBBLE_PREFERENCE_NONE);
|
||||
} else {
|
||||
@@ -122,6 +131,9 @@ public class BubblePreferenceController extends NotificationPreferenceController
|
||||
mBackend.setAllowBubbles(mAppRow.pkg, mAppRow.uid, value);
|
||||
}
|
||||
}
|
||||
if (mListener != null) {
|
||||
mListener.onFieldValueChanged();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ public class ConversationNotificationSettings extends NotificationSettings {
|
||||
mControllers.add(new BadgePreferenceController(context, mBackend));
|
||||
mControllers.add(new NotificationsOffPreferenceController(context));
|
||||
mControllers.add(new BubblePreferenceController(context, getChildFragmentManager(),
|
||||
mBackend, false /* isAppPage */));
|
||||
mBackend, false /* isAppPage */, null /* dependentFieldListener */));
|
||||
mControllers.add(new ConversationDemotePreferenceController(context, this, mBackend));
|
||||
mControllers.add(new BubbleCategoryPreferenceController(context));
|
||||
mControllers.add(new BubbleLinkPreferenceController(context));
|
||||
|
||||
@@ -287,13 +287,13 @@ public class ZenModeBackend {
|
||||
|
||||
protected int getAlarmsTotalSilencePeopleSummary(int category) {
|
||||
if (category == NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES) {
|
||||
return R.string.zen_mode_from_none;
|
||||
return R.string.zen_mode_none_messages;
|
||||
} else if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CALLS){
|
||||
return R.string.zen_mode_from_none;
|
||||
return R.string.zen_mode_none_calls;
|
||||
} else if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS) {
|
||||
return R.string.zen_mode_from_no_conversations;
|
||||
}
|
||||
return R.string.zen_mode_from_none;
|
||||
return R.string.zen_mode_from_no_conversations;
|
||||
}
|
||||
|
||||
protected int getConversationSummary() {
|
||||
@@ -322,7 +322,7 @@ public class ZenModeBackend {
|
||||
return R.string.zen_mode_from_starred;
|
||||
case ZenPolicy.PEOPLE_TYPE_NONE:
|
||||
default:
|
||||
return R.string.zen_mode_from_none;
|
||||
return R.string.zen_mode_none_calls;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ public class ZenModeBackend {
|
||||
return R.string.zen_mode_from_starred;
|
||||
case ZenPolicy.PEOPLE_TYPE_NONE:
|
||||
default:
|
||||
return R.string.zen_mode_from_none;
|
||||
return R.string.zen_mode_none_messages;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,7 +472,7 @@ public class ZenModeBackend {
|
||||
List<String> displayContacts = new ArrayList<>();
|
||||
|
||||
if (numStarredContacts == 0) {
|
||||
displayContacts.add(context.getString(R.string.zen_mode_from_none));
|
||||
displayContacts.add(context.getString(R.string.zen_mode_starred_contacts_summary_none));
|
||||
} else {
|
||||
for (int i = 0; i < 2 && i < numStarredContacts; i++) {
|
||||
displayContacts.add(starredContacts.get(i));
|
||||
@@ -494,10 +494,11 @@ public class ZenModeBackend {
|
||||
String getContactsNumberSummary(Context context) {
|
||||
final int numContacts = queryAllContactsData().getCount();
|
||||
if (numContacts == 0) {
|
||||
return context.getResources().getString(R.string.zen_mode_from_none);
|
||||
return context.getResources().getString(
|
||||
R.string.zen_mode_contacts_count_none);
|
||||
}
|
||||
return context.getResources().getString(R.string.zen_mode_contacts_senders_summary,
|
||||
numContacts);
|
||||
return context.getResources().getQuantityString(R.plurals.zen_mode_contacts_count,
|
||||
numContacts, numContacts);
|
||||
}
|
||||
|
||||
private Cursor queryStarredContactsData() {
|
||||
|
||||
@@ -91,7 +91,9 @@ public class ZenModePrioritySendersPreferenceController
|
||||
makeRadioPreference(KEY_ANY,
|
||||
com.android.settings.R.string.zen_mode_from_anyone);
|
||||
makeRadioPreference(KEY_NONE,
|
||||
com.android.settings.R.string.zen_mode_from_none);
|
||||
mIsMessages
|
||||
? com.android.settings.R.string.zen_mode_none_messages
|
||||
: com.android.settings.R.string.zen_mode_none_calls);
|
||||
updateSummaries();
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,10 @@ public class ZenModeSendersImagePreferenceController
|
||||
newImageRes = mIsMessages
|
||||
? R.drawable.zen_messages_none
|
||||
: R.drawable.zen_calls_none;
|
||||
newContentDescription = mContext.getString(R.string.zen_mode_from_none);
|
||||
newContentDescription =
|
||||
mContext.getString(mIsMessages
|
||||
? R.string.zen_mode_none_messages
|
||||
: R.string.zen_mode_none_calls);
|
||||
}
|
||||
|
||||
mImageView.setImageResource(newImageRes);
|
||||
|
||||
@@ -156,7 +156,7 @@ public class ZenModeSettings extends ZenModeSettingsBase {
|
||||
|| PRIORITY_CATEGORY_REPEAT_CALLERS == category, true);
|
||||
int numCategories = enabledCategories.size();
|
||||
if (numCategories == 0) {
|
||||
return mContext.getString(R.string.zen_mode_from_none);
|
||||
return mContext.getString(R.string.zen_mode_none_calls);
|
||||
} else if (numCategories == 1) {
|
||||
return mContext.getString(R.string.zen_mode_calls_summary_one,
|
||||
enabledCategories.get(0));
|
||||
@@ -172,7 +172,7 @@ public class ZenModeSettings extends ZenModeSettingsBase {
|
||||
category -> PRIORITY_CATEGORY_MESSAGES == category, false);
|
||||
int numCategories = enabledCategories.size();
|
||||
if (numCategories == 0) {
|
||||
return mContext.getString(R.string.zen_mode_from_none);
|
||||
return mContext.getString(R.string.zen_mode_none_messages);
|
||||
} else {
|
||||
return enabledCategories.get(0);
|
||||
}
|
||||
|
||||
@@ -82,15 +82,18 @@ public class ZenModeSliceBuilder {
|
||||
final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction,
|
||||
null /* actionTitle */,
|
||||
isZenModeEnabled);
|
||||
final RowBuilder rowBuilder = new RowBuilder()
|
||||
.setTitle(title)
|
||||
.addEndItem(toggleSliceAction)
|
||||
.setPrimaryAction(primarySliceAction);
|
||||
if (!Utils.isSettingsIntelligence(context)) {
|
||||
rowBuilder.setSubtitle(subtitle);
|
||||
}
|
||||
|
||||
return new ListBuilder(context, CustomSliceRegistry.ZEN_MODE_SLICE_URI,
|
||||
ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addRow(new RowBuilder()
|
||||
.setTitle(title)
|
||||
.setSubtitle(subtitle)
|
||||
.addEndItem(toggleSliceAction)
|
||||
.setPrimaryAction(primarySliceAction))
|
||||
.addRow(rowBuilder)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -241,16 +241,19 @@ public class SliceBuilderUtils {
|
||||
final SliceAction sliceAction = getToggleAction(context, sliceData,
|
||||
toggleController.isChecked());
|
||||
final Set<String> keywords = buildSliceKeywords(sliceData);
|
||||
|
||||
return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addRow(new RowBuilder()
|
||||
final RowBuilder rowBuilder = new RowBuilder()
|
||||
.setTitle(sliceData.getTitle())
|
||||
.setSubtitle(subtitleText)
|
||||
.setPrimaryAction(
|
||||
SliceAction.createDeeplink(contentIntent, icon,
|
||||
ListBuilder.ICON_IMAGE, sliceData.getTitle()))
|
||||
.addEndItem(sliceAction))
|
||||
.addEndItem(sliceAction);
|
||||
if (!Utils.isSettingsIntelligence(context)) {
|
||||
rowBuilder.setSubtitle(subtitleText);
|
||||
}
|
||||
|
||||
return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addRow(rowBuilder)
|
||||
.setKeywords(keywords)
|
||||
.build();
|
||||
}
|
||||
@@ -262,16 +265,19 @@ public class SliceBuilderUtils {
|
||||
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
|
||||
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
|
||||
final Set<String> keywords = buildSliceKeywords(sliceData);
|
||||
|
||||
return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addRow(new RowBuilder()
|
||||
final RowBuilder rowBuilder = new RowBuilder()
|
||||
.setTitle(sliceData.getTitle())
|
||||
.setSubtitle(subtitleText)
|
||||
.setPrimaryAction(
|
||||
SliceAction.createDeeplink(contentIntent, icon,
|
||||
ListBuilder.ICON_IMAGE,
|
||||
sliceData.getTitle())))
|
||||
sliceData.getTitle()));
|
||||
if (!Utils.isSettingsIntelligence(context)) {
|
||||
rowBuilder.setSubtitle(subtitleText);
|
||||
}
|
||||
|
||||
return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addRow(rowBuilder)
|
||||
.setKeywords(keywords)
|
||||
.build();
|
||||
}
|
||||
@@ -301,7 +307,6 @@ public class SliceBuilderUtils {
|
||||
}
|
||||
final InputRangeBuilder inputRangeBuilder = new InputRangeBuilder()
|
||||
.setTitle(sliceData.getTitle())
|
||||
.setSubtitle(subtitleText)
|
||||
.setPrimaryAction(primaryAction)
|
||||
.setMax(sliderController.getMax())
|
||||
.setMin(sliderController.getMin())
|
||||
@@ -311,6 +316,9 @@ public class SliceBuilderUtils {
|
||||
inputRangeBuilder.setTitleItem(icon, ListBuilder.ICON_IMAGE);
|
||||
color = CustomSliceable.COLOR_NOT_TINTED;
|
||||
}
|
||||
if (!Utils.isSettingsIntelligence(context)) {
|
||||
inputRangeBuilder.setSubtitle(subtitleText);
|
||||
}
|
||||
|
||||
return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
@@ -330,14 +338,17 @@ public class SliceBuilderUtils {
|
||||
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
|
||||
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
|
||||
final Set<String> keywords = buildSliceKeywords(sliceData);
|
||||
final RowBuilder rowBuilder = new RowBuilder()
|
||||
.setTitle(sliceData.getTitle())
|
||||
.setPrimaryAction(primaryAction)
|
||||
.addEndItem(copyableAction);
|
||||
if (!Utils.isSettingsIntelligence(context)) {
|
||||
rowBuilder.setSubtitle(subtitleText);
|
||||
}
|
||||
|
||||
return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addRow(new RowBuilder()
|
||||
.setTitle(sliceData.getTitle())
|
||||
.setSubtitle(subtitleText)
|
||||
.setPrimaryAction(primaryAction)
|
||||
.addEndItem(copyableAction))
|
||||
.addRow(rowBuilder)
|
||||
.setKeywords(keywords)
|
||||
.build();
|
||||
}
|
||||
@@ -418,14 +429,17 @@ public class SliceBuilderUtils {
|
||||
final SliceAction primaryAction = SliceAction.createDeeplink(
|
||||
getContentPendingIntent(context, data),
|
||||
icon, ListBuilder.ICON_IMAGE, title);
|
||||
final RowBuilder rowBuilder = new RowBuilder()
|
||||
.setTitle(title)
|
||||
.setTitleItem(icon, ListBuilder.ICON_IMAGE)
|
||||
.setPrimaryAction(primaryAction);
|
||||
if (!Utils.isSettingsIntelligence(context)) {
|
||||
rowBuilder.setSubtitle(subtitle);
|
||||
}
|
||||
|
||||
return new ListBuilder(context, data.getUri(), ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addRow(new RowBuilder()
|
||||
.setTitle(title)
|
||||
.setTitleItem(icon, ListBuilder.ICON_IMAGE)
|
||||
.setSubtitle(subtitle)
|
||||
.setPrimaryAction(primaryAction))
|
||||
.addRow(rowBuilder)
|
||||
.setKeywords(keywords)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -544,15 +544,10 @@ public class WifiSettings2 extends RestrictedSettingsFragment
|
||||
final WifiEntry selectedEntry =
|
||||
((LongPressWifiEntryPreference) preference).getWifiEntry();
|
||||
|
||||
// If the clicked WiFi entry is never connected, launch Wi-Fi edit UI to edit password.
|
||||
if (selectedEntry.getSecurity() != WifiEntry.SECURITY_NONE
|
||||
&& selectedEntry.getSecurity() != WifiEntry.SECURITY_OWE) {
|
||||
final WifiConfiguration config = selectedEntry.getWifiConfiguration();
|
||||
if (config != null && !config.getNetworkSelectionStatus().hasEverConnected()) {
|
||||
if (selectedEntry.shouldEditBeforeConnect()) {
|
||||
launchConfigNewNetworkFragment(selectedEntry);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
connect(selectedEntry, true /* editIfNoConfig */, true /* fullScreenEdit */);
|
||||
} else if (preference == mAddWifiNetworkPreference) {
|
||||
|
||||
@@ -269,14 +269,17 @@ public class WifiCallingSliceHelper {
|
||||
// Top row shows information on current preference state
|
||||
final ListBuilder listBuilder = new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY)
|
||||
.setAccentColor(Utils.getColorAccentDefaultColor(mContext));
|
||||
listBuilder.setHeader(new ListBuilder.HeaderBuilder()
|
||||
final ListBuilder.HeaderBuilder headerBuilder = new ListBuilder.HeaderBuilder()
|
||||
.setTitle(res.getText(R.string.wifi_calling_mode_title))
|
||||
.setSubtitle(getWifiCallingPreferenceSummary(currentWfcPref, subId))
|
||||
.setPrimaryAction(SliceAction.createDeeplink(
|
||||
getActivityIntent(ACTION_WIFI_CALLING_SETTINGS_ACTIVITY),
|
||||
icon,
|
||||
ListBuilder.ICON_IMAGE,
|
||||
res.getText(R.string.wifi_calling_mode_title))));
|
||||
res.getText(R.string.wifi_calling_mode_title)));
|
||||
if (!Utils.isSettingsIntelligence(mContext)) {
|
||||
headerBuilder.setSubtitle(getWifiCallingPreferenceSummary(currentWfcPref, subId));
|
||||
}
|
||||
listBuilder.setHeader(headerBuilder);
|
||||
|
||||
if (isWifiOnlySupported) {
|
||||
listBuilder.addRow(wifiPreferenceRowBuilder(listBuilder,
|
||||
@@ -458,14 +461,17 @@ public class WifiCallingSliceHelper {
|
||||
private Slice getNonActionableWifiCallingSlice(CharSequence title, CharSequence subtitle,
|
||||
Uri sliceUri, PendingIntent primaryActionIntent) {
|
||||
final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.wifi_signal);
|
||||
return new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY)
|
||||
.setAccentColor(Utils.getColorAccentDefaultColor(mContext))
|
||||
.addRow(new RowBuilder()
|
||||
final RowBuilder rowBuilder = new RowBuilder()
|
||||
.setTitle(title)
|
||||
.setSubtitle(subtitle)
|
||||
.setPrimaryAction(SliceAction.createDeeplink(
|
||||
primaryActionIntent, icon, ListBuilder.SMALL_IMAGE,
|
||||
title)))
|
||||
title));
|
||||
if (!Utils.isSettingsIntelligence(mContext)) {
|
||||
rowBuilder.setSubtitle(subtitle);
|
||||
}
|
||||
return new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY)
|
||||
.setAccentColor(Utils.getColorAccentDefaultColor(mContext))
|
||||
.addRow(rowBuilder)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.ActionBar;
|
||||
import android.app.Activity;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@@ -67,6 +66,7 @@ import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.shadows.ShadowBinder;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
@@ -281,4 +281,22 @@ public class UtilsTest {
|
||||
|
||||
assertThat(actionBar.getElevation()).isEqualTo(0.f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSettingsIntelligence_IsSI_returnTrue() {
|
||||
final String siPackageName = mContext.getString(
|
||||
R.string.config_settingsintelligence_package_name);
|
||||
ShadowBinder.setCallingUid(USER_ID);
|
||||
when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{siPackageName});
|
||||
|
||||
assertThat(Utils.isSettingsIntelligence(mContext)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSettingsIntelligence_IsNotSI_returnFalse() {
|
||||
ShadowBinder.setCallingUid(USER_ID);
|
||||
when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{PACKAGE_NAME});
|
||||
|
||||
assertThat(Utils.isSettingsIntelligence(mContext)).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,8 +130,8 @@ public class AccessibilitySettingsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceSummary_invisibleType_shortcutDisabled_showsOffSummary() {
|
||||
setInvisibleFragmentType(mServiceInfo);
|
||||
public void getServiceSummary_invisibleToggle_shortcutDisabled_showsOffSummary() {
|
||||
setInvisibleToggleFragmentType(mServiceInfo);
|
||||
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
|
||||
|
||||
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
|
||||
@@ -277,7 +277,7 @@ public class AccessibilitySettingsTest {
|
||||
when(mockInfo.getComponentName()).thenReturn(DUMMY_COMPONENT_NAME);
|
||||
}
|
||||
|
||||
private void setInvisibleFragmentType(AccessibilityServiceInfo info) {
|
||||
private void setInvisibleToggleFragmentType(AccessibilityServiceInfo info) {
|
||||
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
|
||||
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
||||
}
|
||||
|
||||
@@ -102,36 +102,36 @@ public final class AccessibilityUtilTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAccessibilityServiceFragmentType_targetSdkQ_legacyType() {
|
||||
public void getAccessibilityServiceFragmentType_targetSdkQ_volumeShortcutType() {
|
||||
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
|
||||
|
||||
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
|
||||
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
||||
|
||||
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
|
||||
AccessibilityUtil.AccessibilityServiceFragmentType.LEGACY);
|
||||
AccessibilityUtil.AccessibilityServiceFragmentType.VOLUME_SHORTCUT_TOGGLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAccessibilityServiceFragmentType_targetSdkR_HaveA11yButton_headlessType() {
|
||||
public void getAccessibilityServiceFragmentType_targetSdkR_HaveA11yButton_invisibleType() {
|
||||
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
|
||||
|
||||
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
|
||||
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
||||
|
||||
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
|
||||
AccessibilityUtil.AccessibilityServiceFragmentType.INVISIBLE);
|
||||
AccessibilityUtil.AccessibilityServiceFragmentType.INVISIBLE_TOGGLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAccessibilityServiceFragmentType_targetSdkR_NoA11yButton_intuitiveType() {
|
||||
public void getAccessibilityServiceFragmentType_targetSdkR_NoA11yButton_toggleType() {
|
||||
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
|
||||
|
||||
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
|
||||
info.flags |= ~AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
||||
|
||||
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
|
||||
AccessibilityUtil.AccessibilityServiceFragmentType.INTUITIVE);
|
||||
AccessibilityUtil.AccessibilityServiceFragmentType.TOGGLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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.app;
|
||||
|
||||
import static android.app.NotificationChannel.DEFAULT_ALLOW_BUBBLE;
|
||||
import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
|
||||
import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
|
||||
import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.UserManager;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
|
||||
import androidx.preference.PreferenceCategory;
|
||||
|
||||
import com.android.settings.notification.AppBubbleListPreferenceController;
|
||||
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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AppBubbleListPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private NotificationBackend mBackend;
|
||||
@Mock
|
||||
private NotificationManager mNm;
|
||||
@Mock
|
||||
private UserManager mUm;
|
||||
|
||||
private AppBubbleListPreferenceController mController;
|
||||
private ParceledListSlice<ConversationChannelWrapper> mConvoList;
|
||||
|
||||
@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;
|
||||
|
||||
List<ConversationChannelWrapper> convoList = new ArrayList<>();
|
||||
convoList.add(getConvo(-1, "default"));
|
||||
convoList.add(getConvo(1, "selected"));
|
||||
convoList.add(getConvo(0, "excluded"));
|
||||
mConvoList = new ParceledListSlice<>(convoList);
|
||||
when(mBackend.getConversations(anyString(), anyInt())).thenReturn(mConvoList);
|
||||
mController = new AppBubbleListPreferenceController(mContext, mBackend);
|
||||
}
|
||||
|
||||
ConversationChannelWrapper getConvo(int bubbleChannelPref, String channelId) {
|
||||
ConversationChannelWrapper ccw = new ConversationChannelWrapper();
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getId()).thenReturn(channelId);
|
||||
when(channel.getAllowBubbles()).thenReturn(bubbleChannelPref);
|
||||
when(channel.canBubble()).thenReturn(bubbleChannelPref == 1);
|
||||
ccw.setNotificationChannel(channel);
|
||||
ccw.setPkg("pkg");
|
||||
ccw.setUid(1);
|
||||
ccw.setShortcutInfo(mock(ShortcutInfo.class));
|
||||
return ccw;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_BUBBLE_PREFERENCE_NONE_false() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_NONE;
|
||||
mController.onResume(appRow, null, null, null, null, null);
|
||||
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_BUBBLE_PREFERENCE_SELECTED_true() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED;
|
||||
mController.onResume(appRow, null, null, null, null, null);
|
||||
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_BUBBLE_PREFERENCE_ALL_true() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
||||
mController.onResume(appRow, null, null, null, null, null);
|
||||
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterAndSortConversations_BUBBLE_PREFERENCE_SELECTED_filtersAllowedBubbles() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED;
|
||||
mController.onResume(appRow, null, null, null, null, null);
|
||||
|
||||
List<ConversationChannelWrapper> result =
|
||||
mController.filterAndSortConversations(mConvoList.getList());
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(0).getNotificationChannel().getId())
|
||||
.isEqualTo("selected");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterAndSortConversations_BUBBLE_PREFERENCE_ALL_filtersExcludedBubbles() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
||||
mController.onResume(appRow, null, null, null, null, null);
|
||||
|
||||
List<ConversationChannelWrapper> result =
|
||||
mController.filterAndSortConversations(mConvoList.getList());
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(0).getNotificationChannel().getId())
|
||||
.isEqualTo("excluded");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickConversationPref_updatesChannel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
||||
appRow.pkg = "PKG";
|
||||
mController.onResume(appRow, null, null, null, null, null);
|
||||
mController.mPreference = new PreferenceCategory(mContext);
|
||||
|
||||
ConversationChannelWrapper ccw = mConvoList.getList().get(0);
|
||||
AppBubbleListPreferenceController.ConversationPreference pref =
|
||||
(AppBubbleListPreferenceController.ConversationPreference)
|
||||
mController.createConversationPref(ccw);
|
||||
pref.onClick(null);
|
||||
|
||||
verify(ccw.getNotificationChannel()).setAllowBubbles(DEFAULT_ALLOW_BUBBLE);
|
||||
verify(mBackend).updateChannel(anyString(), anyInt(), any(NotificationChannel.class));
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,8 @@ public class BubblePreferenceControllerTest {
|
||||
private PreferenceScreen mScreen;
|
||||
@Mock
|
||||
private FragmentManager mFragmentManager;
|
||||
@Mock
|
||||
private NotificationSettings.DependentFieldListener mListener;
|
||||
|
||||
private BubblePreferenceController mController;
|
||||
private BubblePreferenceController mAppPageController;
|
||||
@@ -93,9 +95,9 @@ public class BubblePreferenceControllerTest {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
when(mFragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class));
|
||||
mController = spy(new BubblePreferenceController(mContext, mFragmentManager, mBackend,
|
||||
false /* isAppPage */));
|
||||
false /* isAppPage */, mListener));
|
||||
mAppPageController = spy(new BubblePreferenceController(mContext, mFragmentManager,
|
||||
mBackend, true /* isAppPage */));
|
||||
mBackend, true /* isAppPage */, mListener));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -106,7 +108,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_notIfAppBlocked() {
|
||||
public void isAvailable_notIfAppBlocked() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.banned = true;
|
||||
@@ -115,7 +117,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_notIfChannelBlocked() {
|
||||
public void isAvailable_notIfChannelBlocked() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
@@ -125,7 +127,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_channel_yesIfAppOff() {
|
||||
public void isAvailable_channel_yesIfAppOff() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_NONE;
|
||||
@@ -137,7 +139,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsNotAvailable_ifOffGlobally_app() {
|
||||
public void isNotAvailable_ifOffGlobally_app() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
mController.onResume(appRow, null, null, null, null, null);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
@@ -147,7 +149,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_notIfOffGlobally_channel() {
|
||||
public void isAvailable_notIfOffGlobally_channel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
||||
@@ -159,7 +161,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_app_evenIfOffGlobally() {
|
||||
public void isAvailable_app_evenIfOffGlobally() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
mAppPageController.onResume(appRow, null, null, null, null, null);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
@@ -169,7 +171,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_app() {
|
||||
public void isAvailable_app() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
mController.onResume(appRow, null, null, null, null, null);
|
||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||
@@ -178,7 +180,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_defaultChannel() {
|
||||
public void isAvailable_defaultChannel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
@@ -191,7 +193,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_channel() {
|
||||
public void isAvailable_channel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
@@ -203,7 +205,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_disabledByAdmin() {
|
||||
public void updateState_disabledByAdmin() {
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getId()).thenReturn("something");
|
||||
mController.onResume(new NotificationBackend.AppRow(), channel, null,
|
||||
@@ -216,7 +218,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_app_disabledByAdmin() {
|
||||
public void updateState_app_disabledByAdmin() {
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getId()).thenReturn("something");
|
||||
mAppPageController.onResume(new NotificationBackend.AppRow(), channel, null,
|
||||
@@ -229,7 +231,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_channel_channelNotBlockable() {
|
||||
public void updateState_channel_channelNotBlockable() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
@@ -243,7 +245,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_channel() {
|
||||
public void updateState_channel() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
@@ -263,7 +265,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_app() {
|
||||
public void updateState_app() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.label = "App!";
|
||||
@@ -288,7 +290,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_app_offGlobally() {
|
||||
public void updateState_app_offGlobally() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF);
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
@@ -302,7 +304,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnPreferenceChange_on_channel() {
|
||||
public void onPreferenceChange_on_channel() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED;
|
||||
@@ -321,7 +323,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnPreferenceChange_off_channel() {
|
||||
public void onPreferenceChange_off_channel() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED;
|
||||
@@ -341,7 +343,7 @@ public class BubblePreferenceControllerTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void testOnPreferenceChange_app_all() {
|
||||
public void onPreferenceChange_app_all() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_NONE;
|
||||
@@ -379,7 +381,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnPreferenceChange_app_selected() {
|
||||
public void onPreferenceChange_app_selected() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
||||
@@ -397,7 +399,7 @@ public class BubblePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnPreferenceChange_app_none() {
|
||||
public void onPreferenceChange_app_none() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
||||
@@ -413,4 +415,17 @@ public class BubblePreferenceControllerTest {
|
||||
assertEquals(BUBBLE_PREFERENCE_NONE, appRow.bubblePreference);
|
||||
verify(mBackend, times(1)).setAllowBubbles(any(), anyInt(), eq(BUBBLE_PREFERENCE_NONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_dependentFieldListenerCalled() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
||||
mAppPageController.onResume(appRow, null, null, null, null, null);
|
||||
|
||||
BubblePreference pref = new BubblePreference(mContext);
|
||||
mAppPageController.onPreferenceChange(pref, BUBBLE_PREFERENCE_NONE);
|
||||
|
||||
verify(mListener, times(1)).onFieldValueChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
@@ -455,37 +454,6 @@ public class SliceBuilderUtilsTest {
|
||||
assertThat(actualIconResource).isEqualTo(settingsIcon);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildUnavailableSlice_customizeSubtitle_returnsSliceWithCustomizedSubtitle() {
|
||||
final String subtitleOfUnavailableSlice = "subtitleOfUnavailableSlice";
|
||||
final SliceData data = getDummyData(FakeUnavailablePreferenceController.class,
|
||||
SUMMARY, SliceData.SliceType.SWITCH, SCREEN_TITLE, 0 /* icon */,
|
||||
subtitleOfUnavailableSlice);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
FakeUnavailablePreferenceController.AVAILABILITY_KEY,
|
||||
BasePreferenceController.DISABLED_DEPENDENT_SETTING);
|
||||
|
||||
final Slice slice = SliceBuilderUtils.buildSlice(mContext, data);
|
||||
|
||||
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
|
||||
assertThat(metadata.getSubtitle()).isEqualTo(subtitleOfUnavailableSlice);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildUnavailableSlice_notCustomizeSubtitle_returnsSliceWithDefaultSubtitle() {
|
||||
final SliceData data = getDummyData(FakeUnavailablePreferenceController.class,
|
||||
SliceData.SliceType.SWITCH);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
FakeUnavailablePreferenceController.AVAILABILITY_KEY,
|
||||
BasePreferenceController.DISABLED_DEPENDENT_SETTING);
|
||||
|
||||
final Slice slice = SliceBuilderUtils.buildSlice(mContext, data);
|
||||
|
||||
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
|
||||
assertThat(metadata.getSubtitle()).isEqualTo(
|
||||
mContext.getString(R.string.disabled_dependent_setting_summary));
|
||||
}
|
||||
|
||||
private SliceData getDummyData() {
|
||||
return getDummyData(TOGGLE_CONTROLLER, SUMMARY, SliceData.SliceType.SWITCH, SCREEN_TITLE,
|
||||
ICON, null /* unavailableSliceSubtitle */);
|
||||
|
||||
Reference in New Issue
Block a user