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_anyone</item>
|
||||||
<item>@string/zen_mode_from_contacts</item>
|
<item>@string/zen_mode_from_contacts</item>
|
||||||
<item>@string/zen_mode_from_starred</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>
|
||||||
|
|
||||||
<string-array name="zen_mode_contacts_calls_entries" translatable="false">
|
<string-array name="zen_mode_contacts_calls_entries" translatable="false">
|
||||||
<item>@string/zen_mode_from_anyone</item>
|
<item>@string/zen_mode_from_anyone</item>
|
||||||
<item>@string/zen_mode_from_contacts</item>
|
<item>@string/zen_mode_from_contacts</item>
|
||||||
<item>@string/zen_mode_from_starred</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>
|
||||||
|
|
||||||
<string-array name="zen_mode_contacts_values" translatable="false">
|
<string-array name="zen_mode_contacts_values" translatable="false">
|
||||||
|
|||||||
@@ -8465,6 +8465,8 @@
|
|||||||
<!-- [CHAR LIMIT=150] Notification Importance title: important conversation level summary -->
|
<!-- [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="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 -->
|
<!-- Channel summaries for the app notification page -->
|
||||||
|
|
||||||
<!-- [CHAR LIMIT=150] Notification Importance title: min importance level summary -->
|
<!-- [CHAR LIMIT=150] Notification Importance title: min importance level summary -->
|
||||||
@@ -8976,6 +8978,8 @@
|
|||||||
<item quantity="one">1 other</item>
|
<item quantity="one">1 other</item>
|
||||||
<item quantity="other"><xliff:g id="num_people" example="3">%d</xliff:g> others</item>
|
<item quantity="other"><xliff:g id="num_people" example="3">%d</xliff:g> others</item>
|
||||||
</plurals>
|
</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 -->
|
<!-- [CHAR LIMIT=40] Zen mode settings: Messages option -->
|
||||||
<string name="zen_mode_messages">Messages</string>
|
<string name="zen_mode_messages">Messages</string>
|
||||||
@@ -8995,8 +8999,13 @@
|
|||||||
<!-- Zen mode settings: All calls can bypass DND summary [CHAR LIMIT=NONE -->
|
<!-- 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>
|
<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 -->
|
<!-- Zen mode settings: There are no contacts on the device [CHAR LIMIT=NONE] -->
|
||||||
<string name="zen_mode_contacts_senders_summary"><xliff:g id="num_contacts" example="120">%d</xliff:g> contacts</string>
|
<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 -->
|
<!-- [CHAR LIMIT=40] Zen mode settings: Calls or messages option value: From anyone -->
|
||||||
<string name="zen_mode_from_anyone">Anyone</string>
|
<string name="zen_mode_from_anyone">Anyone</string>
|
||||||
@@ -9004,8 +9013,6 @@
|
|||||||
<string name="zen_mode_from_contacts">Contacts</string>
|
<string name="zen_mode_from_contacts">Contacts</string>
|
||||||
<!-- [CHAR LIMIT=40] Zen mode settings: Calls or messages option value: From starred contacts only -->
|
<!-- [CHAR LIMIT=40] Zen mode settings: Calls or messages option value: From starred contacts only -->
|
||||||
<string name="zen_mode_from_starred">Starred contacts</string>
|
<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]-->
|
<!-- Do not disturb settings, calls summary [CHAR LIMIT=100]-->
|
||||||
<string name="zen_calls_summary_starred_repeat">From starred contacts and repeat callers</string>
|
<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>
|
<string name="zen_calls_summary_repeat_only">From repeat callers only</string>
|
||||||
|
|
||||||
<!-- [CHAR LIMIT=40] Zen mode settings: Calls option value: No calls allowed -->
|
<!-- [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 -->
|
<!-- [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 -->
|
<!-- [CHAR LIMIT=80] Zen mode settings: Allow alarms option -->
|
||||||
<string name="zen_mode_alarms">Alarms</string>
|
<string name="zen_mode_alarms">Alarms</string>
|
||||||
|
|||||||
@@ -27,4 +27,12 @@
|
|||||||
android:title="@string/notification_bubbles_title"
|
android:title="@string/notification_bubbles_title"
|
||||||
settings:allowDividerBelow="false"/>
|
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>
|
</PreferenceScreen>
|
||||||
|
|||||||
@@ -78,14 +78,14 @@
|
|||||||
android:key="ringtone"
|
android:key="ringtone"
|
||||||
android:title="@string/notification_channel_sound_title"
|
android:title="@string/notification_channel_sound_title"
|
||||||
android:dialogTitle="@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:showSilent="true"
|
||||||
android:showDefault="true"/>
|
android:showDefault="true"/>
|
||||||
|
|
||||||
<!-- Visibility Override -->
|
<!-- Visibility Override -->
|
||||||
<com.android.settings.RestrictedListPreference
|
<com.android.settings.RestrictedListPreference
|
||||||
android:key="visibility_override"
|
android:key="visibility_override"
|
||||||
android:icon="@drawable/ic_lock"
|
android:icon="@drawable/ic_lock_closed"
|
||||||
android:title="@string/app_notification_visibility_override_title"/>
|
android:title="@string/app_notification_visibility_override_title"/>
|
||||||
|
|
||||||
<!-- Show badge -->
|
<!-- Show badge -->
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ import android.net.LinkProperties;
|
|||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.BatteryManager;
|
import android.os.BatteryManager;
|
||||||
|
import android.os.Binder;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -1089,4 +1090,15 @@ public final class Utils extends com.android.settingslib.Utils {
|
|||||||
}
|
}
|
||||||
return f;
|
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 CharSequence serviceState;
|
||||||
final int fragmentType = AccessibilityUtil.getAccessibilityServiceFragmentType(info);
|
final int fragmentType = AccessibilityUtil.getAccessibilityServiceFragmentType(info);
|
||||||
if (fragmentType == AccessibilityServiceFragmentType.INVISIBLE) {
|
if (fragmentType == AccessibilityServiceFragmentType.INVISIBLE_TOGGLE) {
|
||||||
final ComponentName componentName = new ComponentName(
|
final ComponentName componentName = new ComponentName(
|
||||||
info.getResolveInfo().serviceInfo.packageName,
|
info.getResolveInfo().serviceInfo.packageName,
|
||||||
info.getResolveInfo().serviceInfo.name);
|
info.getResolveInfo().serviceInfo.name);
|
||||||
@@ -652,13 +652,16 @@ public class AccessibilitySettings extends DashboardFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getAccessibilityServiceFragmentTypeName(AccessibilityServiceInfo info) {
|
private String getAccessibilityServiceFragmentTypeName(AccessibilityServiceInfo info) {
|
||||||
switch (AccessibilityUtil.getAccessibilityServiceFragmentType(
|
// Shorten the name to avoid exceeding 100 characters in one line.
|
||||||
info)) {
|
final String volumeShortcutToggleAccessibilityServicePreferenceFragment =
|
||||||
case AccessibilityServiceFragmentType.LEGACY:
|
VolumeShortcutToggleAccessibilityServicePreferenceFragment.class.getName();
|
||||||
return LegacyAccessibilityServicePreferenceFragment.class.getName();
|
|
||||||
case AccessibilityServiceFragmentType.INVISIBLE:
|
switch (AccessibilityUtil.getAccessibilityServiceFragmentType(info)) {
|
||||||
|
case AccessibilityServiceFragmentType.VOLUME_SHORTCUT_TOGGLE:
|
||||||
|
return volumeShortcutToggleAccessibilityServicePreferenceFragment;
|
||||||
|
case AccessibilityServiceFragmentType.INVISIBLE_TOGGLE:
|
||||||
return InvisibleToggleAccessibilityServicePreferenceFragment.class.getName();
|
return InvisibleToggleAccessibilityServicePreferenceFragment.class.getName();
|
||||||
case AccessibilityServiceFragmentType.INTUITIVE:
|
case AccessibilityServiceFragmentType.TOGGLE:
|
||||||
return ToggleAccessibilityServicePreferenceFragment.class.getName();
|
return ToggleAccessibilityServicePreferenceFragment.class.getName();
|
||||||
default:
|
default:
|
||||||
// impossible status
|
// impossible status
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.android.settings.accessibility;
|
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.accessibilityservice.AccessibilityServiceInfo;
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
@@ -102,10 +102,10 @@ public class AccessibilitySettingsForSetupWizard extends SettingsPreferenceFragm
|
|||||||
super.onResume();
|
super.onResume();
|
||||||
updateAccessibilityServicePreference(mScreenReaderPreference,
|
updateAccessibilityServicePreference(mScreenReaderPreference,
|
||||||
SCREEN_READER_PACKAGE_NAME, SCREEN_READER_SERVICE_NAME,
|
SCREEN_READER_PACKAGE_NAME, SCREEN_READER_SERVICE_NAME,
|
||||||
LegacyToggleScreenReaderPreferenceFragmentForSetupWizard.class.getName());
|
VolumeShortcutToggleScreenReaderPreferenceFragmentForSetupWizard.class.getName());
|
||||||
updateAccessibilityServicePreference(mSelectToSpeakPreference,
|
updateAccessibilityServicePreference(mSelectToSpeakPreference,
|
||||||
SELECT_TO_SPEAK_PACKAGE_NAME, SELECT_TO_SPEAK_SERVICE_NAME,
|
SELECT_TO_SPEAK_PACKAGE_NAME, SELECT_TO_SPEAK_SERVICE_NAME,
|
||||||
LegacyToggleSelectToSpeakPreferenceFragmentForSetupWizard.class.getName());
|
VolumeShortcutToggleSelectToSpeakPreferenceFragmentForSetupWizard.class.getName());
|
||||||
configureMagnificationPreferenceIfNeeded(mDisplayMagnificationPreference);
|
configureMagnificationPreferenceIfNeeded(mDisplayMagnificationPreference);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ public class AccessibilitySettingsForSetupWizard extends SettingsPreferenceFragm
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateAccessibilityServicePreference(Preference preference,
|
private void updateAccessibilityServicePreference(Preference preference,
|
||||||
String packageName, String serviceName, String targetLegacyFragment) {
|
String packageName, String serviceName, String targetFragment) {
|
||||||
final AccessibilityServiceInfo info = findService(packageName, serviceName);
|
final AccessibilityServiceInfo info = findService(packageName, serviceName);
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
getPreferenceScreen().removePreference(preference);
|
getPreferenceScreen().removePreference(preference);
|
||||||
@@ -159,8 +159,8 @@ public class AccessibilitySettingsForSetupWizard extends SettingsPreferenceFragm
|
|||||||
preference.setTitle(title);
|
preference.setTitle(title);
|
||||||
ComponentName componentName = new ComponentName(serviceInfo.packageName, serviceInfo.name);
|
ComponentName componentName = new ComponentName(serviceInfo.packageName, serviceInfo.name);
|
||||||
preference.setKey(componentName.flattenToString());
|
preference.setKey(componentName.flattenToString());
|
||||||
if (AccessibilityUtil.getAccessibilityServiceFragmentType(info) == LEGACY) {
|
if (AccessibilityUtil.getAccessibilityServiceFragmentType(info) == VOLUME_SHORTCUT_TOGGLE) {
|
||||||
preference.setFragment(targetLegacyFragment);
|
preference.setFragment(targetFragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the extras.
|
// Update the extras.
|
||||||
|
|||||||
@@ -46,22 +46,23 @@ final class AccessibilityUtil {
|
|||||||
/**
|
/**
|
||||||
* Annotation for different accessibilityService fragment UI type.
|
* Annotation for different accessibilityService fragment UI type.
|
||||||
*
|
*
|
||||||
* {@code LEGACY} for displaying appearance aligned with sdk version Q accessibility service
|
* {@code VOLUME_SHORTCUT_TOGGLE} for displaying basic accessibility service fragment but
|
||||||
* page, but only hardware shortcut allowed.
|
* only hardware shortcut allowed.
|
||||||
* {@code INVISIBLE} for displaying appearance without switch bar.
|
* {@code INVISIBLE_TOGGLE} for displaying basic accessibility service fragment without
|
||||||
* {@code INTUITIVE} for displaying appearance with new design.
|
* switch bar.
|
||||||
|
* {@code TOGGLE} for displaying basic accessibility service fragment.
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef({
|
@IntDef({
|
||||||
AccessibilityServiceFragmentType.LEGACY,
|
AccessibilityServiceFragmentType.VOLUME_SHORTCUT_TOGGLE,
|
||||||
AccessibilityServiceFragmentType.INVISIBLE,
|
AccessibilityServiceFragmentType.INVISIBLE_TOGGLE,
|
||||||
AccessibilityServiceFragmentType.INTUITIVE,
|
AccessibilityServiceFragmentType.TOGGLE,
|
||||||
})
|
})
|
||||||
|
|
||||||
public @interface AccessibilityServiceFragmentType {
|
public @interface AccessibilityServiceFragmentType {
|
||||||
int LEGACY = 0;
|
int VOLUME_SHORTCUT_TOGGLE = 0;
|
||||||
int INVISIBLE = 1;
|
int INVISIBLE_TOGGLE = 1;
|
||||||
int INTUITIVE = 2;
|
int TOGGLE = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(b/147021230): Will move common functions and variables to
|
// TODO(b/147021230): Will move common functions and variables to
|
||||||
@@ -162,11 +163,11 @@ final class AccessibilityUtil {
|
|||||||
& AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0;
|
& AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0;
|
||||||
|
|
||||||
if (targetSdk <= Build.VERSION_CODES.Q) {
|
if (targetSdk <= Build.VERSION_CODES.Q) {
|
||||||
return AccessibilityServiceFragmentType.LEGACY;
|
return AccessibilityServiceFragmentType.VOLUME_SHORTCUT_TOGGLE;
|
||||||
}
|
}
|
||||||
return requestA11yButton
|
return requestA11yButton
|
||||||
? AccessibilityServiceFragmentType.INVISIBLE
|
? AccessibilityServiceFragmentType.INVISIBLE_TOGGLE
|
||||||
: AccessibilityServiceFragmentType.INTUITIVE;
|
: AccessibilityServiceFragmentType.TOGGLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import com.google.common.collect.ImmutableSet;
|
|||||||
*
|
*
|
||||||
* <p>For accessibility services that target SDK <= Q.
|
* <p>For accessibility services that target SDK <= Q.
|
||||||
*/
|
*/
|
||||||
public class LegacyAccessibilityServicePreferenceFragment extends
|
public class VolumeShortcutToggleAccessibilityServicePreferenceFragment extends
|
||||||
ToggleAccessibilityServicePreferenceFragment {
|
ToggleAccessibilityServicePreferenceFragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -21,8 +21,8 @@ import android.os.Bundle;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
/** For accessibility services that target SDK <= Q in setup wizard. */
|
/** For accessibility services that target SDK <= Q in setup wizard. */
|
||||||
public class LegacyToggleScreenReaderPreferenceFragmentForSetupWizard
|
public class VolumeShortcutToggleScreenReaderPreferenceFragmentForSetupWizard
|
||||||
extends LegacyAccessibilityServicePreferenceFragment {
|
extends VolumeShortcutToggleAccessibilityServicePreferenceFragment {
|
||||||
|
|
||||||
private boolean mToggleSwitchWasInitiallyChecked;
|
private boolean mToggleSwitchWasInitiallyChecked;
|
||||||
|
|
||||||
@@ -21,8 +21,8 @@ import android.os.Bundle;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
/** For accessibility services that target SDK <= Q in setup wizard. */
|
/** For accessibility services that target SDK <= Q in setup wizard. */
|
||||||
public class LegacyToggleSelectToSpeakPreferenceFragmentForSetupWizard
|
public class VolumeShortcutToggleSelectToSpeakPreferenceFragmentForSetupWizard
|
||||||
extends LegacyAccessibilityServicePreferenceFragment {
|
extends VolumeShortcutToggleAccessibilityServicePreferenceFragment {
|
||||||
|
|
||||||
private boolean mToggleSwitchWasInitiallyChecked;
|
private boolean mToggleSwitchWasInitiallyChecked;
|
||||||
|
|
||||||
@@ -114,6 +114,7 @@ public class DataUsageSummaryPreferenceController extends TelephonyBasePreferenc
|
|||||||
*/
|
*/
|
||||||
public void init(int subscriptionId) {
|
public void init(int subscriptionId) {
|
||||||
mSubId = subscriptionId;
|
mSubId = subscriptionId;
|
||||||
|
mHasMobileData = DataUsageUtils.hasMobileData(mContext);
|
||||||
mDataUsageController = null;
|
mDataUsageController = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,8 +124,6 @@ public class DataUsageSummaryPreferenceController extends TelephonyBasePreferenc
|
|||||||
context.getSystemService(NetworkPolicyManager.class);
|
context.getSystemService(NetworkPolicyManager.class);
|
||||||
mPolicyEditor = new NetworkPolicyEditor(policyManager);
|
mPolicyEditor = new NetworkPolicyEditor(policyManager);
|
||||||
|
|
||||||
mHasMobileData = DataUsageUtils.hasMobileData(context);
|
|
||||||
|
|
||||||
mDataUsageController = new DataUsageController(context);
|
mDataUsageController = new DataUsageController(context);
|
||||||
mDataUsageController.setSubscriptionId(subscriptionId);
|
mDataUsageController.setSubscriptionId(subscriptionId);
|
||||||
mDataInfoController = new DataUsageInfoController();
|
mDataInfoController = new DataUsageInfoController();
|
||||||
@@ -210,6 +209,11 @@ public class DataUsageSummaryPreferenceController extends TelephonyBasePreferenc
|
|||||||
final DataUsageController.DataUsageInfo info =
|
final DataUsageController.DataUsageInfo info =
|
||||||
mDataUsageController.getDataUsageInfo(mDefaultTemplate);
|
mDataUsageController.getDataUsageInfo(mDefaultTemplate);
|
||||||
|
|
||||||
|
long usageLevel = info.usageLevel;
|
||||||
|
if (usageLevel <= 0L) {
|
||||||
|
usageLevel = mDataUsageController.getHistoricalUsageLevel(mDefaultTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
if (subInfo != null) {
|
if (subInfo != null) {
|
||||||
mDataInfoController.updateDataLimit(info, mPolicyEditor.getPolicy(mDefaultTemplate));
|
mDataInfoController.updateDataLimit(info, mPolicyEditor.getPolicy(mDefaultTemplate));
|
||||||
summaryPreference.setWifiMode(/* isWifiMode */ false,
|
summaryPreference.setWifiMode(/* isWifiMode */ false,
|
||||||
@@ -218,7 +222,7 @@ public class DataUsageSummaryPreferenceController extends TelephonyBasePreferenc
|
|||||||
summaryPreference.setWifiMode(/* isWifiMode */ true, /* usagePeriod */
|
summaryPreference.setWifiMode(/* isWifiMode */ true, /* usagePeriod */
|
||||||
info.period, /* isSingleWifi */ false);
|
info.period, /* isSingleWifi */ false);
|
||||||
summaryPreference.setLimitInfo(null);
|
summaryPreference.setLimitInfo(null);
|
||||||
summaryPreference.setUsageNumbers(info.usageLevel,
|
summaryPreference.setUsageNumbers(usageLevel,
|
||||||
/* dataPlanSize */ -1L,
|
/* dataPlanSize */ -1L,
|
||||||
/* hasMobileData */ true);
|
/* hasMobileData */ true);
|
||||||
summaryPreference.setChartEnabled(false);
|
summaryPreference.setChartEnabled(false);
|
||||||
@@ -231,6 +235,11 @@ public class DataUsageSummaryPreferenceController extends TelephonyBasePreferenc
|
|||||||
}
|
}
|
||||||
|
|
||||||
refreshDataplanInfo(info, subInfo);
|
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) {
|
if (info.warningLevel > 0 && info.limitLevel > 0) {
|
||||||
summaryPreference.setLimitInfo(TextUtils.expandTemplate(
|
summaryPreference.setLimitInfo(TextUtils.expandTemplate(
|
||||||
|
|||||||
@@ -70,6 +70,16 @@ import java.util.List;
|
|||||||
public class StorageSettings extends SettingsPreferenceFragment implements Indexable {
|
public class StorageSettings extends SettingsPreferenceFragment implements Indexable {
|
||||||
static final String TAG = "StorageSettings";
|
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_VOLUME_UNMOUNTED = "volume_unmounted";
|
||||||
private static final String TAG_DISK_INIT = "disk_init";
|
private static final String TAG_DISK_INIT = "disk_init";
|
||||||
private static final int METRICS_CATEGORY = SettingsEnums.DEVICEINFO_STORAGE;
|
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);
|
SearchIndexableRaw data = new SearchIndexableRaw(context);
|
||||||
data.title = context.getString(R.string.storage_settings);
|
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.screenTitle = context.getString(R.string.storage_settings);
|
||||||
data.keywords = context.getString(R.string.keywords_storage_settings);
|
data.keywords = context.getString(R.string.keywords_storage_settings);
|
||||||
result.add(data);
|
result.add(data);
|
||||||
|
|
||||||
data = new SearchIndexableRaw(context);
|
data = new SearchIndexableRaw(context);
|
||||||
data.title = context.getString(R.string.internal_storage);
|
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);
|
data.screenTitle = context.getString(R.string.storage_settings);
|
||||||
result.add(data);
|
result.add(data);
|
||||||
|
|
||||||
@@ -568,7 +578,7 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
|
|||||||
for (VolumeInfo vol : vols) {
|
for (VolumeInfo vol : vols) {
|
||||||
if (isInteresting(vol)) {
|
if (isInteresting(vol)) {
|
||||||
data.title = storage.getBestVolumeDescription(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);
|
data.screenTitle = context.getString(R.string.storage_settings);
|
||||||
result.add(data);
|
result.add(data);
|
||||||
}
|
}
|
||||||
@@ -576,37 +586,37 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
|
|||||||
|
|
||||||
data = new SearchIndexableRaw(context);
|
data = new SearchIndexableRaw(context);
|
||||||
data.title = context.getString(R.string.memory_size);
|
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);
|
data.screenTitle = context.getString(R.string.storage_settings);
|
||||||
result.add(data);
|
result.add(data);
|
||||||
|
|
||||||
data = new SearchIndexableRaw(context);
|
data = new SearchIndexableRaw(context);
|
||||||
data.title = context.getString(R.string.memory_available);
|
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);
|
data.screenTitle = context.getString(R.string.storage_settings);
|
||||||
result.add(data);
|
result.add(data);
|
||||||
|
|
||||||
data = new SearchIndexableRaw(context);
|
data = new SearchIndexableRaw(context);
|
||||||
data.title = context.getString(R.string.memory_dcim_usage);
|
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);
|
data.screenTitle = context.getString(R.string.storage_settings);
|
||||||
result.add(data);
|
result.add(data);
|
||||||
|
|
||||||
data = new SearchIndexableRaw(context);
|
data = new SearchIndexableRaw(context);
|
||||||
data.title = context.getString(R.string.memory_music_usage);
|
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);
|
data.screenTitle = context.getString(R.string.storage_settings);
|
||||||
result.add(data);
|
result.add(data);
|
||||||
|
|
||||||
data = new SearchIndexableRaw(context);
|
data = new SearchIndexableRaw(context);
|
||||||
data.title = context.getString(R.string.memory_media_misc_usage);
|
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);
|
data.screenTitle = context.getString(R.string.storage_settings);
|
||||||
result.add(data);
|
result.add(data);
|
||||||
|
|
||||||
data = new SearchIndexableRaw(context);
|
data = new SearchIndexableRaw(context);
|
||||||
data.title = context.getString(R.string.storage_menu_free);
|
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);
|
data.screenTitle = context.getString(R.string.storage_menu_free);
|
||||||
// We need to define all three in order for this to trigger properly.
|
// We need to define all three in order for this to trigger properly.
|
||||||
data.intentAction = StorageManager.ACTION_MANAGE_STORAGE;
|
data.intentAction = StorageManager.ACTION_MANAGE_STORAGE;
|
||||||
@@ -618,5 +628,69 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
|
|||||||
|
|
||||||
return result;
|
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 androidx.preference.Preference;
|
||||||
|
|
||||||
|
import com.android.settings.Utils;
|
||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
import com.android.settings.widget.GearPreference;
|
import com.android.settings.widget.GearPreference;
|
||||||
|
import com.android.settingslib.RestrictedPreference;
|
||||||
import com.android.settingslib.dream.DreamBackend;
|
import com.android.settingslib.dream.DreamBackend;
|
||||||
import com.android.settingslib.dream.DreamBackend.DreamInfo;
|
import com.android.settingslib.dream.DreamBackend.DreamInfo;
|
||||||
|
|
||||||
@@ -45,6 +47,7 @@ public class CurrentDreamPreferenceController extends BasePreferenceController {
|
|||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
super.updateState(preference);
|
super.updateState(preference);
|
||||||
setGearClickListenerForPreference(preference);
|
setGearClickListenerForPreference(preference);
|
||||||
|
setActiveDreamIcon(preference);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -78,4 +81,13 @@ public class CurrentDreamPreferenceController extends BasePreferenceController {
|
|||||||
.filter((info) -> info.isActive)
|
.filter((info) -> info.isActive)
|
||||||
.findFirst();
|
.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);
|
ListBuilder.ICON_IMAGE, title);
|
||||||
final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction,
|
final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction,
|
||||||
null /* actionTitle */, isMobileDataEnabled());
|
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(),
|
final ListBuilder listBuilder = new ListBuilder(mContext, getUri(),
|
||||||
ListBuilder.INFINITY)
|
ListBuilder.INFINITY)
|
||||||
.setAccentColor(color)
|
.setAccentColor(color)
|
||||||
.addRow(new ListBuilder.RowBuilder()
|
.addRow(rowBuilder);
|
||||||
.setTitle(title)
|
|
||||||
.setSubtitle(summary)
|
|
||||||
.addEndItem(toggleSliceAction)
|
|
||||||
.setPrimaryAction(primarySliceAction));
|
|
||||||
return listBuilder.build();
|
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
|
* 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 android.util.Log;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.notification.AppBubbleListPreferenceController;
|
||||||
import com.android.settings.notification.NotificationBackend;
|
import com.android.settings.notification.NotificationBackend;
|
||||||
import com.android.settings.search.BaseSearchIndexProvider;
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
@@ -56,18 +57,20 @@ public class AppBubbleNotificationSettings extends NotificationSettings implemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||||
mControllers = getPreferenceControllers(context, this);
|
mControllers = getPreferenceControllers(context, this, mDependentFieldListener);
|
||||||
return new ArrayList<>(mControllers);
|
return new ArrayList<>(mControllers);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static List<NotificationPreferenceController> getPreferenceControllers(
|
protected static List<NotificationPreferenceController> getPreferenceControllers(
|
||||||
Context context, AppBubbleNotificationSettings fragment) {
|
Context context, AppBubbleNotificationSettings fragment,
|
||||||
|
DependentFieldListener listener) {
|
||||||
List<NotificationPreferenceController> controllers = new ArrayList<>();
|
List<NotificationPreferenceController> controllers = new ArrayList<>();
|
||||||
controllers.add(new HeaderPreferenceController(context, fragment));
|
controllers.add(new HeaderPreferenceController(context, fragment));
|
||||||
controllers.add(new BubblePreferenceController(context, fragment != null
|
controllers.add(new BubblePreferenceController(context, fragment != null
|
||||||
? fragment.getChildFragmentManager()
|
? fragment.getChildFragmentManager()
|
||||||
: null,
|
: null,
|
||||||
new NotificationBackend(), true /* isAppPage */));
|
new NotificationBackend(), true /* isAppPage */, listener));
|
||||||
|
controllers.add(new AppBubbleListPreferenceController(context, new NotificationBackend()));
|
||||||
return controllers;
|
return controllers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +117,7 @@ public class AppBubbleNotificationSettings extends NotificationSettings implemen
|
|||||||
public List<AbstractPreferenceController> createPreferenceControllers(Context
|
public List<AbstractPreferenceController> createPreferenceControllers(Context
|
||||||
context) {
|
context) {
|
||||||
return new ArrayList<>(AppBubbleNotificationSettings.getPreferenceControllers(
|
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.NotificationChannel;
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.ParceledListSlice;
|
||||||
import android.content.pm.ShortcutInfo;
|
import android.content.pm.ShortcutInfo;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -33,6 +34,7 @@ import com.android.settings.applications.AppInfoBase;
|
|||||||
import com.android.settings.core.SubSettingLauncher;
|
import com.android.settings.core.SubSettingLauncher;
|
||||||
import com.android.settings.notification.NotificationBackend;
|
import com.android.settings.notification.NotificationBackend;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -42,8 +44,9 @@ public class AppConversationListPreferenceController extends NotificationPrefere
|
|||||||
private static final String KEY = "conversations";
|
private static final String KEY = "conversations";
|
||||||
public static final String ARG_FROM_SETTINGS = "fromSettings";
|
public static final String ARG_FROM_SETTINGS = "fromSettings";
|
||||||
|
|
||||||
private List<ConversationChannelWrapper> mConversations;
|
protected List<ConversationChannelWrapper> mConversations = new ArrayList<>();
|
||||||
private PreferenceCategory mPreference;
|
protected PreferenceCategory mPreference;
|
||||||
|
private boolean mHasSentMsg;
|
||||||
|
|
||||||
public AppConversationListPreferenceController(Context context, NotificationBackend backend) {
|
public AppConversationListPreferenceController(Context context, NotificationBackend backend) {
|
||||||
super(context, backend);
|
super(context, backend);
|
||||||
@@ -74,12 +77,23 @@ public class AppConversationListPreferenceController extends NotificationPrefere
|
|||||||
@Override
|
@Override
|
||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
mPreference = (PreferenceCategory) preference;
|
mPreference = (PreferenceCategory) preference;
|
||||||
|
loadConversationsAndPopulate();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void loadConversationsAndPopulate() {
|
||||||
|
if (mAppRow == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Load channel settings
|
// Load channel settings
|
||||||
new AsyncTask<Void, Void, Void>() {
|
new AsyncTask<Void, Void, Void>() {
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... unused) {
|
protected Void doInBackground(Void... unused) {
|
||||||
mConversations = mBackend.getConversations(mAppRow.pkg, mAppRow.uid).getList();
|
mHasSentMsg = mBackend.hasSentMessage(mAppRow.pkg, mAppRow.uid);
|
||||||
Collections.sort(mConversations, mConversationComparator);
|
ParceledListSlice<ConversationChannelWrapper> list =
|
||||||
|
mBackend.getConversations(mAppRow.pkg, mAppRow.uid);
|
||||||
|
if (list != null) {
|
||||||
|
mConversations = filterAndSortConversations(list.getList());
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,15 +107,35 @@ public class AppConversationListPreferenceController extends NotificationPrefere
|
|||||||
}.execute();
|
}.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() {
|
private void populateList() {
|
||||||
|
if (mPreference == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// TODO: if preference has children, compare with newly loaded list
|
// TODO: if preference has children, compare with newly loaded list
|
||||||
mPreference.removeAll();
|
mPreference.removeAll();
|
||||||
mPreference.setTitle(R.string.conversations_category_title);
|
|
||||||
|
|
||||||
if (mConversations.isEmpty()) {
|
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);
|
mPreference.setVisible(false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mPreference.setVisible(true);
|
mPreference.setVisible(true);
|
||||||
|
mPreference.setTitle(getTitleResId());
|
||||||
populateConversations();
|
populateConversations();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,6 +151,12 @@ public class AppConversationListPreferenceController extends NotificationPrefere
|
|||||||
|
|
||||||
protected Preference createConversationPref(final ConversationChannelWrapper conversation) {
|
protected Preference createConversationPref(final ConversationChannelWrapper conversation) {
|
||||||
Preference pref = new Preference(mContext);
|
Preference pref = new Preference(mContext);
|
||||||
|
populateConversationPreference(conversation, pref);
|
||||||
|
return pref;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void populateConversationPreference(final ConversationChannelWrapper conversation,
|
||||||
|
final Preference pref) {
|
||||||
ShortcutInfo si = conversation.getShortcutInfo();
|
ShortcutInfo si = conversation.getShortcutInfo();
|
||||||
|
|
||||||
pref.setTitle(si != null
|
pref.setTitle(si != null
|
||||||
@@ -147,7 +187,6 @@ public class AppConversationListPreferenceController extends NotificationPrefere
|
|||||||
.setTitleText(pref.getTitle())
|
.setTitleText(pref.getTitle())
|
||||||
.setSourceMetricsCategory(SettingsEnums.NOTIFICATION_APP_NOTIFICATION)
|
.setSourceMetricsCategory(SettingsEnums.NOTIFICATION_APP_NOTIFICATION)
|
||||||
.toIntent());
|
.toIntent());
|
||||||
return pref;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Comparator<ConversationChannelWrapper> mConversationComparator =
|
protected Comparator<ConversationChannelWrapper> mConversationComparator =
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ public class BubblePreference extends Preference implements View.OnClickListener
|
|||||||
private ButtonViewHolder mBubbleSelectedButton;
|
private ButtonViewHolder mBubbleSelectedButton;
|
||||||
private ButtonViewHolder mBubbleNoneButton;
|
private ButtonViewHolder mBubbleNoneButton;
|
||||||
|
|
||||||
|
private boolean mSelectedVisible;
|
||||||
|
|
||||||
public BubblePreference(Context context) {
|
public BubblePreference(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
}
|
}
|
||||||
@@ -89,6 +91,11 @@ public class BubblePreference extends Preference implements View.OnClickListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSelectedVisibility(boolean visible) {
|
||||||
|
mSelectedVisible = visible;
|
||||||
|
notifyChanged();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(final PreferenceViewHolder holder) {
|
public void onBindViewHolder(final PreferenceViewHolder holder) {
|
||||||
super.onBindViewHolder(holder);
|
super.onBindViewHolder(holder);
|
||||||
@@ -122,7 +129,8 @@ public class BubblePreference extends Preference implements View.OnClickListener
|
|||||||
mSelectedPreference == BUBBLE_PREFERENCE_SELECTED);
|
mSelectedPreference == BUBBLE_PREFERENCE_SELECTED);
|
||||||
bubbleSelected.setTag(BUBBLE_PREFERENCE_SELECTED);
|
bubbleSelected.setTag(BUBBLE_PREFERENCE_SELECTED);
|
||||||
bubbleSelected.setOnClickListener(this);
|
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);
|
View bubbleNone = holder.findViewById(R.id.bubble_none);
|
||||||
ImageView bubbleNoneImage = (ImageView) holder.findViewById(R.id.bubble_none_icon);
|
ImageView bubbleNoneImage = (ImageView) holder.findViewById(R.id.bubble_none_icon);
|
||||||
|
|||||||
@@ -47,12 +47,17 @@ public class BubblePreferenceController extends NotificationPreferenceController
|
|||||||
|
|
||||||
private FragmentManager mFragmentManager;
|
private FragmentManager mFragmentManager;
|
||||||
private boolean mIsAppPage;
|
private boolean mIsAppPage;
|
||||||
|
private boolean mHasSentInvalidMsg;
|
||||||
|
private int mNumConversations;
|
||||||
|
private NotificationSettings.DependentFieldListener mListener;
|
||||||
|
|
||||||
public BubblePreferenceController(Context context, @Nullable FragmentManager fragmentManager,
|
public BubblePreferenceController(Context context, @Nullable FragmentManager fragmentManager,
|
||||||
NotificationBackend backend, boolean isAppPage) {
|
NotificationBackend backend, boolean isAppPage,
|
||||||
|
@Nullable NotificationSettings.DependentFieldListener listener) {
|
||||||
super(context, backend);
|
super(context, backend);
|
||||||
mFragmentManager = fragmentManager;
|
mFragmentManager = fragmentManager;
|
||||||
mIsAppPage = isAppPage;
|
mIsAppPage = isAppPage;
|
||||||
|
mListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -81,10 +86,14 @@ public class BubblePreferenceController extends NotificationPreferenceController
|
|||||||
@Override
|
@Override
|
||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
if (mIsAppPage && mAppRow != null) {
|
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
|
// We're on the app specific bubble page which displays a tri-state
|
||||||
int backEndPref = mAppRow.bubblePreference;
|
int backEndPref = mAppRow.bubblePreference;
|
||||||
BubblePreference pref = (BubblePreference) preference;
|
BubblePreference pref = (BubblePreference) preference;
|
||||||
pref.setDisabledByAdmin(mAdmin);
|
pref.setDisabledByAdmin(mAdmin);
|
||||||
|
pref.setSelectedVisibility(!mHasSentInvalidMsg || mNumConversations > 0);
|
||||||
if (!isGloballyEnabled()) {
|
if (!isGloballyEnabled()) {
|
||||||
pref.setSelectedPreference(BUBBLE_PREFERENCE_NONE);
|
pref.setSelectedPreference(BUBBLE_PREFERENCE_NONE);
|
||||||
} else {
|
} else {
|
||||||
@@ -122,6 +131,9 @@ public class BubblePreferenceController extends NotificationPreferenceController
|
|||||||
mBackend.setAllowBubbles(mAppRow.pkg, mAppRow.uid, value);
|
mBackend.setAllowBubbles(mAppRow.pkg, mAppRow.uid, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (mListener != null) {
|
||||||
|
mListener.onFieldValueChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ public class ConversationNotificationSettings extends NotificationSettings {
|
|||||||
mControllers.add(new BadgePreferenceController(context, mBackend));
|
mControllers.add(new BadgePreferenceController(context, mBackend));
|
||||||
mControllers.add(new NotificationsOffPreferenceController(context));
|
mControllers.add(new NotificationsOffPreferenceController(context));
|
||||||
mControllers.add(new BubblePreferenceController(context, getChildFragmentManager(),
|
mControllers.add(new BubblePreferenceController(context, getChildFragmentManager(),
|
||||||
mBackend, false /* isAppPage */));
|
mBackend, false /* isAppPage */, null /* dependentFieldListener */));
|
||||||
mControllers.add(new ConversationDemotePreferenceController(context, this, mBackend));
|
mControllers.add(new ConversationDemotePreferenceController(context, this, mBackend));
|
||||||
mControllers.add(new BubbleCategoryPreferenceController(context));
|
mControllers.add(new BubbleCategoryPreferenceController(context));
|
||||||
mControllers.add(new BubbleLinkPreferenceController(context));
|
mControllers.add(new BubbleLinkPreferenceController(context));
|
||||||
|
|||||||
@@ -287,13 +287,13 @@ public class ZenModeBackend {
|
|||||||
|
|
||||||
protected int getAlarmsTotalSilencePeopleSummary(int category) {
|
protected int getAlarmsTotalSilencePeopleSummary(int category) {
|
||||||
if (category == NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES) {
|
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){
|
} 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) {
|
} else if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS) {
|
||||||
return R.string.zen_mode_from_no_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() {
|
protected int getConversationSummary() {
|
||||||
@@ -322,7 +322,7 @@ public class ZenModeBackend {
|
|||||||
return R.string.zen_mode_from_starred;
|
return R.string.zen_mode_from_starred;
|
||||||
case ZenPolicy.PEOPLE_TYPE_NONE:
|
case ZenPolicy.PEOPLE_TYPE_NONE:
|
||||||
default:
|
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;
|
return R.string.zen_mode_from_starred;
|
||||||
case ZenPolicy.PEOPLE_TYPE_NONE:
|
case ZenPolicy.PEOPLE_TYPE_NONE:
|
||||||
default:
|
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<>();
|
List<String> displayContacts = new ArrayList<>();
|
||||||
|
|
||||||
if (numStarredContacts == 0) {
|
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 {
|
} else {
|
||||||
for (int i = 0; i < 2 && i < numStarredContacts; i++) {
|
for (int i = 0; i < 2 && i < numStarredContacts; i++) {
|
||||||
displayContacts.add(starredContacts.get(i));
|
displayContacts.add(starredContacts.get(i));
|
||||||
@@ -494,10 +494,11 @@ public class ZenModeBackend {
|
|||||||
String getContactsNumberSummary(Context context) {
|
String getContactsNumberSummary(Context context) {
|
||||||
final int numContacts = queryAllContactsData().getCount();
|
final int numContacts = queryAllContactsData().getCount();
|
||||||
if (numContacts == 0) {
|
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,
|
return context.getResources().getQuantityString(R.plurals.zen_mode_contacts_count,
|
||||||
numContacts);
|
numContacts, numContacts);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Cursor queryStarredContactsData() {
|
private Cursor queryStarredContactsData() {
|
||||||
|
|||||||
@@ -91,7 +91,9 @@ public class ZenModePrioritySendersPreferenceController
|
|||||||
makeRadioPreference(KEY_ANY,
|
makeRadioPreference(KEY_ANY,
|
||||||
com.android.settings.R.string.zen_mode_from_anyone);
|
com.android.settings.R.string.zen_mode_from_anyone);
|
||||||
makeRadioPreference(KEY_NONE,
|
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();
|
updateSummaries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,10 @@ public class ZenModeSendersImagePreferenceController
|
|||||||
newImageRes = mIsMessages
|
newImageRes = mIsMessages
|
||||||
? R.drawable.zen_messages_none
|
? R.drawable.zen_messages_none
|
||||||
: R.drawable.zen_calls_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);
|
mImageView.setImageResource(newImageRes);
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ public class ZenModeSettings extends ZenModeSettingsBase {
|
|||||||
|| PRIORITY_CATEGORY_REPEAT_CALLERS == category, true);
|
|| PRIORITY_CATEGORY_REPEAT_CALLERS == category, true);
|
||||||
int numCategories = enabledCategories.size();
|
int numCategories = enabledCategories.size();
|
||||||
if (numCategories == 0) {
|
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) {
|
} else if (numCategories == 1) {
|
||||||
return mContext.getString(R.string.zen_mode_calls_summary_one,
|
return mContext.getString(R.string.zen_mode_calls_summary_one,
|
||||||
enabledCategories.get(0));
|
enabledCategories.get(0));
|
||||||
@@ -172,7 +172,7 @@ public class ZenModeSettings extends ZenModeSettingsBase {
|
|||||||
category -> PRIORITY_CATEGORY_MESSAGES == category, false);
|
category -> PRIORITY_CATEGORY_MESSAGES == category, false);
|
||||||
int numCategories = enabledCategories.size();
|
int numCategories = enabledCategories.size();
|
||||||
if (numCategories == 0) {
|
if (numCategories == 0) {
|
||||||
return mContext.getString(R.string.zen_mode_from_none);
|
return mContext.getString(R.string.zen_mode_none_messages);
|
||||||
} else {
|
} else {
|
||||||
return enabledCategories.get(0);
|
return enabledCategories.get(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,15 +82,18 @@ public class ZenModeSliceBuilder {
|
|||||||
final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction,
|
final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction,
|
||||||
null /* actionTitle */,
|
null /* actionTitle */,
|
||||||
isZenModeEnabled);
|
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,
|
return new ListBuilder(context, CustomSliceRegistry.ZEN_MODE_SLICE_URI,
|
||||||
ListBuilder.INFINITY)
|
ListBuilder.INFINITY)
|
||||||
.setAccentColor(color)
|
.setAccentColor(color)
|
||||||
.addRow(new RowBuilder()
|
.addRow(rowBuilder)
|
||||||
.setTitle(title)
|
|
||||||
.setSubtitle(subtitle)
|
|
||||||
.addEndItem(toggleSliceAction)
|
|
||||||
.setPrimaryAction(primarySliceAction))
|
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -241,16 +241,19 @@ public class SliceBuilderUtils {
|
|||||||
final SliceAction sliceAction = getToggleAction(context, sliceData,
|
final SliceAction sliceAction = getToggleAction(context, sliceData,
|
||||||
toggleController.isChecked());
|
toggleController.isChecked());
|
||||||
final Set<String> keywords = buildSliceKeywords(sliceData);
|
final Set<String> keywords = buildSliceKeywords(sliceData);
|
||||||
|
final RowBuilder rowBuilder = new RowBuilder()
|
||||||
return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
|
|
||||||
.setAccentColor(color)
|
|
||||||
.addRow(new RowBuilder()
|
|
||||||
.setTitle(sliceData.getTitle())
|
.setTitle(sliceData.getTitle())
|
||||||
.setSubtitle(subtitleText)
|
|
||||||
.setPrimaryAction(
|
.setPrimaryAction(
|
||||||
SliceAction.createDeeplink(contentIntent, icon,
|
SliceAction.createDeeplink(contentIntent, icon,
|
||||||
ListBuilder.ICON_IMAGE, sliceData.getTitle()))
|
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)
|
.setKeywords(keywords)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
@@ -262,16 +265,19 @@ public class SliceBuilderUtils {
|
|||||||
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
|
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
|
||||||
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
|
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
|
||||||
final Set<String> keywords = buildSliceKeywords(sliceData);
|
final Set<String> keywords = buildSliceKeywords(sliceData);
|
||||||
|
final RowBuilder rowBuilder = new RowBuilder()
|
||||||
return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
|
|
||||||
.setAccentColor(color)
|
|
||||||
.addRow(new RowBuilder()
|
|
||||||
.setTitle(sliceData.getTitle())
|
.setTitle(sliceData.getTitle())
|
||||||
.setSubtitle(subtitleText)
|
|
||||||
.setPrimaryAction(
|
.setPrimaryAction(
|
||||||
SliceAction.createDeeplink(contentIntent, icon,
|
SliceAction.createDeeplink(contentIntent, icon,
|
||||||
ListBuilder.ICON_IMAGE,
|
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)
|
.setKeywords(keywords)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
@@ -301,7 +307,6 @@ public class SliceBuilderUtils {
|
|||||||
}
|
}
|
||||||
final InputRangeBuilder inputRangeBuilder = new InputRangeBuilder()
|
final InputRangeBuilder inputRangeBuilder = new InputRangeBuilder()
|
||||||
.setTitle(sliceData.getTitle())
|
.setTitle(sliceData.getTitle())
|
||||||
.setSubtitle(subtitleText)
|
|
||||||
.setPrimaryAction(primaryAction)
|
.setPrimaryAction(primaryAction)
|
||||||
.setMax(sliderController.getMax())
|
.setMax(sliderController.getMax())
|
||||||
.setMin(sliderController.getMin())
|
.setMin(sliderController.getMin())
|
||||||
@@ -311,6 +316,9 @@ public class SliceBuilderUtils {
|
|||||||
inputRangeBuilder.setTitleItem(icon, ListBuilder.ICON_IMAGE);
|
inputRangeBuilder.setTitleItem(icon, ListBuilder.ICON_IMAGE);
|
||||||
color = CustomSliceable.COLOR_NOT_TINTED;
|
color = CustomSliceable.COLOR_NOT_TINTED;
|
||||||
}
|
}
|
||||||
|
if (!Utils.isSettingsIntelligence(context)) {
|
||||||
|
inputRangeBuilder.setSubtitle(subtitleText);
|
||||||
|
}
|
||||||
|
|
||||||
return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
|
return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
|
||||||
.setAccentColor(color)
|
.setAccentColor(color)
|
||||||
@@ -330,14 +338,17 @@ public class SliceBuilderUtils {
|
|||||||
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
|
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
|
||||||
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
|
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
|
||||||
final Set<String> keywords = buildSliceKeywords(sliceData);
|
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)
|
return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
|
||||||
.setAccentColor(color)
|
.setAccentColor(color)
|
||||||
.addRow(new RowBuilder()
|
.addRow(rowBuilder)
|
||||||
.setTitle(sliceData.getTitle())
|
|
||||||
.setSubtitle(subtitleText)
|
|
||||||
.setPrimaryAction(primaryAction)
|
|
||||||
.addEndItem(copyableAction))
|
|
||||||
.setKeywords(keywords)
|
.setKeywords(keywords)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
@@ -418,14 +429,17 @@ public class SliceBuilderUtils {
|
|||||||
final SliceAction primaryAction = SliceAction.createDeeplink(
|
final SliceAction primaryAction = SliceAction.createDeeplink(
|
||||||
getContentPendingIntent(context, data),
|
getContentPendingIntent(context, data),
|
||||||
icon, ListBuilder.ICON_IMAGE, title);
|
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)
|
return new ListBuilder(context, data.getUri(), ListBuilder.INFINITY)
|
||||||
.setAccentColor(color)
|
.setAccentColor(color)
|
||||||
.addRow(new RowBuilder()
|
.addRow(rowBuilder)
|
||||||
.setTitle(title)
|
|
||||||
.setTitleItem(icon, ListBuilder.ICON_IMAGE)
|
|
||||||
.setSubtitle(subtitle)
|
|
||||||
.setPrimaryAction(primaryAction))
|
|
||||||
.setKeywords(keywords)
|
.setKeywords(keywords)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -544,15 +544,10 @@ public class WifiSettings2 extends RestrictedSettingsFragment
|
|||||||
final WifiEntry selectedEntry =
|
final WifiEntry selectedEntry =
|
||||||
((LongPressWifiEntryPreference) preference).getWifiEntry();
|
((LongPressWifiEntryPreference) preference).getWifiEntry();
|
||||||
|
|
||||||
// If the clicked WiFi entry is never connected, launch Wi-Fi edit UI to edit password.
|
if (selectedEntry.shouldEditBeforeConnect()) {
|
||||||
if (selectedEntry.getSecurity() != WifiEntry.SECURITY_NONE
|
|
||||||
&& selectedEntry.getSecurity() != WifiEntry.SECURITY_OWE) {
|
|
||||||
final WifiConfiguration config = selectedEntry.getWifiConfiguration();
|
|
||||||
if (config != null && !config.getNetworkSelectionStatus().hasEverConnected()) {
|
|
||||||
launchConfigNewNetworkFragment(selectedEntry);
|
launchConfigNewNetworkFragment(selectedEntry);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
connect(selectedEntry, true /* editIfNoConfig */, true /* fullScreenEdit */);
|
connect(selectedEntry, true /* editIfNoConfig */, true /* fullScreenEdit */);
|
||||||
} else if (preference == mAddWifiNetworkPreference) {
|
} else if (preference == mAddWifiNetworkPreference) {
|
||||||
|
|||||||
@@ -269,14 +269,17 @@ public class WifiCallingSliceHelper {
|
|||||||
// Top row shows information on current preference state
|
// Top row shows information on current preference state
|
||||||
final ListBuilder listBuilder = new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY)
|
final ListBuilder listBuilder = new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY)
|
||||||
.setAccentColor(Utils.getColorAccentDefaultColor(mContext));
|
.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))
|
.setTitle(res.getText(R.string.wifi_calling_mode_title))
|
||||||
.setSubtitle(getWifiCallingPreferenceSummary(currentWfcPref, subId))
|
|
||||||
.setPrimaryAction(SliceAction.createDeeplink(
|
.setPrimaryAction(SliceAction.createDeeplink(
|
||||||
getActivityIntent(ACTION_WIFI_CALLING_SETTINGS_ACTIVITY),
|
getActivityIntent(ACTION_WIFI_CALLING_SETTINGS_ACTIVITY),
|
||||||
icon,
|
icon,
|
||||||
ListBuilder.ICON_IMAGE,
|
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) {
|
if (isWifiOnlySupported) {
|
||||||
listBuilder.addRow(wifiPreferenceRowBuilder(listBuilder,
|
listBuilder.addRow(wifiPreferenceRowBuilder(listBuilder,
|
||||||
@@ -458,14 +461,17 @@ public class WifiCallingSliceHelper {
|
|||||||
private Slice getNonActionableWifiCallingSlice(CharSequence title, CharSequence subtitle,
|
private Slice getNonActionableWifiCallingSlice(CharSequence title, CharSequence subtitle,
|
||||||
Uri sliceUri, PendingIntent primaryActionIntent) {
|
Uri sliceUri, PendingIntent primaryActionIntent) {
|
||||||
final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.wifi_signal);
|
final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.wifi_signal);
|
||||||
return new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY)
|
final RowBuilder rowBuilder = new RowBuilder()
|
||||||
.setAccentColor(Utils.getColorAccentDefaultColor(mContext))
|
|
||||||
.addRow(new RowBuilder()
|
|
||||||
.setTitle(title)
|
.setTitle(title)
|
||||||
.setSubtitle(subtitle)
|
|
||||||
.setPrimaryAction(SliceAction.createDeeplink(
|
.setPrimaryAction(SliceAction.createDeeplink(
|
||||||
primaryActionIntent, icon, ListBuilder.SMALL_IMAGE,
|
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();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import static org.mockito.Mockito.verify;
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.ActionBar;
|
import android.app.ActionBar;
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -67,6 +66,7 @@ import org.mockito.MockitoAnnotations;
|
|||||||
import org.robolectric.Robolectric;
|
import org.robolectric.Robolectric;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.shadows.ShadowBinder;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -281,4 +281,22 @@ public class UtilsTest {
|
|||||||
|
|
||||||
assertThat(actionBar.getElevation()).isEqualTo(0.f);
|
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
|
@Test
|
||||||
public void getServiceSummary_invisibleType_shortcutDisabled_showsOffSummary() {
|
public void getServiceSummary_invisibleToggle_shortcutDisabled_showsOffSummary() {
|
||||||
setInvisibleFragmentType(mServiceInfo);
|
setInvisibleToggleFragmentType(mServiceInfo);
|
||||||
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
|
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
|
||||||
|
|
||||||
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
|
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
|
||||||
@@ -277,7 +277,7 @@ public class AccessibilitySettingsTest {
|
|||||||
when(mockInfo.getComponentName()).thenReturn(DUMMY_COMPONENT_NAME);
|
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.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
|
||||||
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,36 +102,36 @@ public final class AccessibilityUtilTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getAccessibilityServiceFragmentType_targetSdkQ_legacyType() {
|
public void getAccessibilityServiceFragmentType_targetSdkQ_volumeShortcutType() {
|
||||||
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
|
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
|
||||||
|
|
||||||
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
|
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
|
||||||
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
||||||
|
|
||||||
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
|
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
|
||||||
AccessibilityUtil.AccessibilityServiceFragmentType.LEGACY);
|
AccessibilityUtil.AccessibilityServiceFragmentType.VOLUME_SHORTCUT_TOGGLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getAccessibilityServiceFragmentType_targetSdkR_HaveA11yButton_headlessType() {
|
public void getAccessibilityServiceFragmentType_targetSdkR_HaveA11yButton_invisibleType() {
|
||||||
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
|
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
|
||||||
|
|
||||||
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
|
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
|
||||||
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
||||||
|
|
||||||
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
|
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
|
||||||
AccessibilityUtil.AccessibilityServiceFragmentType.INVISIBLE);
|
AccessibilityUtil.AccessibilityServiceFragmentType.INVISIBLE_TOGGLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getAccessibilityServiceFragmentType_targetSdkR_NoA11yButton_intuitiveType() {
|
public void getAccessibilityServiceFragmentType_targetSdkR_NoA11yButton_toggleType() {
|
||||||
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
|
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
|
||||||
|
|
||||||
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
|
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
|
||||||
info.flags |= ~AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
info.flags |= ~AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
||||||
|
|
||||||
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
|
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
|
||||||
AccessibilityUtil.AccessibilityServiceFragmentType.INTUITIVE);
|
AccessibilityUtil.AccessibilityServiceFragmentType.TOGGLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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;
|
private PreferenceScreen mScreen;
|
||||||
@Mock
|
@Mock
|
||||||
private FragmentManager mFragmentManager;
|
private FragmentManager mFragmentManager;
|
||||||
|
@Mock
|
||||||
|
private NotificationSettings.DependentFieldListener mListener;
|
||||||
|
|
||||||
private BubblePreferenceController mController;
|
private BubblePreferenceController mController;
|
||||||
private BubblePreferenceController mAppPageController;
|
private BubblePreferenceController mAppPageController;
|
||||||
@@ -93,9 +95,9 @@ public class BubblePreferenceControllerTest {
|
|||||||
mContext = RuntimeEnvironment.application;
|
mContext = RuntimeEnvironment.application;
|
||||||
when(mFragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class));
|
when(mFragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class));
|
||||||
mController = spy(new BubblePreferenceController(mContext, mFragmentManager, mBackend,
|
mController = spy(new BubblePreferenceController(mContext, mFragmentManager, mBackend,
|
||||||
false /* isAppPage */));
|
false /* isAppPage */, mListener));
|
||||||
mAppPageController = spy(new BubblePreferenceController(mContext, mFragmentManager,
|
mAppPageController = spy(new BubblePreferenceController(mContext, mFragmentManager,
|
||||||
mBackend, true /* isAppPage */));
|
mBackend, true /* isAppPage */, mListener));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -106,7 +108,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsAvailable_notIfAppBlocked() {
|
public void isAvailable_notIfAppBlocked() {
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
appRow.banned = true;
|
appRow.banned = true;
|
||||||
@@ -115,7 +117,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsAvailable_notIfChannelBlocked() {
|
public void isAvailable_notIfChannelBlocked() {
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
NotificationChannel channel = mock(NotificationChannel.class);
|
NotificationChannel channel = mock(NotificationChannel.class);
|
||||||
@@ -125,7 +127,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsAvailable_channel_yesIfAppOff() {
|
public void isAvailable_channel_yesIfAppOff() {
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
appRow.bubblePreference = BUBBLE_PREFERENCE_NONE;
|
appRow.bubblePreference = BUBBLE_PREFERENCE_NONE;
|
||||||
@@ -137,7 +139,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsNotAvailable_ifOffGlobally_app() {
|
public void isNotAvailable_ifOffGlobally_app() {
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
mController.onResume(appRow, null, null, null, null, null);
|
mController.onResume(appRow, null, null, null, null, null);
|
||||||
Settings.Global.putInt(mContext.getContentResolver(),
|
Settings.Global.putInt(mContext.getContentResolver(),
|
||||||
@@ -147,7 +149,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsAvailable_notIfOffGlobally_channel() {
|
public void isAvailable_notIfOffGlobally_channel() {
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
NotificationChannel channel = mock(NotificationChannel.class);
|
NotificationChannel channel = mock(NotificationChannel.class);
|
||||||
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
||||||
@@ -159,7 +161,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsAvailable_app_evenIfOffGlobally() {
|
public void isAvailable_app_evenIfOffGlobally() {
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
mAppPageController.onResume(appRow, null, null, null, null, null);
|
mAppPageController.onResume(appRow, null, null, null, null, null);
|
||||||
Settings.Global.putInt(mContext.getContentResolver(),
|
Settings.Global.putInt(mContext.getContentResolver(),
|
||||||
@@ -169,7 +171,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsAvailable_app() {
|
public void isAvailable_app() {
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
mController.onResume(appRow, null, null, null, null, null);
|
mController.onResume(appRow, null, null, null, null, null);
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||||
@@ -178,7 +180,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsAvailable_defaultChannel() {
|
public void isAvailable_defaultChannel() {
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
||||||
NotificationChannel channel = mock(NotificationChannel.class);
|
NotificationChannel channel = mock(NotificationChannel.class);
|
||||||
@@ -191,7 +193,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsAvailable_channel() {
|
public void isAvailable_channel() {
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
||||||
NotificationChannel channel = mock(NotificationChannel.class);
|
NotificationChannel channel = mock(NotificationChannel.class);
|
||||||
@@ -203,7 +205,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_disabledByAdmin() {
|
public void updateState_disabledByAdmin() {
|
||||||
NotificationChannel channel = mock(NotificationChannel.class);
|
NotificationChannel channel = mock(NotificationChannel.class);
|
||||||
when(channel.getId()).thenReturn("something");
|
when(channel.getId()).thenReturn("something");
|
||||||
mController.onResume(new NotificationBackend.AppRow(), channel, null,
|
mController.onResume(new NotificationBackend.AppRow(), channel, null,
|
||||||
@@ -216,7 +218,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_app_disabledByAdmin() {
|
public void updateState_app_disabledByAdmin() {
|
||||||
NotificationChannel channel = mock(NotificationChannel.class);
|
NotificationChannel channel = mock(NotificationChannel.class);
|
||||||
when(channel.getId()).thenReturn("something");
|
when(channel.getId()).thenReturn("something");
|
||||||
mAppPageController.onResume(new NotificationBackend.AppRow(), channel, null,
|
mAppPageController.onResume(new NotificationBackend.AppRow(), channel, null,
|
||||||
@@ -229,7 +231,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_channel_channelNotBlockable() {
|
public void updateState_channel_channelNotBlockable() {
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
NotificationChannel channel = mock(NotificationChannel.class);
|
NotificationChannel channel = mock(NotificationChannel.class);
|
||||||
@@ -243,7 +245,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_channel() {
|
public void updateState_channel() {
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
NotificationChannel channel = mock(NotificationChannel.class);
|
NotificationChannel channel = mock(NotificationChannel.class);
|
||||||
@@ -263,7 +265,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_app() {
|
public void updateState_app() {
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
appRow.label = "App!";
|
appRow.label = "App!";
|
||||||
@@ -288,7 +290,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_app_offGlobally() {
|
public void updateState_app_offGlobally() {
|
||||||
Settings.Global.putInt(mContext.getContentResolver(),
|
Settings.Global.putInt(mContext.getContentResolver(),
|
||||||
NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF);
|
NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF);
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
@@ -302,7 +304,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnPreferenceChange_on_channel() {
|
public void onPreferenceChange_on_channel() {
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED;
|
appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED;
|
||||||
@@ -321,7 +323,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnPreferenceChange_off_channel() {
|
public void onPreferenceChange_off_channel() {
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED;
|
appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED;
|
||||||
@@ -341,7 +343,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnPreferenceChange_app_all() {
|
public void onPreferenceChange_app_all() {
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
appRow.bubblePreference = BUBBLE_PREFERENCE_NONE;
|
appRow.bubblePreference = BUBBLE_PREFERENCE_NONE;
|
||||||
@@ -379,7 +381,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnPreferenceChange_app_selected() {
|
public void onPreferenceChange_app_selected() {
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
||||||
@@ -397,7 +399,7 @@ public class BubblePreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnPreferenceChange_app_none() {
|
public void onPreferenceChange_app_none() {
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
|
||||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||||
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
appRow.bubblePreference = BUBBLE_PREFERENCE_ALL;
|
||||||
@@ -413,4 +415,17 @@ public class BubblePreferenceControllerTest {
|
|||||||
assertEquals(BUBBLE_PREFERENCE_NONE, appRow.bubblePreference);
|
assertEquals(BUBBLE_PREFERENCE_NONE, appRow.bubblePreference);
|
||||||
verify(mBackend, times(1)).setAllowBubbles(any(), anyInt(), eq(BUBBLE_PREFERENCE_NONE));
|
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 static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@@ -455,37 +454,6 @@ public class SliceBuilderUtilsTest {
|
|||||||
assertThat(actualIconResource).isEqualTo(settingsIcon);
|
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() {
|
private SliceData getDummyData() {
|
||||||
return getDummyData(TOGGLE_CONTROLLER, SUMMARY, SliceData.SliceType.SWITCH, SCREEN_TITLE,
|
return getDummyData(TOGGLE_CONTROLLER, SUMMARY, SliceData.SliceType.SWITCH, SCREEN_TITLE,
|
||||||
ICON, null /* unavailableSliceSubtitle */);
|
ICON, null /* unavailableSliceSubtitle */);
|
||||||
|
|||||||
Reference in New Issue
Block a user