Changes to the trigger segment
* Switch is always visible, even without a configuration activity * Custom icon, title, and summary for some mode types (such as SCHEDULE_TIME, etc). * Default texts in case of missing trigger description. * Different icons for having/missing configuration activity. * Move the section to the top of the screen. Bug: 349376785 Test: atest ZenModeTriggerLinkPreferenceControllerTest Flag: android.app.modes_ui Change-Id: I960318899cf4da20ffc5765818429d5790d05067
This commit is contained in:
@@ -16,14 +16,26 @@
|
||||
|
||||
package com.android.settings.notification.modes;
|
||||
|
||||
import static android.app.AutomaticZenRule.TYPE_BEDTIME;
|
||||
import static android.app.AutomaticZenRule.TYPE_DRIVING;
|
||||
import static android.app.AutomaticZenRule.TYPE_SCHEDULE_CALENDAR;
|
||||
import static android.app.AutomaticZenRule.TYPE_SCHEDULE_TIME;
|
||||
import static android.service.notification.ZenModeConfig.tryParseScheduleConditionId;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.service.notification.SystemZenRules;
|
||||
import android.service.notification.ZenModeConfig;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
@@ -35,6 +47,8 @@ import com.android.settingslib.PrimarySwitchPreference;
|
||||
import com.android.settingslib.notification.modes.ZenMode;
|
||||
import com.android.settingslib.notification.modes.ZenModesBackend;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
/**
|
||||
* Preference controller for the link to an individual mode's configuration page.
|
||||
*/
|
||||
@@ -42,26 +56,29 @@ class ZenModeSetTriggerLinkPreferenceController extends AbstractZenModePreferenc
|
||||
private static final String TAG = "ZenModeSetTriggerLink";
|
||||
|
||||
@VisibleForTesting
|
||||
protected static final String AUTOMATIC_TRIGGER_PREF_KEY = "zen_automatic_trigger_settings";
|
||||
static final String AUTOMATIC_TRIGGER_KEY = "zen_automatic_trigger_settings";
|
||||
static final String ADD_TRIGGER_KEY = "zen_add_automatic_trigger";
|
||||
|
||||
private final DashboardFragment mFragment;
|
||||
private final PackageManager mPackageManager;
|
||||
private final ConfigurationActivityHelper mConfigurationActivityHelper;
|
||||
private final ZenServiceListing mServiceListing;
|
||||
private final DashboardFragment mFragment;
|
||||
|
||||
ZenModeSetTriggerLinkPreferenceController(Context context, String key,
|
||||
DashboardFragment fragment, ZenModesBackend backend) {
|
||||
this(context, key, fragment, backend,
|
||||
this(context, key, fragment, backend, context.getPackageManager(),
|
||||
new ConfigurationActivityHelper(context.getPackageManager()),
|
||||
new ZenServiceListing(context));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
ZenModeSetTriggerLinkPreferenceController(Context context, String key,
|
||||
DashboardFragment fragment, ZenModesBackend backend,
|
||||
DashboardFragment fragment, ZenModesBackend backend, PackageManager packageManager,
|
||||
ConfigurationActivityHelper configurationActivityHelper,
|
||||
ZenServiceListing serviceListing) {
|
||||
super(context, key, backend);
|
||||
mFragment = fragment;
|
||||
mPackageManager = packageManager;
|
||||
mConfigurationActivityHelper = configurationActivityHelper;
|
||||
mServiceListing = serviceListing;
|
||||
}
|
||||
@@ -83,64 +100,137 @@ class ZenModeSetTriggerLinkPreferenceController extends AbstractZenModePreferenc
|
||||
// This controller is expected to govern a preference category so that it controls the
|
||||
// availability of the entire preference category if the mode doesn't have a way to
|
||||
// automatically trigger (such as manual DND).
|
||||
PrimarySwitchPreference switchPref = ((PreferenceCategory) preference).findPreference(
|
||||
AUTOMATIC_TRIGGER_PREF_KEY);
|
||||
if (switchPref == null) {
|
||||
if (zenMode.isManualDnd()) {
|
||||
return;
|
||||
}
|
||||
switchPref.setChecked(zenMode.getRule().isEnabled());
|
||||
switchPref.setOnPreferenceChangeListener(mSwitchChangeListener);
|
||||
switchPref.setSummary(zenMode.getRule().getTriggerDescription());
|
||||
switchPref.setIcon(null);
|
||||
switchPref.setOnPreferenceClickListener(null);
|
||||
switchPref.setIntent(null);
|
||||
PrimarySwitchPreference triggerPref = checkNotNull(
|
||||
((PreferenceCategory) preference).findPreference(AUTOMATIC_TRIGGER_KEY));
|
||||
Preference addTriggerPref = checkNotNull(
|
||||
((PreferenceCategory) preference).findPreference(ADD_TRIGGER_KEY));
|
||||
|
||||
if (zenMode.isSystemOwned()) {
|
||||
if (zenMode.getType() == TYPE_SCHEDULE_TIME) {
|
||||
switchPref.setTitle(R.string.zen_mode_set_schedule_link);
|
||||
// TODO: b/332937635 - set correct metrics category
|
||||
switchPref.setIntent(ZenSubSettingLauncher.forModeFragment(mContext,
|
||||
ZenModeSetScheduleFragment.class, zenMode.getId(), 0).toIntent());
|
||||
} else if (zenMode.getType() == TYPE_SCHEDULE_CALENDAR) {
|
||||
switchPref.setTitle(R.string.zen_mode_set_calendar_link);
|
||||
switchPref.setIcon(null);
|
||||
// TODO: b/332937635 - set correct metrics category
|
||||
switchPref.setIntent(ZenSubSettingLauncher.forModeFragment(mContext,
|
||||
ZenModeSetCalendarFragment.class, zenMode.getId(), 0).toIntent());
|
||||
} else {
|
||||
switchPref.setTitle(R.string.zen_mode_select_schedule);
|
||||
switchPref.setIcon(R.drawable.ic_add_24dp);
|
||||
switchPref.setSummary("");
|
||||
// TODO: b/342156843 - Hide the switch (needs support in SettingsLib).
|
||||
switchPref.setOnPreferenceClickListener(clickedPreference -> {
|
||||
ZenModeScheduleChooserDialog.show(mFragment, mOnScheduleOptionListener);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
boolean isAddTrigger = zenMode.isSystemOwned() && zenMode.getType() != TYPE_SCHEDULE_TIME
|
||||
&& zenMode.getType() != TYPE_SCHEDULE_CALENDAR;
|
||||
|
||||
if (isAddTrigger) {
|
||||
triggerPref.setVisible(false);
|
||||
addTriggerPref.setVisible(true);
|
||||
addTriggerPref.setOnPreferenceClickListener(unused -> {
|
||||
ZenModeScheduleChooserDialog.show(mFragment, mOnScheduleOptionListener);
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
Intent intent = mConfigurationActivityHelper.getConfigurationActivityIntentForMode(
|
||||
zenMode, mServiceListing::findService);
|
||||
if (intent != null) {
|
||||
preference.setVisible(true);
|
||||
switchPref.setTitle(R.string.zen_mode_configuration_link_title);
|
||||
switchPref.setSummary(zenMode.getRule().getTriggerDescription());
|
||||
switchPref.setIntent(intent);
|
||||
addTriggerPref.setVisible(false);
|
||||
triggerPref.setVisible(true);
|
||||
triggerPref.setChecked(zenMode.getRule().isEnabled());
|
||||
triggerPref.setOnPreferenceChangeListener(mSwitchChangeListener);
|
||||
|
||||
if (zenMode.isSystemOwned()) {
|
||||
setUpForSystemOwnedTrigger(triggerPref, zenMode);
|
||||
} else {
|
||||
Log.i(TAG, "No intent found for " + zenMode.getRule().getName());
|
||||
preference.setVisible(false);
|
||||
setUpForAppTrigger(triggerPref, zenMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpForSystemOwnedTrigger(Preference preference, ZenMode mode) {
|
||||
if (mode.getType() == TYPE_SCHEDULE_TIME) {
|
||||
// TODO: b/332937635 - set correct metrics category
|
||||
preference.setIntent(ZenSubSettingLauncher.forModeFragment(mContext,
|
||||
ZenModeSetScheduleFragment.class, mode.getId(), 0).toIntent());
|
||||
|
||||
// [Clock Icon] 9:00 - 17:00 / Sun-Mon
|
||||
preference.setIcon(com.android.internal.R.drawable.ic_zen_mode_type_schedule_time);
|
||||
ZenModeConfig.ScheduleInfo schedule =
|
||||
tryParseScheduleConditionId(mode.getRule().getConditionId());
|
||||
if (schedule != null) {
|
||||
preference.setTitle(SystemZenRules.getTimeSummary(mContext, schedule));
|
||||
preference.setSummary(SystemZenRules.getShortDaysSummary(mContext, schedule));
|
||||
} else {
|
||||
// Fallback, but shouldn't happen.
|
||||
Log.wtf(TAG, "SCHEDULE_TIME mode without schedule: " + mode);
|
||||
preference.setTitle(R.string.zen_mode_set_schedule_link);
|
||||
preference.setSummary(null);
|
||||
}
|
||||
} else if (mode.getType() == TYPE_SCHEDULE_CALENDAR) {
|
||||
// TODO: b/332937635 - set correct metrics category
|
||||
preference.setIntent(ZenSubSettingLauncher.forModeFragment(mContext,
|
||||
ZenModeSetCalendarFragment.class, mode.getId(), 0).toIntent());
|
||||
|
||||
// [Event Icon] Calendar Events / <Calendar name>
|
||||
preference.setIcon(
|
||||
com.android.internal.R.drawable.ic_zen_mode_type_schedule_calendar);
|
||||
preference.setTitle(R.string.zen_mode_trigger_title_schedule_calendar);
|
||||
preference.setSummary(mode.getTriggerDescription());
|
||||
} else {
|
||||
Log.wtf(TAG, "Unexpected type for system-owned mode: " + mode);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SwitchIntDef")
|
||||
private void setUpForAppTrigger(Preference preference, ZenMode mode) {
|
||||
// App-owned mode may have triggerDescription, configurationActivity, or both/neither.
|
||||
Intent configurationIntent =
|
||||
mConfigurationActivityHelper.getConfigurationActivityIntentForMode(
|
||||
mode, mServiceListing::findService);
|
||||
|
||||
@StringRes int title = switch (mode.getType()) {
|
||||
case TYPE_BEDTIME -> R.string.zen_mode_trigger_title_bedtime;
|
||||
case TYPE_DRIVING -> R.string.zen_mode_trigger_title_driving;
|
||||
default -> R.string.zen_mode_trigger_title_generic;
|
||||
};
|
||||
|
||||
String summary;
|
||||
if (!Strings.isNullOrEmpty(mode.getTriggerDescription())) {
|
||||
summary = mode.getTriggerDescription();
|
||||
} else if (!Strings.isNullOrEmpty(mode.getRule().getPackageName())) {
|
||||
String appName = null;
|
||||
try {
|
||||
ApplicationInfo appInfo = mPackageManager.getApplicationInfo(
|
||||
mode.getRule().getPackageName(), 0);
|
||||
appName = appInfo.loadLabel(mPackageManager).toString();
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(TAG, "Couldn't resolve owner for mode: " + mode);
|
||||
}
|
||||
|
||||
if (appName != null) {
|
||||
summary = mContext.getString(
|
||||
configurationIntent != null
|
||||
? R.string.zen_mode_trigger_summary_settings_in_app
|
||||
: R.string.zen_mode_trigger_summary_managed_by_app,
|
||||
appName);
|
||||
} else {
|
||||
summary = null;
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "Mode without package! " + mode);
|
||||
summary = null;
|
||||
}
|
||||
|
||||
@DrawableRes int icon;
|
||||
if (mode.getType() == TYPE_BEDTIME) {
|
||||
icon = com.android.internal.R.drawable.ic_zen_mode_type_schedule_time; // Clock
|
||||
} else if (mode.getType() == TYPE_DRIVING) {
|
||||
icon = com.android.internal.R.drawable.ic_zen_mode_type_driving; // Car
|
||||
} else {
|
||||
icon = configurationIntent != null ? R.drawable.ic_zen_mode_trigger_with_activity
|
||||
: R.drawable.ic_zen_mode_trigger_without_activity;
|
||||
}
|
||||
|
||||
preference.setTitle(title);
|
||||
preference.setSummary(summary);
|
||||
preference.setIcon(icon);
|
||||
preference.setIntent(configurationIntent);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
final ZenModeScheduleChooserDialog.OnScheduleOptionListener mOnScheduleOptionListener =
|
||||
conditionId -> saveMode(mode -> {
|
||||
mode.setCustomModeConditionId(mContext, conditionId);
|
||||
return mode;
|
||||
// TODO: b/342156843 - Maybe jump to the corresponding schedule editing screen?
|
||||
});
|
||||
|
||||
@VisibleForTesting
|
||||
protected Preference.OnPreferenceChangeListener mSwitchChangeListener = (p, newValue) -> {
|
||||
private final Preference.OnPreferenceChangeListener mSwitchChangeListener = (p, newValue) -> {
|
||||
final boolean newEnabled = (Boolean) newValue;
|
||||
return saveMode((zenMode) -> {
|
||||
if (newEnabled != zenMode.getRule().isEnabled()) {
|
||||
@@ -148,6 +238,5 @@ class ZenModeSetTriggerLinkPreferenceController extends AbstractZenModePreferenc
|
||||
}
|
||||
return zenMode;
|
||||
});
|
||||
// TODO: b/342156843 - Do we want to jump to the corresponding schedule editing screen?
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user