Files
packages_apps_Settings/src/com/android/settings/notification/modes/ZenModeFragment.java
Yuri Lin 65548c0e56 Add interstitial for modes that are disabled but not by user
This covers both the case of navigating to the mode page through the mode aggregator menu as well as if an app sends an intent to go to the mode.

The interstitial visuals are not done yet; in particular, the image is just a gray box for now.

Manual tests done:
- visually verifying the interstitial page in both portrait and landscape
- accessing the mode page from modes list, confirming interstitial pops up
- accessing enabled and disabled-by-user mode page from modes list (no interstitial)
- getting to the mode page from intent through an app
- accessing enabled and disabled-by-user mode pages from app intent (no interstitial)
- adjusted display and font size (it looks bad with max display & font size, maybe not much to be done)

Bug: 332730534
Test: manual, ZenModeFragmentTest, SetupInterstitialActivityTest
Flag: android.app.modes_ui
Change-Id: I21f13b0842d5b118a341f7d85e8fcac947ca3a06
2024-08-01 18:44:22 -04:00

190 lines
7.8 KiB
Java

/*
* Copyright (C) 2024 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.modes;
import static com.android.settingslib.notification.modes.ZenMode.Status.DISABLED_BY_OTHER;
import android.app.AlertDialog;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import androidx.activity.ComponentActivity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.MenuProvider;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.notification.modes.ZenMode;
import java.util.ArrayList;
import java.util.List;
public class ZenModeFragment extends ZenModeFragmentBase {
// for mode context menu
private static final int RENAME_MODE = 1;
private static final int DELETE_MODE = 2;
private ModeMenuProvider mModeMenuProvider;
private boolean mSettingsObserverRegistered = false; // for ManualDurationPreferenceController
@Override
protected int getPreferenceScreenResId() {
return R.xml.modes_rule_settings;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
List<AbstractPreferenceController> prefControllers = new ArrayList<>();
prefControllers.add(new ZenModeHeaderController(context, "header", this));
prefControllers.add(new ZenModeBlurbPreferenceController(context, "mode_blurb"));
prefControllers.add(
new ZenModeButtonPreferenceController(context, "activate", this, mBackend));
prefControllers.add(new ZenModePreferenceCategoryController(context, "modes_filters"));
prefControllers.add(new ZenModePeopleLinkPreferenceController(
context, "zen_mode_people", mHelperBackend));
prefControllers.add(new ZenModeAppsLinkPreferenceController(
context, "zen_mode_apps", this, mBackend, mHelperBackend));
prefControllers.add(new ZenModeOtherLinkPreferenceController(
context, "zen_other_settings", mHelperBackend));
prefControllers.add(
new ZenModePreferenceCategoryController(context, "modes_additional_actions"));
prefControllers.add(new ZenModeDisplayLinkPreferenceController(
context, "mode_display_settings", mBackend, mHelperBackend));
prefControllers.add(new ZenModeTriggerCategoryPreferenceController(context,
"zen_automatic_trigger_category"));
prefControllers.add(new ZenModeTriggerUpdatePreferenceController(context,
"zen_automatic_trigger_settings", mBackend));
prefControllers.add(
new ZenModeTriggerAddPreferenceController(context, "zen_add_automatic_trigger",
this, mBackend));
prefControllers.add(new InterruptionFilterPreferenceController(
context, "allow_filtering", mBackend));
prefControllers.add(new ManualDurationPreferenceController(
context, "mode_manual_duration", this, mBackend));
return prefControllers;
}
@Override
public void onStart() {
super.onStart();
ZenMode mode = getMode();
// Consider redirecting to the interstitial if the mode is disabled (but not by the user).
if (maybeRedirectToInterstitial(mode)) {
return;
}
// Set title for the entire screen
ComponentActivity activity = getActivity();
if (mode != null && activity != null) {
activity.setTitle(mode.getName());
mModeMenuProvider = new ModeMenuProvider(mode);
activity.addMenuProvider(mModeMenuProvider);
}
// allow duration preference controller to listen for settings changes
use(ManualDurationPreferenceController.class).registerSettingsObserver();
mSettingsObserverRegistered = true;
}
private boolean maybeRedirectToInterstitial(@Nullable ZenMode mode) {
if (mode == null || mode.getStatus() != DISABLED_BY_OTHER) {
return false;
}
// don't come back here from the interstitial
finish();
mContext.startActivity(SetupInterstitialActivity.getIntent(mContext, mode));
return true;
}
@Override
public void onStop() {
if (getActivity() != null && mModeMenuProvider != null) {
getActivity().removeMenuProvider(mModeMenuProvider);
}
if (mSettingsObserverRegistered) {
use(ManualDurationPreferenceController.class).unregisterSettingsObserver();
}
super.onStop();
}
@Override
public int getMetricsCategory() {
// TODO: b/332937635 - make this the correct metrics category
return SettingsEnums.NOTIFICATION_ZEN_MODE_AUTOMATION;
}
@Override
protected void onUpdatedZenModeState() {
// Because this fragment may be asked to finish by the delete menu but not be done doing
// so yet, ignore any attempts to update info in that case.
if (getActivity() != null && getActivity().isFinishing()) {
return;
}
super.onUpdatedZenModeState();
}
private class ModeMenuProvider implements MenuProvider {
@NonNull private final ZenMode mZenMode;
ModeMenuProvider(@NonNull ZenMode mode) {
mZenMode = mode;
}
@Override
public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
if (mZenMode.canEditNameAndIcon()) {
menu.add(Menu.NONE, RENAME_MODE, Menu.NONE, R.string.zen_mode_menu_rename_mode);
}
if (mZenMode.canBeDeleted()) {
// Only deleteable modes should get a delete menu option.
menu.add(Menu.NONE, DELETE_MODE, Menu.NONE, R.string.zen_mode_menu_delete_mode);
}
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
if (menuItem.getItemId() == RENAME_MODE) {
// TODO: b/332937635 - Update metrics category
ZenSubSettingLauncher.forModeFragment(mContext, ZenModeEditNameIconFragment.class,
mZenMode.getId(), 0).launch();
} else if (menuItem.getItemId() == DELETE_MODE) {
new AlertDialog.Builder(mContext)
.setTitle(mContext.getString(R.string.zen_mode_delete_mode_confirmation,
mZenMode.getRule().getName()))
.setPositiveButton(R.string.zen_mode_schedule_delete,
(dialog, which) -> {
// start finishing before calling removeMode() so that we
// don't try to update this activity with a nonexistent mode
// when the zen mode config is updated
finish();
mBackend.removeMode(mZenMode);
})
.setNegativeButton(R.string.cancel, null)
.show();
return true;
}
return false;
}
}
}