Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8e615470 authored by Fabian Kozynski's avatar Fabian Kozynski Committed by Android (Google) Code Review
Browse files

Merge "Add animation for Dnd dialog"

parents d46eb6c3 b25a2176
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.settingslib.notification;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
@@ -85,6 +84,7 @@ public class EnableZenModeDialog {

    @VisibleForTesting
    protected Context mContext;
    private final int mThemeResId;
    @VisibleForTesting
    protected TextView mZenAlarmWarning;
    @VisibleForTesting
@@ -97,10 +97,15 @@ public class EnableZenModeDialog {
    protected LayoutInflater mLayoutInflater;

    public EnableZenModeDialog(Context context) {
        this(context, 0);
    }

    public EnableZenModeDialog(Context context, int themeResId) {
        mContext = context;
        mThemeResId = themeResId;
    }

    public Dialog createDialog() {
    public AlertDialog createDialog() {
        mNotificationManager = (NotificationManager) mContext.
                getSystemService(Context.NOTIFICATION_SERVICE);
        mForeverId =  Condition.newId(mContext).appendPath("forever").build();
@@ -108,7 +113,7 @@ public class EnableZenModeDialog {
        mUserId = mContext.getUserId();
        mAttached = false;

        final AlertDialog.Builder builder = new AlertDialog.Builder(mContext)
        final AlertDialog.Builder builder = new AlertDialog.Builder(mContext, mThemeResId)
                .setTitle(R.string.zen_mode_settings_turn_on_dialog_title)
                .setNegativeButton(R.string.cancel, null)
                .setPositiveButton(R.string.zen_mode_enable_dialog_turn_on,
+31 −12
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.qs.tiles;
import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
import static android.provider.Settings.Global.ZEN_MODE_OFF;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
@@ -41,7 +42,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Switch;
import android.widget.Toast;

@@ -53,6 +53,7 @@ import com.android.settingslib.notification.EnableZenModeDialog;
import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.SysUIToast;
import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
@@ -84,6 +85,7 @@ public class DndTile extends QSTileImpl<BooleanState> {
    private final DndDetailAdapter mDetailAdapter;
    private final SharedPreferences mSharedPreferences;
    private final SettingObserver mSettingZenDuration;
    private final DialogLaunchAnimator mDialogLaunchAnimator;

    private boolean mListening;
    private boolean mShowingDetail;
@@ -100,7 +102,8 @@ public class DndTile extends QSTileImpl<BooleanState> {
            QSLogger qsLogger,
            ZenModeController zenModeController,
            @Main SharedPreferences sharedPreferences,
            SecureSettings secureSettings
            SecureSettings secureSettings,
            DialogLaunchAnimator dialogLaunchAnimator
    ) {
        super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
                statusBarStateController, activityStarter, qsLogger);
@@ -108,6 +111,7 @@ public class DndTile extends QSTileImpl<BooleanState> {
        mSharedPreferences = sharedPreferences;
        mDetailAdapter = new DndDetailAdapter();
        mController.observe(getLifecycle(), mZenCallback);
        mDialogLaunchAnimator = dialogLaunchAnimator;
        mSettingZenDuration = new SettingObserver(secureSettings, mUiHandler,
                Settings.Secure.ZEN_DURATION, getHost().getUserId()) {
            @Override
@@ -117,8 +121,6 @@ public class DndTile extends QSTileImpl<BooleanState> {
        };
    }



    public static void setVisible(Context context, boolean visible) {
        Prefs.putBoolean(context, Prefs.Key.DND_TILE_VISIBLE, visible);
    }
@@ -187,14 +189,17 @@ public class DndTile extends QSTileImpl<BooleanState> {
            switch (zenDuration) {
                case Settings.Secure.ZEN_DURATION_PROMPT:
                    mUiHandler.post(() -> {
                        Dialog mDialog = new EnableZenModeDialog(mContext).createDialog();
                        mDialog.getWindow().setType(
                                WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
                        SystemUIDialog.setShowForAllUsers(mDialog, true);
                        SystemUIDialog.registerDismissListener(mDialog);
                        SystemUIDialog.setWindowOnTop(mDialog);
                        mUiHandler.post(() -> mDialog.show());
                        mHost.collapsePanels();
                        Dialog dialog = makeZenModeDialog();
                        if (view != null) {
                            final Dialog hostDialog =
                                    mDialogLaunchAnimator.showFromView(dialog, view, false);
                            setDialogListeners(dialog, hostDialog);
                        } else {
                            // If we are not launching with animator, register default
                            // dismiss listener
                            SystemUIDialog.registerDismissListener(dialog);
                            dialog.show();
                        }
                    });
                    break;
                case Settings.Secure.ZEN_DURATION_FOREVER:
@@ -209,6 +214,20 @@ public class DndTile extends QSTileImpl<BooleanState> {
        }
    }

    private Dialog makeZenModeDialog() {
        AlertDialog dialog = new EnableZenModeDialog(mContext, R.style.Theme_SystemUI_Dialog)
                .createDialog();
        SystemUIDialog.applyFlags(dialog);
        SystemUIDialog.setShowForAllUsers(dialog, true);
        return dialog;
    }

    private void setDialogListeners(Dialog zenModeDialog, Dialog hostDialog) {
        // Zen mode dialog is never hidden.
        SystemUIDialog.registerDismissListener(zenModeDialog, hostDialog::dismiss);
        zenModeDialog.setOnCancelListener(dialog -> hostDialog.cancel());
    }

    @Override
    protected void handleSecondaryClick(@Nullable View view) {
        if (mController.isVolumeRestricted()) {
+23 −2
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ import android.view.WindowInsets.Type;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;

import androidx.annotation.Nullable;

import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.animation.DialogListener;
@@ -303,13 +305,32 @@ public class SystemUIDialog extends AlertDialog implements ListenableDialog,
     * the screen off / close system dialogs broadcast.
     * <p>
     * <strong>Note:</strong> Don't call dialog.setOnDismissListener() after
     * calling this because it causes a leak of BroadcastReceiver.
     * calling this because it causes a leak of BroadcastReceiver. Instead, call the version that
     * takes an extra Runnable as a parameter.
     *
     * @param dialog The dialog to be associated with the listener.
     */
    public static void registerDismissListener(Dialog dialog) {
        registerDismissListener(dialog, null);
    }


    /**
     * Registers a listener that dismisses the given dialog when it receives
     * the screen off / close system dialogs broadcast.
     * <p>
     * <strong>Note:</strong> Don't call dialog.setOnDismissListener() after
     * calling this because it causes a leak of BroadcastReceiver.
     *
     * @param dialog The dialog to be associated with the listener.
     * @param dismissAction An action to run when the dialog is dismissed.
     */
    public static void registerDismissListener(Dialog dialog, @Nullable Runnable dismissAction) {
        DismissReceiver dismissReceiver = new DismissReceiver(dialog);
        dialog.setOnDismissListener(d -> dismissReceiver.unregister());
        dialog.setOnDismissListener(d -> {
            dismissReceiver.unregister();
            if (dismissAction != null) dismissAction.run();
        });
        dismissReceiver.register();
    }

+49 −5
Original line number Diff line number Diff line
@@ -16,22 +16,28 @@

package com.android.systemui.qs.tiles

import android.app.Dialog
import android.content.ContextWrapper
import android.content.SharedPreferences
import android.os.Handler
import android.provider.Settings
import android.provider.Settings.Global.ZEN_MODE_OFF
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.UiEventLogger
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.classifier.FalsingManagerFake
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.statusbar.policy.ZenModeController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.settings.FakeSettings
import com.android.systemui.util.settings.SecureSettings
import com.google.common.truth.Truth.assertThat
@@ -40,9 +46,12 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.anyBoolean
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import java.io.File
import org.mockito.Mockito.`when` as whenever

@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -70,6 +79,10 @@ class DndTileTest : SysuiTestCase() {
    private lateinit var zenModeController: ZenModeController
    @Mock
    private lateinit var sharedPreferences: SharedPreferences
    @Mock
    private lateinit var dialogLaunchAnimator: DialogLaunchAnimator
    @Mock
    private lateinit var hostDialog: Dialog

    private lateinit var secureSettings: SecureSettings
    private lateinit var testableLooper: TestableLooper
@@ -81,15 +94,17 @@ class DndTileTest : SysuiTestCase() {
        testableLooper = TestableLooper.get(this)
        secureSettings = FakeSettings()

        Mockito.`when`(qsHost.userId).thenReturn(DEFAULT_USER)
        Mockito.`when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
        whenever(qsHost.userId).thenReturn(DEFAULT_USER)
        whenever(qsHost.uiEventLogger).thenReturn(uiEventLogger)
        whenever(dialogLaunchAnimator.showFromView(any(), any(), anyBoolean()))
                .thenReturn(hostDialog)

        val wrappedContext = object : ContextWrapper(context) {
            override fun getSharedPreferences(file: File?, mode: Int): SharedPreferences {
                return sharedPreferences
            }
        }
        Mockito.`when`(qsHost.context).thenReturn(wrappedContext)
        whenever(qsHost.context).thenReturn(wrappedContext)

        tile = DndTile(
            qsHost,
@@ -102,7 +117,8 @@ class DndTileTest : SysuiTestCase() {
            qsLogger,
            zenModeController,
            sharedPreferences,
            secureSettings
            secureSettings,
            dialogLaunchAnimator
        )
    }

@@ -147,4 +163,32 @@ class DndTileTest : SysuiTestCase() {

        assertThat(tile.state.forceExpandIcon).isTrue()
    }

    @Test
    fun testLaunchDialogFromViewWhenPrompt() {
        whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)

        secureSettings.putIntForUser(KEY, Settings.Secure.ZEN_DURATION_PROMPT, DEFAULT_USER)
        testableLooper.processAllMessages()

        val view = View(context)
        tile.handleClick(view)
        testableLooper.processAllMessages()

        verify(dialogLaunchAnimator).showFromView(any(), eq(view), anyBoolean())
    }

    @Test
    fun testNoLaunchDialogWhenNotPrompt() {
        whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)

        secureSettings.putIntForUser(KEY, 60, DEFAULT_USER)
        testableLooper.processAllMessages()

        val view = View(context)
        tile.handleClick(view)
        testableLooper.processAllMessages()

        verify(dialogLaunchAnimator, never()).showFromView(any(), any(), anyBoolean())
    }
}
 No newline at end of file