Snap for 12177962 from 58d851863c to 24Q4-release

Change-Id: I3cb52a183492b0c0614325574b3650c8b13be661
This commit is contained in:
Android Build Coastguard Worker
2024-08-03 03:21:19 +00:00
12 changed files with 1404 additions and 327 deletions

View File

@@ -1503,12 +1503,14 @@
<!-- A locale list of not supporting Terms of Address. [DO NOT TRANSLATE] --> <!-- A locale list of not supporting Terms of Address. [DO NOT TRANSLATE] -->
<string-array name="terms_of_address_unsupported_locales"> <string-array name="terms_of_address_unsupported_locales">
<item>fr-CA</item> <!-- French (Canada) -->
</string-array> </string-array>
<!-- A language list of supporting Terms of Address. [DO NOT TRANSLATE] --> <!-- A language list of supporting Terms of Address. [DO NOT TRANSLATE] -->
<string-array name="terms_of_address_supported_languages"> <string-array name="terms_of_address_supported_languages">
<item>fr</item> <!-- French --> <item>fr</item> <!-- French -->
<item>es</item> <!-- Spanish -->
<item>it</item> <!-- Italian -->
<item>de</item> <!-- German -->
</string-array> </string-array>
<!-- Entries for private space auto lock option --> <!-- Entries for private space auto lock option -->

View File

@@ -9177,6 +9177,8 @@
<!-- [CHAR LIMIT=120] Zen mode settings: Title for conversations settings page --> <!-- [CHAR LIMIT=120] Zen mode settings: Title for conversations settings page -->
<string name="zen_mode_conversations_title">Conversations</string> <string name="zen_mode_conversations_title">Conversations</string>
<string name="zen_mode_from_all_conversations">All conversations</string> <string name="zen_mode_from_all_conversations">All conversations</string>
<!-- [CHAR LIMIT=40] Version of zen_mode_from_all_conversations when it is a non-first member of a list -->
<string name="zen_mode_from_all_conversations_second">all conversations</string>
<string name="zen_mode_from_important_conversations">Priority conversations</string> <string name="zen_mode_from_important_conversations">Priority conversations</string>
<!-- [CHAR LIMIT=40] Version of the above for "priority conversations" when it is a non-first member of a list --> <!-- [CHAR LIMIT=40] Version of the above for "priority conversations" when it is a non-first member of a list -->
<string name="zen_mode_from_important_conversations_second">priority conversations</string> <string name="zen_mode_from_important_conversations_second">priority conversations</string>

View File

@@ -17,38 +17,47 @@
package com.android.settings.fuelgauge.batteryusage; package com.android.settings.fuelgauge.batteryusage;
import android.content.Context; import android.content.Context;
import android.util.ArrayMap; import android.util.SparseArray;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.core.util.Pair;
import com.android.settings.fuelgauge.BatteryOptimizeUtils; import com.android.settings.fuelgauge.BatteryOptimizeUtils;
import com.android.settingslib.fuelgauge.PowerAllowlistBackend; import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
import java.util.Map;
/** A cache to log battery optimization mode of an app */ /** A cache to log battery optimization mode of an app */
final class BatteryOptimizationModeCache { final class BatteryOptimizationModeCache {
private static final String TAG = "BatteryOptimizationModeCache"; private static final String TAG = "BatteryOptimizationModeCache";
@VisibleForTesting final Map<Integer, BatteryOptimizationMode> mBatteryOptimizeModeCacheMap; /* Stores the battery optimization mode and mutable state for each UID. */
@VisibleForTesting
final SparseArray<Pair<BatteryOptimizationMode, Boolean>> mBatteryOptimizeModeCache;
private final Context mContext; private final Context mContext;
BatteryOptimizationModeCache(final Context context) { BatteryOptimizationModeCache(final Context context) {
mContext = context; mContext = context;
mBatteryOptimizeModeCacheMap = new ArrayMap<>(); mBatteryOptimizeModeCache = new SparseArray<>();
PowerAllowlistBackend.getInstance(mContext).refreshList(); PowerAllowlistBackend.getInstance(mContext).refreshList();
} }
BatteryOptimizationMode getBatteryOptimizeMode(final int uid, final String packageName) { Pair<BatteryOptimizationMode, Boolean> getBatteryOptimizeModeInfo(
if (!mBatteryOptimizeModeCacheMap.containsKey(uid)) { final int uid, final String packageName) {
if (!mBatteryOptimizeModeCache.contains(uid)) {
final BatteryOptimizeUtils batteryOptimizeUtils = final BatteryOptimizeUtils batteryOptimizeUtils =
new BatteryOptimizeUtils(mContext, uid, packageName); new BatteryOptimizeUtils(mContext, uid, packageName);
mBatteryOptimizeModeCacheMap.put( mBatteryOptimizeModeCache.put(
uid, uid,
BatteryOptimizationMode.forNumber( Pair.create(
batteryOptimizeUtils.getAppOptimizationMode(/* refreshList= */ false))); BatteryOptimizationMode.forNumber(
batteryOptimizeUtils.getAppOptimizationMode(
/* refreshList= */ false)),
batteryOptimizeUtils.isOptimizeModeMutable()));
} }
return mBatteryOptimizeModeCacheMap.get(uid); final Pair<BatteryOptimizationMode, Boolean> batteryOptimizeModeInfo =
mBatteryOptimizeModeCache.get(uid);
return batteryOptimizeModeInfo != null
? batteryOptimizeModeInfo
: new Pair<>(BatteryOptimizationMode.MODE_UNKNOWN, false);
} }
} }

View File

@@ -35,6 +35,7 @@ import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.core.util.Pair;
import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity; import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity;
@@ -542,9 +543,11 @@ public final class ConvertUtils {
} }
// Log the battery optimization mode of AppEntry while converting to batteryUsageSlot. // Log the battery optimization mode of AppEntry while converting to batteryUsageSlot.
if (optimizationModeCache != null && !batteryDiffEntry.isSystemEntry()) { if (optimizationModeCache != null && !batteryDiffEntry.isSystemEntry()) {
builder.setAppOptimizationMode( final Pair<BatteryOptimizationMode, Boolean> batteryOptimizationModeInfo =
optimizationModeCache.getBatteryOptimizeMode( optimizationModeCache.getBatteryOptimizeModeInfo(
(int) batteryDiffEntry.mUid, batteryDiffEntry.getPackageName())); (int) batteryDiffEntry.mUid, batteryDiffEntry.getPackageName());
builder.setAppOptimizationMode(batteryOptimizationModeInfo.first)
.setIsAppOptimizationModeMutable(batteryOptimizationModeInfo.second);
} }
return builder.build(); return builder.build();
} }

View File

@@ -40,4 +40,5 @@ message BatteryUsageDiff {
optional int64 screen_on_time = 16; optional int64 screen_on_time = 16;
optional int64 foreground_service_usage_time = 17; optional int64 foreground_service_usage_time = 17;
optional BatteryOptimizationMode app_optimization_mode = 18; optional BatteryOptimizationMode app_optimization_mode = 18;
optional bool is_app_optimization_mode_mutable = 19;
} }

View File

@@ -81,12 +81,20 @@ class ZenHelperBackend {
} }
} }
@SuppressWarnings("unchecked") ImmutableList<ConversationChannelWrapper> getAllConversations() {
return getConversations(false);
}
ImmutableList<ConversationChannelWrapper> getImportantConversations() { ImmutableList<ConversationChannelWrapper> getImportantConversations() {
return getConversations(true);
}
@SuppressWarnings("unchecked")
private ImmutableList<ConversationChannelWrapper> getConversations(boolean onlyImportant) {
try { try {
ImmutableList.Builder<ConversationChannelWrapper> list = new ImmutableList.Builder<>(); ImmutableList.Builder<ConversationChannelWrapper> list = new ImmutableList.Builder<>();
ParceledListSlice<ConversationChannelWrapper> parceledList = mInm.getConversations( ParceledListSlice<ConversationChannelWrapper> parceledList = mInm.getConversations(
/* onlyImportant= */ true); onlyImportant);
if (parceledList != null) { if (parceledList != null) {
for (ConversationChannelWrapper conversation : parceledList.getList()) { for (ConversationChannelWrapper conversation : parceledList.getList()) {
if (!conversation.getNotificationChannel().isDemoted()) { if (!conversation.getNotificationChannel().isDemoted()) {

View File

@@ -189,8 +189,7 @@ class ZenModePeopleLinkPreferenceController extends AbstractZenModePreferenceCon
: CONVERSATION_SENDERS_NONE; : CONVERSATION_SENDERS_NONE;
ImmutableList<ConversationChannelWrapper> conversationsAllowed = ImmutableList.of(); ImmutableList<ConversationChannelWrapper> conversationsAllowed = ImmutableList.of();
if (conversationSendersAllowed == CONVERSATION_SENDERS_ANYONE) { if (conversationSendersAllowed == CONVERSATION_SENDERS_ANYONE) {
// TODO: b/354658240 - Need to handle CONVERSATION_SENDERS_ANYONE? conversationsAllowed = mHelperBackend.getAllConversations();
return;
} else if (conversationSendersAllowed == CONVERSATION_SENDERS_IMPORTANT) { } else if (conversationSendersAllowed == CONVERSATION_SENDERS_IMPORTANT) {
conversationsAllowed = mHelperBackend.getImportantConversations(); conversationsAllowed = mHelperBackend.getImportantConversations();
} }
@@ -223,7 +222,7 @@ class ZenModePeopleLinkPreferenceController extends AbstractZenModePreferenceCon
peopleItem.conversation.getShortcutInfo(), peopleItem.conversation.getShortcutInfo(),
peopleItem.conversation.getPkg(), peopleItem.conversation.getPkg(),
peopleItem.conversation.getUid(), peopleItem.conversation.getUid(),
/* important= */ true); peopleItem.conversation.getNotificationChannel().isImportantConversation());
} else { } else {
throw new IllegalArgumentException("Neither all nor contact nor conversation!"); throw new IllegalArgumentException("Neither all nor contact nor conversation!");
} }

View File

@@ -26,6 +26,8 @@ import static android.service.notification.ZenPolicy.PEOPLE_TYPE_NONE;
import static android.service.notification.ZenPolicy.PEOPLE_TYPE_STARRED; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_STARRED;
import static android.service.notification.ZenPolicy.PEOPLE_TYPE_UNSET; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_UNSET;
import static com.google.common.base.Preconditions.checkNotNull;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@@ -36,7 +38,6 @@ import android.service.notification.ZenPolicy;
import android.view.View; import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
@@ -48,11 +49,13 @@ import com.android.settingslib.notification.modes.ZenMode;
import com.android.settingslib.notification.modes.ZenModesBackend; import com.android.settingslib.notification.modes.ZenModesBackend;
import com.android.settingslib.widget.SelectorWithWidgetPreference; import com.android.settingslib.widget.SelectorWithWidgetPreference;
import java.util.ArrayList; import com.google.common.collect.ImmutableSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.LinkedHashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
* Common preference controller functionality for zen mode priority senders preferences for both * Common preference controller functionality for zen mode priority senders preferences for both
@@ -69,9 +72,11 @@ class ZenModePrioritySendersPreferenceController
static final String KEY_ANY = "senders_anyone"; static final String KEY_ANY = "senders_anyone";
static final String KEY_CONTACTS = "senders_contacts"; static final String KEY_CONTACTS = "senders_contacts";
static final String KEY_STARRED = "senders_starred_contacts"; static final String KEY_STARRED = "senders_starred_contacts";
static final String KEY_IMPORTANT = "conversations_important"; static final String KEY_IMPORTANT_CONVERSATIONS = "conversations_important";
static final String KEY_ANY_CONVERSATIONS = "conversations_any";
static final String KEY_NONE = "senders_none"; static final String KEY_NONE = "senders_none";
private int mNumAllConversations = 0;
private int mNumImportantConversations = 0; private int mNumImportantConversations = 0;
private static final Intent ALL_CONTACTS_INTENT = private static final Intent ALL_CONTACTS_INTENT =
@@ -86,7 +91,8 @@ class ZenModePrioritySendersPreferenceController
private final ZenHelperBackend mHelperBackend; private final ZenHelperBackend mHelperBackend;
private final PackageManager mPackageManager; private final PackageManager mPackageManager;
private PreferenceCategory mPreferenceCategory; private PreferenceCategory mPreferenceCategory;
private List<SelectorWithWidgetPreference> mSelectorPreferences = new ArrayList<>(); private final LinkedHashMap<String, SelectorWithWidgetPreference> mOptions =
new LinkedHashMap<>();
private final ZenModeSummaryHelper mZenModeSummaryHelper; private final ZenModeSummaryHelper mZenModeSummaryHelper;
@@ -110,53 +116,92 @@ class ZenModePrioritySendersPreferenceController
@Override @Override
public void displayPreference(PreferenceScreen screen) { public void displayPreference(PreferenceScreen screen) {
mPreferenceCategory = screen.findPreference(getPreferenceKey()); mPreferenceCategory = checkNotNull(screen.findPreference(getPreferenceKey()));
if (mPreferenceCategory.getPreferenceCount() == 0) { if (mPreferenceCategory.getPreferenceCount() == 0) {
makeSelectorPreference(KEY_STARRED, makeSelectorPreference(KEY_STARRED,
com.android.settings.R.string.zen_mode_from_starred, mIsMessages); com.android.settings.R.string.zen_mode_from_starred, mIsMessages, true);
makeSelectorPreference(KEY_CONTACTS, makeSelectorPreference(KEY_CONTACTS,
com.android.settings.R.string.zen_mode_from_contacts, mIsMessages); com.android.settings.R.string.zen_mode_from_contacts, mIsMessages, true);
if (mIsMessages) { if (mIsMessages) {
makeSelectorPreference(KEY_IMPORTANT, // "Any conversations" will only be available as option if it is the current value.
com.android.settings.R.string.zen_mode_from_important_conversations, true); // Because it's confusing and we don't want users setting it up that way, but apps
// could create such ZenPolicies and we must show that.
makeSelectorPreference(KEY_ANY_CONVERSATIONS,
com.android.settings.R.string.zen_mode_from_all_conversations, true,
/* isVisibleByDefault= */ false);
makeSelectorPreference(KEY_IMPORTANT_CONVERSATIONS,
com.android.settings.R.string.zen_mode_from_important_conversations, true,
true);
} }
makeSelectorPreference(KEY_ANY, makeSelectorPreference(KEY_ANY,
com.android.settings.R.string.zen_mode_from_anyone, mIsMessages); com.android.settings.R.string.zen_mode_from_anyone, mIsMessages, true);
makeSelectorPreference(KEY_NONE, makeSelectorPreference(KEY_NONE,
com.android.settings.R.string.zen_mode_none_messages, mIsMessages); com.android.settings.R.string.zen_mode_none_messages, mIsMessages, true);
} }
super.displayPreference(screen); super.displayPreference(screen);
} }
@Override @Override
public void updateState(Preference preference, @NonNull ZenMode zenMode) { public void updateState(Preference preference, @NonNull ZenMode zenMode) {
final int contacts = getPrioritySenders(zenMode.getPolicy());
final int conversations = getPriorityConversationSenders(zenMode.getPolicy());
if (mIsMessages) { if (mIsMessages) {
updateChannelCounts(); updateChannelCounts();
}
final int currContactsSetting = getPrioritySenders(zenMode.getPolicy());
final int currConversationsSetting = getPriorityConversationSenders(zenMode.getPolicy());
for (SelectorWithWidgetPreference pref : mSelectorPreferences) {
// for each preference, check whether the current state matches what this state
// would look like if the button were checked.
final int[] checkedState = keyToSettingEndState(pref.getKey(), true);
final int checkedContactsSetting = checkedState[0];
final int checkedConversationsSetting = checkedState[1];
boolean match = checkedContactsSetting == currContactsSetting; if (contacts == PEOPLE_TYPE_ANYONE) {
if (mIsMessages && checkedConversationsSetting != CONVERSATION_SENDERS_UNSET) { setSelectedOption(KEY_ANY);
// "CONVERSATION_SENDERS_UNSET" in checkedContactsSetting means this preference } else if (contacts == PEOPLE_TYPE_NONE && conversations == CONVERSATION_SENDERS_NONE) {
// doesn't govern the priority senders setting, so the full match happens when setSelectedOption(KEY_NONE);
// either the priority senders setting matches or if it's CONVERSATION_SENDERS_UNSET } else {
// so only the conversation setting needs to match. ImmutableSet.Builder<String> selectedOptions = new ImmutableSet.Builder<>();
match = (match || checkedContactsSetting == PEOPLE_TYPE_UNSET) if (contacts == PEOPLE_TYPE_STARRED) {
&& (checkedConversationsSetting == currConversationsSetting); selectedOptions.add(KEY_STARRED);
} else if (contacts == PEOPLE_TYPE_CONTACTS) {
selectedOptions.add(KEY_CONTACTS);
}
if (conversations == CONVERSATION_SENDERS_IMPORTANT) {
selectedOptions.add(KEY_IMPORTANT_CONVERSATIONS);
} else if (conversations == CONVERSATION_SENDERS_ANYONE) {
selectedOptions.add(KEY_ANY_CONVERSATIONS);
}
setSelectedOptions(selectedOptions.build());
}
} else {
// Calls is easy!
switch (contacts) {
case PEOPLE_TYPE_ANYONE -> setSelectedOption(KEY_ANY);
case PEOPLE_TYPE_CONTACTS -> setSelectedOption(KEY_CONTACTS);
case PEOPLE_TYPE_STARRED -> setSelectedOption(KEY_STARRED);
case PEOPLE_TYPE_NONE -> setSelectedOption(KEY_NONE);
default -> throw new IllegalArgumentException("Unexpected PeopleType: " + contacts);
} }
pref.setChecked(match);
} }
updateSummaries(); updateSummaries();
} }
private void setSelectedOption(String key) {
setSelectedOptions(ImmutableSet.of(key));
}
private void setSelectedOptions(Set<String> keys) {
if (keys.isEmpty()) {
throw new IllegalArgumentException("At least one option should be selected!");
}
for (SelectorWithWidgetPreference optionPreference : mOptions.values()) {
optionPreference.setChecked(keys.contains(optionPreference.getKey()));
if (optionPreference.isChecked()) {
// Ensure selected options are visible. This is to support "Any conversations"
// which is only shown if the policy has Conversations=Anyone (and doesn't have
// messages=Anyone), and then remains visible until the user exits the page
// (so that toggling back and forth is possible without the option disappearing).
optionPreference.setVisible(true);
}
}
}
public void onResume() { public void onResume() {
if (mIsMessages) { if (mIsMessages) {
updateChannelCounts(); updateChannelCounts();
@@ -165,6 +210,7 @@ class ZenModePrioritySendersPreferenceController
} }
private void updateChannelCounts() { private void updateChannelCounts() {
mNumAllConversations = mHelperBackend.getAllConversations().size();
mNumImportantConversations = mHelperBackend.getImportantConversations().size(); mNumImportantConversations = mHelperBackend.getImportantConversations().size();
} }
@@ -183,13 +229,14 @@ class ZenModePrioritySendersPreferenceController
return CONVERSATION_SENDERS_UNSET; return CONVERSATION_SENDERS_UNSET;
} }
private SelectorWithWidgetPreference makeSelectorPreference(String key, int titleId, private void makeSelectorPreference(String key, int titleId,
boolean isCheckbox) { boolean isCheckbox, boolean isVisibleByDefault) {
final SelectorWithWidgetPreference pref = final SelectorWithWidgetPreference pref =
new SelectorWithWidgetPreference(mPreferenceCategory.getContext(), isCheckbox); new SelectorWithWidgetPreference(mPreferenceCategory.getContext(), isCheckbox);
pref.setKey(key); pref.setKey(key);
pref.setTitle(titleId); pref.setTitle(titleId);
pref.setOnClickListener(mSelectorClickListener); pref.setOnClickListener(mSelectorClickListener);
pref.setVisible(isVisibleByDefault);
View.OnClickListener widgetClickListener = getWidgetClickListener(key); View.OnClickListener widgetClickListener = getWidgetClickListener(key);
if (widgetClickListener != null) { if (widgetClickListener != null) {
@@ -197,12 +244,12 @@ class ZenModePrioritySendersPreferenceController
} }
mPreferenceCategory.addPreference(pref); mPreferenceCategory.addPreference(pref);
mSelectorPreferences.add(pref); mOptions.put(key, pref);
return pref;
} }
private View.OnClickListener getWidgetClickListener(String key) { private View.OnClickListener getWidgetClickListener(String key) {
if (!KEY_CONTACTS.equals(key) && !KEY_STARRED.equals(key) && !KEY_IMPORTANT.equals(key)) { if (!KEY_CONTACTS.equals(key) && !KEY_STARRED.equals(key)
&& !KEY_ANY_CONVERSATIONS.equals(key) && !KEY_IMPORTANT_CONVERSATIONS.equals(key)) {
return null; return null;
} }
@@ -221,7 +268,8 @@ class ZenModePrioritySendersPreferenceController
} else if (KEY_CONTACTS.equals(key) } else if (KEY_CONTACTS.equals(key)
&& ALL_CONTACTS_INTENT.resolveActivity(mPackageManager) != null) { && ALL_CONTACTS_INTENT.resolveActivity(mPackageManager) != null) {
mContext.startActivity(ALL_CONTACTS_INTENT); mContext.startActivity(ALL_CONTACTS_INTENT);
} else if (KEY_IMPORTANT.equals(key)) { } else if (KEY_ANY_CONVERSATIONS.equals(key)
|| KEY_IMPORTANT_CONVERSATIONS.equals(key)) {
// TODO: b/332937635 - set correct metrics category // TODO: b/332937635 - set correct metrics category
new SubSettingLauncher(mContext) new SubSettingLauncher(mContext)
.setDestination(ConversationListSettings.class.getName()) .setDestination(ConversationListSettings.class.getName())
@@ -244,7 +292,7 @@ class ZenModePrioritySendersPreferenceController
} }
void updateSummaries() { void updateSummaries() {
for (SelectorWithWidgetPreference pref : mSelectorPreferences) { for (SelectorWithWidgetPreference pref : mOptions.values()) {
pref.setSummary(getSummary(pref.getKey())); pref.setSummary(getSummary(pref.getKey()));
} }
} }
@@ -255,7 +303,7 @@ class ZenModePrioritySendersPreferenceController
// Returns an integer array with 2 entries. The first entry is the setting for priority senders // Returns an integer array with 2 entries. The first entry is the setting for priority senders
// and the second entry is for priority conversation senders; if isMessages is false, then // and the second entry is for priority conversation senders; if isMessages is false, then
// no changes will ever be prescribed for conversation senders. // no changes will ever be prescribed for conversation senders.
int[] keyToSettingEndState(String key, boolean checked) { private int[] keyToSettingEndState(String key, boolean checked) {
int[] endState = new int[]{ PEOPLE_TYPE_UNSET, CONVERSATION_SENDERS_UNSET }; int[] endState = new int[]{ PEOPLE_TYPE_UNSET, CONVERSATION_SENDERS_UNSET };
if (!checked) { if (!checked) {
// Unchecking any priority-senders-based state should reset the state to NONE. // Unchecking any priority-senders-based state should reset the state to NONE.
@@ -268,11 +316,12 @@ class ZenModePrioritySendersPreferenceController
endState[0] = PEOPLE_TYPE_NONE; endState[0] = PEOPLE_TYPE_NONE;
} }
// For messages, unchecking "priority conversations" and "any" should reset conversation // For messages, unchecking "priority/any conversations" and "any" should reset
// state to "NONE" as well. // conversation state to "NONE" as well.
if (mIsMessages) { if (mIsMessages) {
switch (key) { switch (key) {
case KEY_IMPORTANT: case KEY_IMPORTANT_CONVERSATIONS:
case KEY_ANY_CONVERSATIONS:
case KEY_ANY: case KEY_ANY:
case KEY_NONE: case KEY_NONE:
endState[1] = CONVERSATION_SENDERS_NONE; endState[1] = CONVERSATION_SENDERS_NONE;
@@ -297,9 +346,10 @@ class ZenModePrioritySendersPreferenceController
// In the messages case *only*, also handle changing of conversation settings. // In the messages case *only*, also handle changing of conversation settings.
if (mIsMessages) { if (mIsMessages) {
switch (key) { switch (key) {
case KEY_IMPORTANT: case KEY_IMPORTANT_CONVERSATIONS:
endState[1] = CONVERSATION_SENDERS_IMPORTANT; endState[1] = CONVERSATION_SENDERS_IMPORTANT;
break; break;
case KEY_ANY_CONVERSATIONS:
case KEY_ANY: case KEY_ANY:
endState[1] = CONVERSATION_SENDERS_ANYONE; endState[1] = CONVERSATION_SENDERS_ANYONE;
break; break;
@@ -335,7 +385,7 @@ class ZenModePrioritySendersPreferenceController
// the contacts setting is additionally reset to "none". // the contacts setting is additionally reset to "none".
// - if "anyone" is previously selected, and the user clicks one of the contacts values, // - if "anyone" is previously selected, and the user clicks one of the contacts values,
// then the conversations setting is additionally reset to "none". // then the conversations setting is additionally reset to "none".
int[] settingsToSaveOnClick(String key, boolean checked, private int[] settingsToSaveOnClick(String key, boolean checked,
int currSendersSetting, int currConvosSetting) { int currSendersSetting, int currConvosSetting) {
int[] savedSettings = new int[]{ PEOPLE_TYPE_UNSET, CONVERSATION_SENDERS_UNSET }; int[] savedSettings = new int[]{ PEOPLE_TYPE_UNSET, CONVERSATION_SENDERS_UNSET };
@@ -360,15 +410,18 @@ class ZenModePrioritySendersPreferenceController
// Special-case handling for the "priority conversations" checkbox: // Special-case handling for the "priority conversations" checkbox:
// If a specific selection exists for priority senders (starred, contacts), we leave // If a specific selection exists for priority senders (starred, contacts), we leave
// it untouched. Otherwise (when the senders is set to "any"), set it to NONE. // it untouched. Otherwise (when the senders is set to "any"), set it to NONE.
if (key.equals(KEY_IMPORTANT) if ((key.equals(KEY_IMPORTANT_CONVERSATIONS) || key.equals(KEY_ANY_CONVERSATIONS))
&& currSendersSetting == PEOPLE_TYPE_ANYONE) { && currSendersSetting == PEOPLE_TYPE_ANYONE) {
savedSettings[0] = PEOPLE_TYPE_NONE; savedSettings[0] = PEOPLE_TYPE_NONE;
} }
// Flip-side special case for clicking either "contacts" option: if a specific selection // The flip-side case for the "contacts" option is slightly different -- we only
// exists for priority conversations, leave it untouched; otherwise, set to none. // reset conversations if leaving PEOPLE_ANY by selecting a contact option, but not
// if switching contact options. That's because starting from Anyone, checking Contacts,
// and then "important conversations" also shown checked because it was there (albeit
// subsumed into PEOPLE_ANY) would be weird.
if ((key.equals(KEY_STARRED) || key.equals(KEY_CONTACTS)) if ((key.equals(KEY_STARRED) || key.equals(KEY_CONTACTS))
&& currConvosSetting == CONVERSATION_SENDERS_ANYONE) { && currSendersSetting == PEOPLE_TYPE_ANYONE) {
savedSettings[1] = CONVERSATION_SENDERS_NONE; savedSettings[1] = CONVERSATION_SENDERS_NONE;
} }
} }
@@ -382,8 +435,10 @@ class ZenModePrioritySendersPreferenceController
return mZenModeSummaryHelper.getStarredContactsSummary(); return mZenModeSummaryHelper.getStarredContactsSummary();
case KEY_CONTACTS: case KEY_CONTACTS:
return mZenModeSummaryHelper.getContactsNumberSummary(); return mZenModeSummaryHelper.getContactsNumberSummary();
case KEY_IMPORTANT: case KEY_ANY_CONVERSATIONS:
return getConversationSummary(); return getConversationSummary(mNumAllConversations);
case KEY_IMPORTANT_CONVERSATIONS:
return getConversationSummary(mNumImportantConversations);
case KEY_ANY: case KEY_ANY:
return mContext.getResources().getString(mIsMessages return mContext.getResources().getString(mIsMessages
? R.string.zen_mode_all_messages_summary ? R.string.zen_mode_all_messages_summary
@@ -394,9 +449,7 @@ class ZenModePrioritySendersPreferenceController
} }
} }
private String getConversationSummary() { private String getConversationSummary(int numConversations) {
final int numConversations = mNumImportantConversations;
if (numConversations == CONVERSATION_SENDERS_UNSET) { if (numConversations == CONVERSATION_SENDERS_UNSET) {
return null; return null;
} else { } else {
@@ -409,8 +462,7 @@ class ZenModePrioritySendersPreferenceController
} }
} }
@VisibleForTesting private final SelectorWithWidgetPreference.OnClickListener mSelectorClickListener =
SelectorWithWidgetPreference.OnClickListener mSelectorClickListener =
new SelectorWithWidgetPreference.OnClickListener() { new SelectorWithWidgetPreference.OnClickListener() {
@Override @Override
public void onRadioButtonClicked(SelectorWithWidgetPreference preference) { public void onRadioButtonClicked(SelectorWithWidgetPreference preference) {

View File

@@ -140,6 +140,14 @@ class ZenModeSummaryHelper {
} }
String getMessagesSettingSummary(ZenPolicy policy) { String getMessagesSettingSummary(ZenPolicy policy) {
if (policy.getPriorityCategoryMessages() == STATE_ALLOW
&& policy.getPriorityMessageSenders() == PEOPLE_TYPE_ANYONE) {
// Messages=anyone means anyone. Even if conversation senders is specially configured,
// saying "Anyone and priority conversations" 1) makes no sense and 2) is incorrect
// because conversations WILL get through by virtue of also being messages.
return mContext.getString(R.string.zen_mode_from_anyone);
}
List<String> enabledCategories = getEnabledCategories(policy, List<String> enabledCategories = getEnabledCategories(policy,
category -> PRIORITY_CATEGORY_MESSAGES == category category -> PRIORITY_CATEGORY_MESSAGES == category
|| PRIORITY_CATEGORY_CONVERSATIONS == category, true); || PRIORITY_CATEGORY_CONVERSATIONS == category, true);
@@ -278,10 +286,11 @@ class ZenModeSummaryHelper {
continue; continue;
} }
// For conversations, only the "priority conversations" setting is relevant; any // For conversations, only the "all/priority conversations" settings are relevant;
// other setting is subsumed by the messages-specific messaging. // any other setting is subsumed by the messages-specific messaging.
if (category == PRIORITY_CATEGORY_CONVERSATIONS if (category == PRIORITY_CATEGORY_CONVERSATIONS
&& policy.isCategoryAllowed(PRIORITY_CATEGORY_CONVERSATIONS, false) && policy.isCategoryAllowed(PRIORITY_CATEGORY_CONVERSATIONS, false)
&& policy.getPriorityConversationSenders() != CONVERSATION_SENDERS_ANYONE
&& policy.getPriorityConversationSenders() && policy.getPriorityConversationSenders()
!= CONVERSATION_SENDERS_IMPORTANT) { != CONVERSATION_SENDERS_IMPORTANT) {
continue; continue;
@@ -320,13 +329,20 @@ class ZenModeSummaryHelper {
} else { } else {
return mContext.getString(R.string.zen_mode_from_starred); return mContext.getString(R.string.zen_mode_from_starred);
} }
} else if (category == PRIORITY_CATEGORY_CONVERSATIONS } else if (category == PRIORITY_CATEGORY_CONVERSATIONS) {
&& policy.getPriorityConversationSenders() == CONVERSATION_SENDERS_IMPORTANT) { if (policy.getPriorityConversationSenders() == CONVERSATION_SENDERS_IMPORTANT) {
if (isFirst) { if (isFirst) {
return mContext.getString(R.string.zen_mode_from_important_conversations); return mContext.getString(R.string.zen_mode_from_important_conversations);
} else { } else {
return mContext.getString( return mContext.getString(
R.string.zen_mode_from_important_conversations_second); R.string.zen_mode_from_important_conversations_second);
}
} else if (policy.getPriorityConversationSenders() == CONVERSATION_SENDERS_ANYONE) {
if (isFirst) {
return mContext.getString(R.string.zen_mode_from_all_conversations);
} else {
return mContext.getString(R.string.zen_mode_from_all_conversations_second);
}
} }
} else if (category == PRIORITY_CATEGORY_EVENTS) { } else if (category == PRIORITY_CATEGORY_EVENTS) {
if (isFirst) { if (isFirst) {

View File

@@ -38,6 +38,8 @@ import android.os.BatteryUsageStats;
import android.os.LocaleList; import android.os.LocaleList;
import android.os.UserHandle; import android.os.UserHandle;
import androidx.core.util.Pair;
import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity; import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity;
import com.android.settings.fuelgauge.batteryusage.db.BatteryEventEntity; import com.android.settings.fuelgauge.batteryusage.db.BatteryEventEntity;
import com.android.settings.fuelgauge.batteryusage.db.BatteryUsageSlotEntity; import com.android.settings.fuelgauge.batteryusage.db.BatteryUsageSlotEntity;
@@ -384,8 +386,9 @@ public final class ConvertUtilsTest {
/* cachedUsageConsumePower= */ 1.5); /* cachedUsageConsumePower= */ 1.5);
BatteryOptimizationModeCache optimizationModeCache = BatteryOptimizationModeCache optimizationModeCache =
new BatteryOptimizationModeCache(mContext); new BatteryOptimizationModeCache(mContext);
optimizationModeCache.mBatteryOptimizeModeCacheMap.put( optimizationModeCache.mBatteryOptimizeModeCache.put(
(int) batteryDiffEntry.mUid, BatteryOptimizationMode.MODE_OPTIMIZED); (int) batteryDiffEntry.mUid,
Pair.create(BatteryOptimizationMode.MODE_OPTIMIZED, false));
final BatteryUsageDiff batteryUsageDiff = final BatteryUsageDiff batteryUsageDiff =
ConvertUtils.convertToBatteryUsageDiff(batteryDiffEntry, optimizationModeCache); ConvertUtils.convertToBatteryUsageDiff(batteryDiffEntry, optimizationModeCache);
@@ -408,6 +411,7 @@ public final class ConvertUtilsTest {
assertThat(batteryUsageDiff.getKey()).isEqualTo("key"); assertThat(batteryUsageDiff.getKey()).isEqualTo("key");
assertThat(batteryUsageDiff.getAppOptimizationMode()) assertThat(batteryUsageDiff.getAppOptimizationMode())
.isEqualTo(BatteryOptimizationMode.MODE_OPTIMIZED); .isEqualTo(BatteryOptimizationMode.MODE_OPTIMIZED);
assertThat(batteryUsageDiff.getIsAppOptimizationModeMutable()).isFalse();
assertThat(batteryUsageDiff.hasPackageName()).isFalse(); assertThat(batteryUsageDiff.hasPackageName()).isFalse();
assertThat(batteryUsageDiff.hasLabel()).isFalse(); assertThat(batteryUsageDiff.hasLabel()).isFalse();
} }

View File

@@ -21,8 +21,11 @@ import static android.provider.Settings.Global.ZEN_MODE_OFF;
import static android.service.notification.Condition.SOURCE_UNKNOWN; import static android.service.notification.Condition.SOURCE_UNKNOWN;
import static android.service.notification.Condition.STATE_TRUE; import static android.service.notification.Condition.STATE_TRUE;
import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_ANYONE; import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_ANYONE;
import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_IMPORTANT;
import static android.service.notification.ZenPolicy.PEOPLE_TYPE_ANYONE; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_ANYONE;
import static android.service.notification.ZenPolicy.PEOPLE_TYPE_CONTACTS; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_CONTACTS;
import static android.service.notification.ZenPolicy.PEOPLE_TYPE_NONE;
import static android.service.notification.ZenPolicy.PEOPLE_TYPE_STARRED;
import static android.service.notification.ZenPolicy.VISUAL_EFFECT_AMBIENT; import static android.service.notification.ZenPolicy.VISUAL_EFFECT_AMBIENT;
import static android.service.notification.ZenPolicy.VISUAL_EFFECT_LIGHTS; import static android.service.notification.ZenPolicy.VISUAL_EFFECT_LIGHTS;
@@ -123,6 +126,59 @@ public class ZenModesSummaryHelperTest {
assertThat(mSummaryHelper.getPeopleSummary(policy)).isEqualTo("All people can interrupt"); assertThat(mSummaryHelper.getPeopleSummary(policy)).isEqualTo("All people can interrupt");
} }
@Test
public void getMessagesSettingSummary_allMessages() {
ZenPolicy policy1 = new ZenPolicy.Builder()
.allowMessages(PEOPLE_TYPE_ANYONE)
.build();
ZenPolicy policy2 = new ZenPolicy.Builder()
.allowMessages(PEOPLE_TYPE_ANYONE)
.allowConversations(CONVERSATION_SENDERS_IMPORTANT)
.build();
ZenPolicy policy3 = new ZenPolicy.Builder()
.allowMessages(PEOPLE_TYPE_ANYONE)
.allowConversations(CONVERSATION_SENDERS_ANYONE)
.build();
assertThat(mSummaryHelper.getMessagesSettingSummary(policy1)).isEqualTo("Anyone");
assertThat(mSummaryHelper.getMessagesSettingSummary(policy2)).isEqualTo("Anyone");
assertThat(mSummaryHelper.getMessagesSettingSummary(policy3)).isEqualTo("Anyone");
}
@Test
public void getMessagesSettingSummary_noMessagesButSomeConversations() {
ZenPolicy policy1 = new ZenPolicy.Builder()
.allowMessages(PEOPLE_TYPE_NONE)
.allowConversations(CONVERSATION_SENDERS_IMPORTANT)
.build();
ZenPolicy policy2 = new ZenPolicy.Builder()
.allowMessages(PEOPLE_TYPE_NONE)
.allowConversations(CONVERSATION_SENDERS_ANYONE)
.build();
assertThat(mSummaryHelper.getMessagesSettingSummary(policy1)).isEqualTo(
"Priority conversations");
assertThat(mSummaryHelper.getMessagesSettingSummary(policy2)).isEqualTo(
"All conversations");
}
@Test
public void getMessagesSettingSummary_contactsAndConversations() {
ZenPolicy policy1 = new ZenPolicy.Builder()
.allowMessages(PEOPLE_TYPE_STARRED)
.allowConversations(CONVERSATION_SENDERS_IMPORTANT)
.build();
ZenPolicy policy2 = new ZenPolicy.Builder()
.allowMessages(PEOPLE_TYPE_STARRED)
.allowConversations(CONVERSATION_SENDERS_ANYONE)
.build();
assertThat(mSummaryHelper.getMessagesSettingSummary(policy1)).isEqualTo(
"Starred contacts and priority conversations");
assertThat(mSummaryHelper.getMessagesSettingSummary(policy2)).isEqualTo(
"Starred contacts and all conversations");
}
@Test @Test
public void getOtherSoundCategoriesSummary_single() { public void getOtherSoundCategoriesSummary_single() {
ZenMode zenMode = new TestModeBuilder() ZenMode zenMode = new TestModeBuilder()