Loading src/com/android/settings/notification/modes/AbstractZenModePreferenceController.java +22 −21 Original line number Diff line number Diff line Loading @@ -25,8 +25,8 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.notification.modes.ZenMode; Loading Loading @@ -92,29 +92,14 @@ abstract class AbstractZenModePreferenceController extends AbstractPreferenceCon return true; } // Called by parent Fragment onAttach, for any methods (such as isAvailable()) that need // zen mode info before onStart. Most callers should use updateZenMode instead, which will // do any further necessary propagation. protected final void setZenMode(@NonNull ZenMode zenMode) { mZenMode = zenMode; } // Called by the parent Fragment onStart, which means it will happen before resume. public void updateZenMode(@NonNull Preference preference, @NonNull ZenMode zenMode) { /** * Assigns the {@link ZenMode} of this controller, so that it can be used later from * {@link #isAvailable()} and {@link #updateState(Preference)}. */ final void setZenMode(@NonNull ZenMode zenMode) { mZenMode = zenMode; updateState(preference); } @Override public void displayPreference(PreferenceScreen screen) { super.displayPreference(screen); if (mZenMode != null) { displayPreference(screen, mZenMode); } } public void displayPreference(PreferenceScreen screen, @NonNull ZenMode zenMode) {} @Override public final void updateState(Preference preference) { super.updateState(preference); Loading Loading @@ -167,4 +152,20 @@ abstract class AbstractZenModePreferenceController extends AbstractPreferenceCon return mode; }); } @VisibleForTesting(otherwise = VisibleForTesting.NONE) @Nullable ZenMode getZenMode() { return mZenMode; } /** * Convenience method for tests. Assigns the {@link ZenMode} of this controller, and calls * {@link #updateState(Preference)} immediately. */ @VisibleForTesting(otherwise = VisibleForTesting.NONE) final void updateZenMode(@NonNull Preference preference, @NonNull ZenMode zenMode) { mZenMode = zenMode; updateState(preference); } } src/com/android/settings/notification/modes/ManualDurationPreferenceController.java +4 −3 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.settings.notification.modes; import android.content.Context; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; Loading Loading @@ -49,12 +50,12 @@ public class ManualDurationPreferenceController extends AbstractZenModePreferenc return zenMode.isManualDnd(); } // Called by parent fragment onAttach(). // Called by parent fragment onStart(). void registerSettingsObserver() { mSettingsObserver.register(); } // Called by parent fragment onDetach(). // Called by parent fragment onStop(). void unregisterSettingsObserver() { mSettingsObserver.unregister(); } Loading @@ -69,7 +70,7 @@ public class ManualDurationPreferenceController extends AbstractZenModePreferenc } @Override public void updateState(Preference preference, ZenMode unusedZenMode) { public void updateState(Preference preference, @NonNull ZenMode unusedZenMode) { // This controller is a link between a Settings value (ZEN_DURATION) and the manual DND // mode. The status of the zen mode object itself doesn't affect the preference // value, as that comes from settings; that value from settings will determine the Loading src/com/android/settings/notification/modes/ZenModeEditNameIconFragmentBase.java +15 −41 Original line number Diff line number Diff line Loading @@ -21,14 +21,11 @@ import static com.google.common.base.Preconditions.checkState; import android.content.Context; import android.os.Bundle; import android.util.Log; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; Loading @@ -39,7 +36,6 @@ import com.android.settingslib.notification.modes.ZenModesBackend; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import java.util.Collection; import java.util.List; /** Loading Loading @@ -79,7 +75,11 @@ public abstract class ZenModeEditNameIconFragmentBase extends DashboardFragment ? icicle.getParcelable(MODE_KEY, ZenMode.class) : onCreateInstantiateZenMode(); if (mZenMode == null) { if (mZenMode != null) { for (var controller : getZenPreferenceControllers()) { controller.setZenMode(mZenMode); } } else { finish(); } } Loading Loading @@ -110,59 +110,33 @@ public abstract class ZenModeEditNameIconFragmentBase extends DashboardFragment ); } private Iterable<AbstractZenModePreferenceController> getZenPreferenceControllers() { return getPreferenceControllers().stream() .flatMap(List::stream) .filter(AbstractZenModePreferenceController.class::isInstance) .map(AbstractZenModePreferenceController.class::cast) .toList(); } @VisibleForTesting(otherwise = VisibleForTesting.NONE) @Nullable ZenMode getZenMode() { return mZenMode; } @Override public void onStart() { super.onStart(); updateControllers(); } @VisibleForTesting final void setModeName(String name) { checkNotNull(mZenMode).getRule().setName(Strings.nullToEmpty(name)); updateControllers(); // Updates confirmation button. forceUpdatePreferences(); // Updates confirmation button. } @VisibleForTesting final void setModeIcon(@DrawableRes int iconResId) { checkNotNull(mZenMode).getRule().setIconResId(iconResId); updateControllers(); // Updates icon at the top. } protected void updateControllers() { PreferenceScreen screen = getPreferenceScreen(); Collection<List<AbstractPreferenceController>> controllers = getPreferenceControllers(); if (mZenMode == null || screen == null || controllers == null) { return; } for (List<AbstractPreferenceController> list : controllers) { for (AbstractPreferenceController controller : list) { try { final String key = controller.getPreferenceKey(); final Preference preference = screen.findPreference(key); if (preference != null) { AbstractZenModePreferenceController zenController = (AbstractZenModePreferenceController) controller; zenController.updateZenMode(preference, mZenMode); } else { Log.d(getLogTag(), String.format("Cannot find preference with key %s in Controller %s", key, controller.getClass().getSimpleName())); } controller.displayPreference(screen); } catch (ClassCastException e) { // Skip any controllers that aren't AbstractZenModePreferenceController. Log.d(getLogTag(), "Could not cast: " + controller.getClass().getSimpleName()); } } } forceUpdatePreferences(); // Updates icon at the top. } @VisibleForTesting final void saveMode() { saveMode(checkNotNull(mZenMode)); Loading src/com/android/settings/notification/modes/ZenModeFragment.java +6 −16 Original line number Diff line number Diff line Loading @@ -79,14 +79,6 @@ public class ZenModeFragment extends ZenModeFragmentBase { return prefControllers; } @Override public void onAttach(@NonNull Context context) { super.onAttach(context); // allow duration preference controller to listen for settings changes use(ManualDurationPreferenceController.class).registerSettingsObserver(); } @Override public void onStart() { super.onStart(); Loading @@ -99,6 +91,9 @@ public class ZenModeFragment extends ZenModeFragmentBase { mModeMenuProvider = new ModeMenuProvider(mode); activity.addMenuProvider(mModeMenuProvider); } // allow duration preference controller to listen for settings changes use(ManualDurationPreferenceController.class).registerSettingsObserver(); } @Override Loading @@ -106,13 +101,8 @@ public class ZenModeFragment extends ZenModeFragmentBase { if (getActivity() != null) { getActivity().removeMenuProvider(mModeMenuProvider); } super.onStop(); } @Override public void onDetach() { use(ManualDurationPreferenceController.class).unregisterSettingsObserver(); super.onDetach(); super.onStop(); } @Override Loading @@ -122,13 +112,13 @@ public class ZenModeFragment extends ZenModeFragmentBase { } @Override protected void updateZenModeState() { 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.updateZenModeState(); super.onUpdatedZenModeState(); } private class ModeMenuProvider implements MenuProvider { Loading src/com/android/settings/notification/modes/ZenModeFragmentBase.java +58 −90 Original line number Diff line number Diff line Loading @@ -18,24 +18,18 @@ package com.android.settings.notification.modes; import static android.provider.Settings.EXTRA_AUTOMATIC_ZEN_RULE_ID; import android.content.Context; import android.os.Bundle; import android.util.Log; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import androidx.lifecycle.Lifecycle; import com.android.settings.R; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.notification.modes.ZenMode; import com.google.common.base.Preconditions; import java.util.List; import java.util.function.Consumer; /** * Base class for Settings pages used to configure individual modes. Loading @@ -43,13 +37,27 @@ import java.util.function.Consumer; abstract class ZenModeFragmentBase extends ZenModesFragmentBase { static final String TAG = "ZenModeSettings"; @Nullable // only until reloadMode() is called private ZenMode mZenMode; @Nullable private ZenMode mZenMode; @Nullable private ZenMode mModeOnLastControllerUpdate; @Override public void onAttach(@NonNull Context context) { super.onAttach(context); public void onCreate(Bundle icicle) { mZenMode = loadModeFromArguments(); if (mZenMode != null) { // Propagate mode info through to controllers. Must be done before super.onCreate(), // because that one calls AbstractPreferenceController.isAvailable(). for (var controller : getZenPreferenceControllers()) { controller.setZenMode(mZenMode); } } else { toastAndFinish(); } super.onCreate(icicle); } @Nullable private ZenMode loadModeFromArguments() { String id = null; if (getActivity() != null && getActivity().getIntent() != null) { id = getActivity().getIntent().getStringExtra(EXTRA_AUTOMATIC_ZEN_RULE_ID); Loading @@ -60,93 +68,65 @@ abstract class ZenModeFragmentBase extends ZenModesFragmentBase { } if (id == null) { Log.d(TAG, "No id provided"); toastAndFinish(); return; } if (!reloadMode(id)) { Log.d(TAG, "Mode id " + id + " not found"); toastAndFinish(); return; } if (mZenMode != null) { // Propagate mode info through to controllers. for (List<AbstractPreferenceController> list : getPreferenceControllers()) { try { for (AbstractPreferenceController controller : list) { // mZenMode guaranteed non-null from reloadMode() above ((AbstractZenModePreferenceController) controller).setZenMode(mZenMode); } } catch (ClassCastException e) { // ignore controllers that aren't AbstractZenModePreferenceController } return null; } ZenMode mode = mBackend.getMode(id); if (mode == null) { Log.d(TAG, "Mode with id " + id + " not found"); return null; } return mode; } /** * Refresh stored ZenMode data. * @param id the mode ID * @return whether we successfully got mode data from the backend. */ private boolean reloadMode(String id) { mZenMode = mBackend.getMode(id); if (mZenMode == null) { return false; } return true; private Iterable<AbstractZenModePreferenceController> getZenPreferenceControllers() { return getPreferenceControllers().stream() .flatMap(List::stream) .filter(AbstractZenModePreferenceController.class::isInstance) .map(AbstractZenModePreferenceController.class::cast) .toList(); } /** * Refresh ZenMode data any time the system's zen mode state changes (either the zen mode value * itself, or the config), and also (once updated) update the info for all controllers. */ @Override protected void updateZenModeState() { protected void onUpdatedZenModeState() { if (mZenMode == null) { // This shouldn't happen, but guard against it in case Log.wtf(TAG, "mZenMode is null in onUpdatedZenModeState"); toastAndFinish(); return; } String id = mZenMode.getId(); if (!reloadMode(id)) { ZenMode mode = mBackend.getMode(id); if (mode == null) { Log.d(TAG, "Mode id=" + id + " not found"); toastAndFinish(); return; } updateControllers(); } private void updateControllers() { if (getPreferenceControllers() == null || mZenMode == null) { return; mZenMode = mode; maybeUpdateControllersState(mode); } final PreferenceScreen screen = getPreferenceScreen(); if (screen == null) { Log.d(TAG, "PreferenceScreen not found"); return; } for (List<AbstractPreferenceController> list : getPreferenceControllers()) { for (AbstractPreferenceController controller : list) { try { // Find preference associated with controller final String key = controller.getPreferenceKey(); final Preference preference = screen.findPreference(key); if (preference != null) { AbstractZenModePreferenceController zenController = (AbstractZenModePreferenceController) controller; zenController.updateZenMode(preference, mZenMode); } else { Log.d(TAG, String.format("Cannot find preference with key %s in Controller %s", key, controller.getClass().getSimpleName())); } controller.displayPreference(screen); } catch (ClassCastException e) { // Skip any controllers that aren't AbstractZenModePreferenceController. Log.d(TAG, "Could not cast: " + controller.getClass().getSimpleName()); } /** * Updates all {@link AbstractZenModePreferenceController} based on the loaded mode info. * For each controller, {@link AbstractZenModePreferenceController#setZenMode} will be called. * Then, {@link AbstractZenModePreferenceController#updateState} will be called as well, unless * we determine it's not necessary (for example, if we know that {@code DashboardFragment} will * do it soon). */ private void maybeUpdateControllersState(@NonNull ZenMode zenMode) { boolean needsFullUpdate = getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED) && (mModeOnLastControllerUpdate == null || !mModeOnLastControllerUpdate.equals(zenMode)); mModeOnLastControllerUpdate = zenMode.copy(); for (var controller : getZenPreferenceControllers()) { controller.setZenMode(zenMode); } if (needsFullUpdate) { forceUpdatePreferences(); } } Loading @@ -163,16 +143,4 @@ abstract class ZenModeFragmentBase extends ZenModesFragmentBase { public ZenMode getMode() { return mZenMode; } protected final boolean saveMode(Consumer<ZenMode> updater) { Preconditions.checkState(mBackend != null); ZenMode mode = mZenMode; if (mode == null) { Log.wtf(TAG, "Cannot save mode, it hasn't been loaded (" + getClass() + ")"); return false; } updater.accept(mode); mBackend.updateMode(mode); return true; } } Loading
src/com/android/settings/notification/modes/AbstractZenModePreferenceController.java +22 −21 Original line number Diff line number Diff line Loading @@ -25,8 +25,8 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.notification.modes.ZenMode; Loading Loading @@ -92,29 +92,14 @@ abstract class AbstractZenModePreferenceController extends AbstractPreferenceCon return true; } // Called by parent Fragment onAttach, for any methods (such as isAvailable()) that need // zen mode info before onStart. Most callers should use updateZenMode instead, which will // do any further necessary propagation. protected final void setZenMode(@NonNull ZenMode zenMode) { mZenMode = zenMode; } // Called by the parent Fragment onStart, which means it will happen before resume. public void updateZenMode(@NonNull Preference preference, @NonNull ZenMode zenMode) { /** * Assigns the {@link ZenMode} of this controller, so that it can be used later from * {@link #isAvailable()} and {@link #updateState(Preference)}. */ final void setZenMode(@NonNull ZenMode zenMode) { mZenMode = zenMode; updateState(preference); } @Override public void displayPreference(PreferenceScreen screen) { super.displayPreference(screen); if (mZenMode != null) { displayPreference(screen, mZenMode); } } public void displayPreference(PreferenceScreen screen, @NonNull ZenMode zenMode) {} @Override public final void updateState(Preference preference) { super.updateState(preference); Loading Loading @@ -167,4 +152,20 @@ abstract class AbstractZenModePreferenceController extends AbstractPreferenceCon return mode; }); } @VisibleForTesting(otherwise = VisibleForTesting.NONE) @Nullable ZenMode getZenMode() { return mZenMode; } /** * Convenience method for tests. Assigns the {@link ZenMode} of this controller, and calls * {@link #updateState(Preference)} immediately. */ @VisibleForTesting(otherwise = VisibleForTesting.NONE) final void updateZenMode(@NonNull Preference preference, @NonNull ZenMode zenMode) { mZenMode = zenMode; updateState(preference); } }
src/com/android/settings/notification/modes/ManualDurationPreferenceController.java +4 −3 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.settings.notification.modes; import android.content.Context; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; Loading Loading @@ -49,12 +50,12 @@ public class ManualDurationPreferenceController extends AbstractZenModePreferenc return zenMode.isManualDnd(); } // Called by parent fragment onAttach(). // Called by parent fragment onStart(). void registerSettingsObserver() { mSettingsObserver.register(); } // Called by parent fragment onDetach(). // Called by parent fragment onStop(). void unregisterSettingsObserver() { mSettingsObserver.unregister(); } Loading @@ -69,7 +70,7 @@ public class ManualDurationPreferenceController extends AbstractZenModePreferenc } @Override public void updateState(Preference preference, ZenMode unusedZenMode) { public void updateState(Preference preference, @NonNull ZenMode unusedZenMode) { // This controller is a link between a Settings value (ZEN_DURATION) and the manual DND // mode. The status of the zen mode object itself doesn't affect the preference // value, as that comes from settings; that value from settings will determine the Loading
src/com/android/settings/notification/modes/ZenModeEditNameIconFragmentBase.java +15 −41 Original line number Diff line number Diff line Loading @@ -21,14 +21,11 @@ import static com.google.common.base.Preconditions.checkState; import android.content.Context; import android.os.Bundle; import android.util.Log; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; Loading @@ -39,7 +36,6 @@ import com.android.settingslib.notification.modes.ZenModesBackend; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import java.util.Collection; import java.util.List; /** Loading Loading @@ -79,7 +75,11 @@ public abstract class ZenModeEditNameIconFragmentBase extends DashboardFragment ? icicle.getParcelable(MODE_KEY, ZenMode.class) : onCreateInstantiateZenMode(); if (mZenMode == null) { if (mZenMode != null) { for (var controller : getZenPreferenceControllers()) { controller.setZenMode(mZenMode); } } else { finish(); } } Loading Loading @@ -110,59 +110,33 @@ public abstract class ZenModeEditNameIconFragmentBase extends DashboardFragment ); } private Iterable<AbstractZenModePreferenceController> getZenPreferenceControllers() { return getPreferenceControllers().stream() .flatMap(List::stream) .filter(AbstractZenModePreferenceController.class::isInstance) .map(AbstractZenModePreferenceController.class::cast) .toList(); } @VisibleForTesting(otherwise = VisibleForTesting.NONE) @Nullable ZenMode getZenMode() { return mZenMode; } @Override public void onStart() { super.onStart(); updateControllers(); } @VisibleForTesting final void setModeName(String name) { checkNotNull(mZenMode).getRule().setName(Strings.nullToEmpty(name)); updateControllers(); // Updates confirmation button. forceUpdatePreferences(); // Updates confirmation button. } @VisibleForTesting final void setModeIcon(@DrawableRes int iconResId) { checkNotNull(mZenMode).getRule().setIconResId(iconResId); updateControllers(); // Updates icon at the top. } protected void updateControllers() { PreferenceScreen screen = getPreferenceScreen(); Collection<List<AbstractPreferenceController>> controllers = getPreferenceControllers(); if (mZenMode == null || screen == null || controllers == null) { return; } for (List<AbstractPreferenceController> list : controllers) { for (AbstractPreferenceController controller : list) { try { final String key = controller.getPreferenceKey(); final Preference preference = screen.findPreference(key); if (preference != null) { AbstractZenModePreferenceController zenController = (AbstractZenModePreferenceController) controller; zenController.updateZenMode(preference, mZenMode); } else { Log.d(getLogTag(), String.format("Cannot find preference with key %s in Controller %s", key, controller.getClass().getSimpleName())); } controller.displayPreference(screen); } catch (ClassCastException e) { // Skip any controllers that aren't AbstractZenModePreferenceController. Log.d(getLogTag(), "Could not cast: " + controller.getClass().getSimpleName()); } } } forceUpdatePreferences(); // Updates icon at the top. } @VisibleForTesting final void saveMode() { saveMode(checkNotNull(mZenMode)); Loading
src/com/android/settings/notification/modes/ZenModeFragment.java +6 −16 Original line number Diff line number Diff line Loading @@ -79,14 +79,6 @@ public class ZenModeFragment extends ZenModeFragmentBase { return prefControllers; } @Override public void onAttach(@NonNull Context context) { super.onAttach(context); // allow duration preference controller to listen for settings changes use(ManualDurationPreferenceController.class).registerSettingsObserver(); } @Override public void onStart() { super.onStart(); Loading @@ -99,6 +91,9 @@ public class ZenModeFragment extends ZenModeFragmentBase { mModeMenuProvider = new ModeMenuProvider(mode); activity.addMenuProvider(mModeMenuProvider); } // allow duration preference controller to listen for settings changes use(ManualDurationPreferenceController.class).registerSettingsObserver(); } @Override Loading @@ -106,13 +101,8 @@ public class ZenModeFragment extends ZenModeFragmentBase { if (getActivity() != null) { getActivity().removeMenuProvider(mModeMenuProvider); } super.onStop(); } @Override public void onDetach() { use(ManualDurationPreferenceController.class).unregisterSettingsObserver(); super.onDetach(); super.onStop(); } @Override Loading @@ -122,13 +112,13 @@ public class ZenModeFragment extends ZenModeFragmentBase { } @Override protected void updateZenModeState() { 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.updateZenModeState(); super.onUpdatedZenModeState(); } private class ModeMenuProvider implements MenuProvider { Loading
src/com/android/settings/notification/modes/ZenModeFragmentBase.java +58 −90 Original line number Diff line number Diff line Loading @@ -18,24 +18,18 @@ package com.android.settings.notification.modes; import static android.provider.Settings.EXTRA_AUTOMATIC_ZEN_RULE_ID; import android.content.Context; import android.os.Bundle; import android.util.Log; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import androidx.lifecycle.Lifecycle; import com.android.settings.R; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.notification.modes.ZenMode; import com.google.common.base.Preconditions; import java.util.List; import java.util.function.Consumer; /** * Base class for Settings pages used to configure individual modes. Loading @@ -43,13 +37,27 @@ import java.util.function.Consumer; abstract class ZenModeFragmentBase extends ZenModesFragmentBase { static final String TAG = "ZenModeSettings"; @Nullable // only until reloadMode() is called private ZenMode mZenMode; @Nullable private ZenMode mZenMode; @Nullable private ZenMode mModeOnLastControllerUpdate; @Override public void onAttach(@NonNull Context context) { super.onAttach(context); public void onCreate(Bundle icicle) { mZenMode = loadModeFromArguments(); if (mZenMode != null) { // Propagate mode info through to controllers. Must be done before super.onCreate(), // because that one calls AbstractPreferenceController.isAvailable(). for (var controller : getZenPreferenceControllers()) { controller.setZenMode(mZenMode); } } else { toastAndFinish(); } super.onCreate(icicle); } @Nullable private ZenMode loadModeFromArguments() { String id = null; if (getActivity() != null && getActivity().getIntent() != null) { id = getActivity().getIntent().getStringExtra(EXTRA_AUTOMATIC_ZEN_RULE_ID); Loading @@ -60,93 +68,65 @@ abstract class ZenModeFragmentBase extends ZenModesFragmentBase { } if (id == null) { Log.d(TAG, "No id provided"); toastAndFinish(); return; } if (!reloadMode(id)) { Log.d(TAG, "Mode id " + id + " not found"); toastAndFinish(); return; } if (mZenMode != null) { // Propagate mode info through to controllers. for (List<AbstractPreferenceController> list : getPreferenceControllers()) { try { for (AbstractPreferenceController controller : list) { // mZenMode guaranteed non-null from reloadMode() above ((AbstractZenModePreferenceController) controller).setZenMode(mZenMode); } } catch (ClassCastException e) { // ignore controllers that aren't AbstractZenModePreferenceController } return null; } ZenMode mode = mBackend.getMode(id); if (mode == null) { Log.d(TAG, "Mode with id " + id + " not found"); return null; } return mode; } /** * Refresh stored ZenMode data. * @param id the mode ID * @return whether we successfully got mode data from the backend. */ private boolean reloadMode(String id) { mZenMode = mBackend.getMode(id); if (mZenMode == null) { return false; } return true; private Iterable<AbstractZenModePreferenceController> getZenPreferenceControllers() { return getPreferenceControllers().stream() .flatMap(List::stream) .filter(AbstractZenModePreferenceController.class::isInstance) .map(AbstractZenModePreferenceController.class::cast) .toList(); } /** * Refresh ZenMode data any time the system's zen mode state changes (either the zen mode value * itself, or the config), and also (once updated) update the info for all controllers. */ @Override protected void updateZenModeState() { protected void onUpdatedZenModeState() { if (mZenMode == null) { // This shouldn't happen, but guard against it in case Log.wtf(TAG, "mZenMode is null in onUpdatedZenModeState"); toastAndFinish(); return; } String id = mZenMode.getId(); if (!reloadMode(id)) { ZenMode mode = mBackend.getMode(id); if (mode == null) { Log.d(TAG, "Mode id=" + id + " not found"); toastAndFinish(); return; } updateControllers(); } private void updateControllers() { if (getPreferenceControllers() == null || mZenMode == null) { return; mZenMode = mode; maybeUpdateControllersState(mode); } final PreferenceScreen screen = getPreferenceScreen(); if (screen == null) { Log.d(TAG, "PreferenceScreen not found"); return; } for (List<AbstractPreferenceController> list : getPreferenceControllers()) { for (AbstractPreferenceController controller : list) { try { // Find preference associated with controller final String key = controller.getPreferenceKey(); final Preference preference = screen.findPreference(key); if (preference != null) { AbstractZenModePreferenceController zenController = (AbstractZenModePreferenceController) controller; zenController.updateZenMode(preference, mZenMode); } else { Log.d(TAG, String.format("Cannot find preference with key %s in Controller %s", key, controller.getClass().getSimpleName())); } controller.displayPreference(screen); } catch (ClassCastException e) { // Skip any controllers that aren't AbstractZenModePreferenceController. Log.d(TAG, "Could not cast: " + controller.getClass().getSimpleName()); } /** * Updates all {@link AbstractZenModePreferenceController} based on the loaded mode info. * For each controller, {@link AbstractZenModePreferenceController#setZenMode} will be called. * Then, {@link AbstractZenModePreferenceController#updateState} will be called as well, unless * we determine it's not necessary (for example, if we know that {@code DashboardFragment} will * do it soon). */ private void maybeUpdateControllersState(@NonNull ZenMode zenMode) { boolean needsFullUpdate = getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED) && (mModeOnLastControllerUpdate == null || !mModeOnLastControllerUpdate.equals(zenMode)); mModeOnLastControllerUpdate = zenMode.copy(); for (var controller : getZenPreferenceControllers()) { controller.setZenMode(zenMode); } if (needsFullUpdate) { forceUpdatePreferences(); } } Loading @@ -163,16 +143,4 @@ abstract class ZenModeFragmentBase extends ZenModesFragmentBase { public ZenMode getMode() { return mZenMode; } protected final boolean saveMode(Consumer<ZenMode> updater) { Preconditions.checkState(mBackend != null); ZenMode mode = mZenMode; if (mode == null) { Log.wtf(TAG, "Cannot save mode, it hasn't been loaded (" + getClass() + ")"); return false; } updater.accept(mode); mBackend.updateMode(mode); return true; } }