1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.notification.modes; 18 19 import static com.android.settingslib.notification.modes.ZenMode.Status.DISABLED_BY_OTHER; 20 21 import android.app.AlertDialog; 22 import android.app.settings.SettingsEnums; 23 import android.content.Context; 24 import android.view.Menu; 25 import android.view.MenuInflater; 26 import android.view.MenuItem; 27 28 import androidx.activity.ComponentActivity; 29 import androidx.annotation.NonNull; 30 import androidx.annotation.Nullable; 31 import androidx.core.view.MenuProvider; 32 33 import com.android.settings.R; 34 import com.android.settingslib.core.AbstractPreferenceController; 35 import com.android.settingslib.notification.modes.ZenIconLoader; 36 import com.android.settingslib.notification.modes.ZenMode; 37 38 import java.util.ArrayList; 39 import java.util.List; 40 41 public class ZenModeFragment extends ZenModeFragmentBase { 42 43 // for mode context menu 44 private static final int RENAME_MODE = 1; 45 private static final int DELETE_MODE = 2; 46 47 private ModeMenuProvider mModeMenuProvider; 48 private boolean mSettingsObserverRegistered = false; // for ManualDurationPreferenceController 49 50 @Override getPreferenceScreenResId()51 protected int getPreferenceScreenResId() { 52 return R.xml.modes_rule_settings; 53 } 54 55 @Override createPreferenceControllers(Context context)56 protected List<AbstractPreferenceController> createPreferenceControllers(Context context) { 57 List<AbstractPreferenceController> prefControllers = new ArrayList<>(); 58 prefControllers.add( 59 new ZenModeHeaderController(context, ZenIconLoader.getInstance(), "header", this)); 60 prefControllers.add(new ZenModeBlurbPreferenceController(context, "mode_blurb")); 61 prefControllers.add( 62 new ZenModeButtonPreferenceController(context, "activate", this, mBackend)); 63 prefControllers.add(new ZenModePreferenceCategoryController(context, "modes_filters")); 64 prefControllers.add(new ZenModePeopleLinkPreferenceController( 65 context, "zen_mode_people", mHelperBackend)); 66 prefControllers.add(new ZenModeAppsLinkPreferenceController( 67 context, "zen_mode_apps", this, mBackend, mHelperBackend)); 68 prefControllers.add(new ZenModeOtherLinkPreferenceController( 69 context, "zen_other_settings", mHelperBackend)); 70 prefControllers.add( 71 new ZenModePreferenceCategoryController(context, "modes_additional_actions")); 72 prefControllers.add(new ZenModeDisplayLinkPreferenceController( 73 context, "mode_display_settings", mBackend, mHelperBackend)); 74 prefControllers.add(new ZenModeTriggerCategoryPreferenceController(context, 75 "zen_automatic_trigger_category")); 76 prefControllers.add(new ZenModeTriggerUpdatePreferenceController(context, 77 "zen_automatic_trigger_settings", mBackend)); 78 prefControllers.add( 79 new ZenModeTriggerAddPreferenceController(context, "zen_add_automatic_trigger", 80 this, mBackend)); 81 prefControllers.add(new InterruptionFilterPreferenceController( 82 context, "allow_all", mBackend)); 83 prefControllers.add(new ManualDurationPreferenceController( 84 context, "mode_manual_duration", this, mBackend)); 85 return prefControllers; 86 } 87 88 @Override onStart()89 public void onStart() { 90 super.onStart(); 91 ZenMode mode = getMode(); 92 93 // Consider redirecting to the interstitial if the mode is disabled (but not by the user). 94 if (maybeRedirectToInterstitial(mode)) { 95 return; 96 } 97 98 // allow duration preference controller to listen for settings changes 99 use(ManualDurationPreferenceController.class).registerSettingsObserver(); 100 mSettingsObserverRegistered = true; 101 } 102 maybeRedirectToInterstitial(@ullable ZenMode mode)103 private boolean maybeRedirectToInterstitial(@Nullable ZenMode mode) { 104 if (mode == null || mode.getStatus() != DISABLED_BY_OTHER) { 105 return false; 106 } 107 108 mContext.startActivity(SetupInterstitialActivity.getIntent(mContext, mode)); 109 // don't come back here from the interstitial 110 finish(); 111 return true; 112 } 113 114 @Override onResume()115 public void onResume() { 116 super.onResume(); 117 ZenMode mode = getMode(); 118 ComponentActivity activity = getActivity(); 119 if (mode != null && activity != null) { 120 activity.setTitle(mode.getName()); 121 mModeMenuProvider = new ModeMenuProvider(mode); 122 activity.addMenuProvider(mModeMenuProvider); 123 } 124 } 125 126 @Override onPause()127 public void onPause() { 128 if (getActivity() != null && mModeMenuProvider != null) { 129 getActivity().removeMenuProvider(mModeMenuProvider); 130 } 131 super.onPause(); 132 } 133 134 @Override onStop()135 public void onStop() { 136 if (mSettingsObserverRegistered) { 137 use(ManualDurationPreferenceController.class).unregisterSettingsObserver(); 138 } 139 super.onStop(); 140 } 141 142 @Override getMetricsCategory()143 public int getMetricsCategory() { 144 return SettingsEnums.ZEN_PRIORITY_MODE; 145 } 146 147 @Override onUpdatedZenModeState()148 protected void onUpdatedZenModeState() { 149 // Because this fragment may be asked to finish by the delete menu but not be done doing 150 // so yet, ignore any attempts to update info in that case. 151 if (getActivity() != null && getActivity().isFinishing()) { 152 return; 153 } 154 super.onUpdatedZenModeState(); 155 } 156 157 private class ModeMenuProvider implements MenuProvider { 158 @NonNull private final ZenMode mZenMode; 159 ModeMenuProvider(@onNull ZenMode mode)160 ModeMenuProvider(@NonNull ZenMode mode) { 161 mZenMode = mode; 162 } 163 164 @Override onCreateMenu(@onNull Menu menu, @NonNull MenuInflater menuInflater)165 public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) { 166 if (mZenMode.canEditNameAndIcon()) { 167 menu.add(Menu.NONE, RENAME_MODE, Menu.NONE, R.string.zen_mode_menu_rename_mode); 168 } 169 if (mZenMode.canBeDeleted()) { 170 // Only deleteable modes should get a delete menu option. 171 menu.add(Menu.NONE, DELETE_MODE, Menu.NONE, R.string.zen_mode_menu_delete_mode); 172 } 173 } 174 175 @Override onMenuItemSelected(@onNull MenuItem menuItem)176 public boolean onMenuItemSelected(@NonNull MenuItem menuItem) { 177 if (menuItem.getItemId() == RENAME_MODE) { 178 ZenSubSettingLauncher.forModeFragment(mContext, ZenModeEditNameIconFragment.class, 179 mZenMode.getId(), getMetricsCategory()).launch(); 180 } else if (menuItem.getItemId() == DELETE_MODE) { 181 new AlertDialog.Builder(mContext) 182 .setTitle(mContext.getString(R.string.zen_mode_delete_mode_confirmation, 183 mZenMode.getName())) 184 .setPositiveButton(R.string.zen_mode_schedule_delete, 185 (dialog, which) -> { 186 // start finishing before calling removeMode() so that we 187 // don't try to update this activity with a nonexistent mode 188 // when the zen mode config is updated 189 finish(); 190 mBackend.removeMode(mZenMode); 191 }) 192 .setNegativeButton(R.string.cancel, null) 193 .show(); 194 return true; 195 } 196 return false; 197 } 198 } 199 } 200