[DO NOT MERGE] Add animation for Dnd dialog am: 9ac796de8d
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16265468 Change-Id: I68609c1e4fbe0ddcb6fb0b6f6b9df02075179684
This commit is contained in:
@@ -19,7 +19,6 @@ package com.android.settingslib.notification;
|
|||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
@@ -85,6 +84,7 @@ public class EnableZenModeDialog {
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected Context mContext;
|
protected Context mContext;
|
||||||
|
private final int mThemeResId;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected TextView mZenAlarmWarning;
|
protected TextView mZenAlarmWarning;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -97,10 +97,15 @@ public class EnableZenModeDialog {
|
|||||||
protected LayoutInflater mLayoutInflater;
|
protected LayoutInflater mLayoutInflater;
|
||||||
|
|
||||||
public EnableZenModeDialog(Context context) {
|
public EnableZenModeDialog(Context context) {
|
||||||
mContext = context;
|
this(context, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dialog createDialog() {
|
public EnableZenModeDialog(Context context, int themeResId) {
|
||||||
|
mContext = context;
|
||||||
|
mThemeResId = themeResId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AlertDialog createDialog() {
|
||||||
mNotificationManager = (NotificationManager) mContext.
|
mNotificationManager = (NotificationManager) mContext.
|
||||||
getSystemService(Context.NOTIFICATION_SERVICE);
|
getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
mForeverId = Condition.newId(mContext).appendPath("forever").build();
|
mForeverId = Condition.newId(mContext).appendPath("forever").build();
|
||||||
@@ -108,7 +113,7 @@ public class EnableZenModeDialog {
|
|||||||
mUserId = mContext.getUserId();
|
mUserId = mContext.getUserId();
|
||||||
mAttached = false;
|
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)
|
.setTitle(R.string.zen_mode_settings_turn_on_dialog_title)
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.setPositiveButton(R.string.zen_mode_enable_dialog_turn_on,
|
.setPositiveButton(R.string.zen_mode_enable_dialog_turn_on,
|
||||||
|
|||||||
@@ -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_ALARMS;
|
||||||
import static android.provider.Settings.Global.ZEN_MODE_OFF;
|
import static android.provider.Settings.Global.ZEN_MODE_OFF;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -41,7 +42,6 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnAttachStateChangeListener;
|
import android.view.View.OnAttachStateChangeListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.widget.Switch;
|
import android.widget.Switch;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@@ -53,6 +53,7 @@ import com.android.settingslib.notification.EnableZenModeDialog;
|
|||||||
import com.android.systemui.Prefs;
|
import com.android.systemui.Prefs;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.SysUIToast;
|
import com.android.systemui.SysUIToast;
|
||||||
|
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||||
import com.android.systemui.dagger.qualifiers.Background;
|
import com.android.systemui.dagger.qualifiers.Background;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
import com.android.systemui.plugins.ActivityStarter;
|
import com.android.systemui.plugins.ActivityStarter;
|
||||||
@@ -84,6 +85,7 @@ public class DndTile extends QSTileImpl<BooleanState> {
|
|||||||
private final DndDetailAdapter mDetailAdapter;
|
private final DndDetailAdapter mDetailAdapter;
|
||||||
private final SharedPreferences mSharedPreferences;
|
private final SharedPreferences mSharedPreferences;
|
||||||
private final SecureSetting mSettingZenDuration;
|
private final SecureSetting mSettingZenDuration;
|
||||||
|
private final DialogLaunchAnimator mDialogLaunchAnimator;
|
||||||
|
|
||||||
private boolean mListening;
|
private boolean mListening;
|
||||||
private boolean mShowingDetail;
|
private boolean mShowingDetail;
|
||||||
@@ -100,7 +102,8 @@ public class DndTile extends QSTileImpl<BooleanState> {
|
|||||||
QSLogger qsLogger,
|
QSLogger qsLogger,
|
||||||
ZenModeController zenModeController,
|
ZenModeController zenModeController,
|
||||||
@Main SharedPreferences sharedPreferences,
|
@Main SharedPreferences sharedPreferences,
|
||||||
SecureSettings secureSettings
|
SecureSettings secureSettings,
|
||||||
|
DialogLaunchAnimator dialogLaunchAnimator
|
||||||
) {
|
) {
|
||||||
super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
|
super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
|
||||||
statusBarStateController, activityStarter, qsLogger);
|
statusBarStateController, activityStarter, qsLogger);
|
||||||
@@ -108,6 +111,7 @@ public class DndTile extends QSTileImpl<BooleanState> {
|
|||||||
mSharedPreferences = sharedPreferences;
|
mSharedPreferences = sharedPreferences;
|
||||||
mDetailAdapter = new DndDetailAdapter();
|
mDetailAdapter = new DndDetailAdapter();
|
||||||
mController.observe(getLifecycle(), mZenCallback);
|
mController.observe(getLifecycle(), mZenCallback);
|
||||||
|
mDialogLaunchAnimator = dialogLaunchAnimator;
|
||||||
mSettingZenDuration = new SecureSetting(secureSettings, mUiHandler,
|
mSettingZenDuration = new SecureSetting(secureSettings, mUiHandler,
|
||||||
Settings.Secure.ZEN_DURATION, getHost().getUserId()) {
|
Settings.Secure.ZEN_DURATION, getHost().getUserId()) {
|
||||||
@Override
|
@Override
|
||||||
@@ -117,8 +121,6 @@ public class DndTile extends QSTileImpl<BooleanState> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void setVisible(Context context, boolean visible) {
|
public static void setVisible(Context context, boolean visible) {
|
||||||
Prefs.putBoolean(context, Prefs.Key.DND_TILE_VISIBLE, visible);
|
Prefs.putBoolean(context, Prefs.Key.DND_TILE_VISIBLE, visible);
|
||||||
}
|
}
|
||||||
@@ -187,14 +189,17 @@ public class DndTile extends QSTileImpl<BooleanState> {
|
|||||||
switch (zenDuration) {
|
switch (zenDuration) {
|
||||||
case Settings.Secure.ZEN_DURATION_PROMPT:
|
case Settings.Secure.ZEN_DURATION_PROMPT:
|
||||||
mUiHandler.post(() -> {
|
mUiHandler.post(() -> {
|
||||||
Dialog mDialog = new EnableZenModeDialog(mContext).createDialog();
|
Dialog dialog = makeZenModeDialog();
|
||||||
mDialog.getWindow().setType(
|
if (view != null) {
|
||||||
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
|
final Dialog hostDialog =
|
||||||
SystemUIDialog.setShowForAllUsers(mDialog, true);
|
mDialogLaunchAnimator.showFromView(dialog, view, false);
|
||||||
SystemUIDialog.registerDismissListener(mDialog);
|
setDialogListeners(dialog, hostDialog);
|
||||||
SystemUIDialog.setWindowOnTop(mDialog);
|
} else {
|
||||||
mUiHandler.post(() -> mDialog.show());
|
// If we are not launching with animator, register default
|
||||||
mHost.collapsePanels();
|
// dismiss listener
|
||||||
|
SystemUIDialog.registerDismissListener(dialog);
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case Settings.Secure.ZEN_DURATION_FOREVER:
|
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
|
@Override
|
||||||
protected void handleSecondaryClick(@Nullable View view) {
|
protected void handleSecondaryClick(@Nullable View view) {
|
||||||
if (mController.isVolumeRestricted()) {
|
if (mController.isVolumeRestricted()) {
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ import android.view.WindowInsets.Type;
|
|||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.WindowManager.LayoutParams;
|
import android.view.WindowManager.LayoutParams;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.systemui.Dependency;
|
import com.android.systemui.Dependency;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.animation.DialogListener;
|
import com.android.systemui.animation.DialogListener;
|
||||||
@@ -303,13 +305,32 @@ public class SystemUIDialog extends AlertDialog implements ListenableDialog,
|
|||||||
* the screen off / close system dialogs broadcast.
|
* the screen off / close system dialogs broadcast.
|
||||||
* <p>
|
* <p>
|
||||||
* <strong>Note:</strong> Don't call dialog.setOnDismissListener() after
|
* <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.
|
* @param dialog The dialog to be associated with the listener.
|
||||||
*/
|
*/
|
||||||
public static void registerDismissListener(Dialog dialog) {
|
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);
|
DismissReceiver dismissReceiver = new DismissReceiver(dialog);
|
||||||
dialog.setOnDismissListener(d -> dismissReceiver.unregister());
|
dialog.setOnDismissListener(d -> {
|
||||||
|
dismissReceiver.unregister();
|
||||||
|
if (dismissAction != null) dismissAction.run();
|
||||||
|
});
|
||||||
dismissReceiver.register();
|
dismissReceiver.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,22 +16,28 @@
|
|||||||
|
|
||||||
package com.android.systemui.qs.tiles
|
package com.android.systemui.qs.tiles
|
||||||
|
|
||||||
|
import android.app.Dialog
|
||||||
import android.content.ContextWrapper
|
import android.content.ContextWrapper
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
|
import android.provider.Settings.Global.ZEN_MODE_OFF
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper
|
import android.testing.TestableLooper
|
||||||
|
import android.view.View
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.internal.logging.MetricsLogger
|
import com.android.internal.logging.MetricsLogger
|
||||||
import com.android.internal.logging.UiEventLogger
|
import com.android.internal.logging.UiEventLogger
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.animation.DialogLaunchAnimator
|
||||||
import com.android.systemui.classifier.FalsingManagerFake
|
import com.android.systemui.classifier.FalsingManagerFake
|
||||||
import com.android.systemui.plugins.ActivityStarter
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||||
import com.android.systemui.qs.QSHost
|
import com.android.systemui.qs.QSHost
|
||||||
import com.android.systemui.qs.logging.QSLogger
|
import com.android.systemui.qs.logging.QSLogger
|
||||||
import com.android.systemui.statusbar.policy.ZenModeController
|
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.FakeSettings
|
||||||
import com.android.systemui.util.settings.SecureSettings
|
import com.android.systemui.util.settings.SecureSettings
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
@@ -40,9 +46,12 @@ import org.junit.Before
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.Mock
|
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 org.mockito.MockitoAnnotations
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import org.mockito.Mockito.`when` as whenever
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
@@ -70,6 +79,10 @@ class DndTileTest : SysuiTestCase() {
|
|||||||
private lateinit var zenModeController: ZenModeController
|
private lateinit var zenModeController: ZenModeController
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var sharedPreferences: SharedPreferences
|
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 secureSettings: SecureSettings
|
||||||
private lateinit var testableLooper: TestableLooper
|
private lateinit var testableLooper: TestableLooper
|
||||||
@@ -81,15 +94,17 @@ class DndTileTest : SysuiTestCase() {
|
|||||||
testableLooper = TestableLooper.get(this)
|
testableLooper = TestableLooper.get(this)
|
||||||
secureSettings = FakeSettings()
|
secureSettings = FakeSettings()
|
||||||
|
|
||||||
Mockito.`when`(qsHost.userId).thenReturn(DEFAULT_USER)
|
whenever(qsHost.userId).thenReturn(DEFAULT_USER)
|
||||||
Mockito.`when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
|
whenever(qsHost.uiEventLogger).thenReturn(uiEventLogger)
|
||||||
|
whenever(dialogLaunchAnimator.showFromView(any(), any(), anyBoolean()))
|
||||||
|
.thenReturn(hostDialog)
|
||||||
|
|
||||||
val wrappedContext = object : ContextWrapper(context) {
|
val wrappedContext = object : ContextWrapper(context) {
|
||||||
override fun getSharedPreferences(file: File?, mode: Int): SharedPreferences {
|
override fun getSharedPreferences(file: File?, mode: Int): SharedPreferences {
|
||||||
return sharedPreferences
|
return sharedPreferences
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Mockito.`when`(qsHost.context).thenReturn(wrappedContext)
|
whenever(qsHost.context).thenReturn(wrappedContext)
|
||||||
|
|
||||||
tile = DndTile(
|
tile = DndTile(
|
||||||
qsHost,
|
qsHost,
|
||||||
@@ -102,7 +117,8 @@ class DndTileTest : SysuiTestCase() {
|
|||||||
qsLogger,
|
qsLogger,
|
||||||
zenModeController,
|
zenModeController,
|
||||||
sharedPreferences,
|
sharedPreferences,
|
||||||
secureSettings
|
secureSettings,
|
||||||
|
dialogLaunchAnimator
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,4 +163,32 @@ class DndTileTest : SysuiTestCase() {
|
|||||||
|
|
||||||
assertThat(tile.state.forceExpandIcon).isTrue()
|
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())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user