Merge changes I08c5006a,I6686b77c into qt-dev
* changes: Handle null OnSettingsClickListeners in ChannelDialogEditorController Close channel dialog when the guts go away
This commit is contained in:
committed by
Android (Google) Code Review
commit
d42cb76a74
@@ -29,6 +29,7 @@ import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.util.Log
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
import android.view.Window
|
||||
@@ -86,13 +87,17 @@ class ChannelEditorDialogController @Inject constructor(
|
||||
internal val groupNameLookup = hashMapOf<String, CharSequence>()
|
||||
private val channelGroupList = mutableListOf<NotificationChannelGroup>()
|
||||
|
||||
/**
|
||||
* Give the controller all of the information it needs to present the dialog
|
||||
* for a given app. Does a bunch of querying of NoMan, but won't present anything yet
|
||||
*/
|
||||
fun prepareDialogForApp(
|
||||
appName: String,
|
||||
packageName: String,
|
||||
uid: Int,
|
||||
channels: Set<NotificationChannel>,
|
||||
appIcon: Drawable,
|
||||
onSettingsClickListener: NotificationInfo.OnSettingsClickListener
|
||||
onSettingsClickListener: NotificationInfo.OnSettingsClickListener?
|
||||
) {
|
||||
this.appName = appName
|
||||
this.packageName = packageName
|
||||
@@ -156,6 +161,13 @@ class ChannelEditorDialogController @Inject constructor(
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the dialog without saving. For external callers
|
||||
*/
|
||||
fun close() {
|
||||
done()
|
||||
}
|
||||
|
||||
private fun done() {
|
||||
resetState()
|
||||
dialog.dismiss()
|
||||
@@ -235,6 +247,11 @@ class ChannelEditorDialogController @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
fun launchSettings(sender: View) {
|
||||
onSettingsClickListener?.onClick(sender, null, appUid!!)
|
||||
}
|
||||
|
||||
private fun initDialog() {
|
||||
dialog = Dialog(context)
|
||||
|
||||
@@ -257,7 +274,7 @@ class ChannelEditorDialogController @Inject constructor(
|
||||
}
|
||||
|
||||
findViewById<TextView>(R.id.see_more_button)?.setOnClickListener {
|
||||
onSettingsClickListener?.onClick(it, null, appUid!!)
|
||||
launchSettings(it)
|
||||
done()
|
||||
}
|
||||
|
||||
|
||||
@@ -41,12 +41,14 @@ import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.SysUiServiceProvider;
|
||||
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.NotificationLifetimeExtender;
|
||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
||||
import com.android.systemui.statusbar.NotificationPresenter;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
|
||||
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
|
||||
import com.android.systemui.statusbar.notification.VisualStabilityManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
@@ -97,6 +99,8 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
|
||||
@VisibleForTesting
|
||||
protected String mKeyToRemoveOnGutsClosed;
|
||||
|
||||
private StatusBar mStatusBar;
|
||||
|
||||
@Inject
|
||||
public NotificationGutsManager(
|
||||
Context context,
|
||||
@@ -114,6 +118,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
|
||||
mListContainer = listContainer;
|
||||
mCheckSaveListener = checkSave;
|
||||
mOnSettingsClickListener = onSettingsClick;
|
||||
mStatusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
|
||||
}
|
||||
|
||||
public void setNotificationActivityStarter(
|
||||
@@ -376,6 +381,34 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
|
||||
int x,
|
||||
int y,
|
||||
NotificationMenuRowPlugin.MenuItem menuItem) {
|
||||
if (menuItem.getGutsView() instanceof NotificationInfo) {
|
||||
if (mStatusBarStateController instanceof StatusBarStateControllerImpl) {
|
||||
((StatusBarStateControllerImpl) mStatusBarStateController)
|
||||
.setLeaveOpenOnKeyguardHide(true);
|
||||
}
|
||||
|
||||
Runnable r = () -> Dependency.get(Dependency.MAIN_HANDLER).post(
|
||||
() -> openGutsInternal(view, x, y, menuItem));
|
||||
|
||||
mStatusBar.executeRunnableDismissingKeyguard(
|
||||
r,
|
||||
null /* cancelAction */,
|
||||
false /* dismissShade */,
|
||||
true /* afterKeyguardGone */,
|
||||
true /* deferred */);
|
||||
|
||||
return true;
|
||||
}
|
||||
return openGutsInternal(view, x, y, menuItem);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean openGutsInternal(
|
||||
View view,
|
||||
int x,
|
||||
int y,
|
||||
NotificationMenuRowPlugin.MenuItem menuItem) {
|
||||
|
||||
if (!(view instanceof ExpandableNotificationRow)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -118,6 +118,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
private int mStartingChannelImportance;
|
||||
private boolean mWasShownHighPriority;
|
||||
private boolean mPressedApply;
|
||||
private boolean mPresentingChannelEditorDialog = false;
|
||||
|
||||
/**
|
||||
* The last importance level chosen by the user. Null if the user has not chosen an importance
|
||||
@@ -447,11 +448,15 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
|
||||
private OnClickListener getTurnOffNotificationsClickListener() {
|
||||
return ((View view) -> {
|
||||
if (mChannelEditorDialogController != null) {
|
||||
if (!mPresentingChannelEditorDialog && mChannelEditorDialogController != null) {
|
||||
mPresentingChannelEditorDialog = true;
|
||||
|
||||
mChannelEditorDialogController.prepareDialogForApp(mAppName, mPackageName, mAppUid,
|
||||
mUniqueChannelsInRow, mPkgIcon, mOnSettingsClickListener);
|
||||
mChannelEditorDialogController.setOnFinishListener(
|
||||
() -> closeControls(this, false));
|
||||
mChannelEditorDialogController.setOnFinishListener(() -> {
|
||||
mPresentingChannelEditorDialog = false;
|
||||
closeControls(this, false);
|
||||
});
|
||||
mChannelEditorDialogController.show();
|
||||
}
|
||||
});
|
||||
@@ -772,6 +777,13 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
|
||||
@Override
|
||||
public boolean handleCloseControls(boolean save, boolean force) {
|
||||
if (mPresentingChannelEditorDialog && mChannelEditorDialogController != null) {
|
||||
mPresentingChannelEditorDialog = false;
|
||||
// No need for the finish listener because we're closing
|
||||
mChannelEditorDialogController.setOnFinishListener(null);
|
||||
mChannelEditorDialogController.close();
|
||||
}
|
||||
|
||||
// Save regardless of the importance so we can lock the importance field if the user wants
|
||||
// to keep getting notifications
|
||||
if (save) {
|
||||
|
||||
@@ -109,7 +109,7 @@ class ChannelEditorDialogControllerTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPrepareDialogForApp_retrievesUpto4Channels() {
|
||||
fun testPrepareDialogForApp_retrievesUpTo4Channels() {
|
||||
val channel3 = NotificationChannel("test_channel_3", "Test channel 3", IMPORTANCE_DEFAULT)
|
||||
val channel4 = NotificationChannel("test_channel_4", "Test channel 4", IMPORTANCE_DEFAULT)
|
||||
|
||||
@@ -169,6 +169,16 @@ class ChannelEditorDialogControllerTest : SysuiTestCase() {
|
||||
eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSettingsClickListenerNull_noCrash() {
|
||||
group.channels = listOf(channel1, channel2)
|
||||
controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID,
|
||||
setOf(channel1, channel2), appIcon, null)
|
||||
|
||||
// Pass in any old view, it should never actually be used
|
||||
controller.launchSettings(View(context))
|
||||
}
|
||||
|
||||
private val clickListener = object : NotificationInfo.OnSettingsClickListener {
|
||||
override fun onClick(v: View, c: NotificationChannel, appUid: Int) {
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ import com.android.systemui.statusbar.notification.VisualStabilityManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||
import com.android.systemui.util.Assert;
|
||||
|
||||
@@ -105,6 +106,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
|
||||
@Mock private NotificationInfo.CheckSaveListener mCheckSaveListener;
|
||||
@Mock private OnSettingsClickListener mOnSettingsClickListener;
|
||||
@Mock private DeviceProvisionedController mDeviceProvisionedController;
|
||||
@Mock private StatusBar mStatusBar;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -115,7 +117,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
|
||||
mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
|
||||
mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
|
||||
mHandler = Handler.createAsync(mTestableLooper.getLooper());
|
||||
|
||||
mContext.putComponent(StatusBar.class, mStatusBar);
|
||||
mHelper = new NotificationTestHelper(mContext);
|
||||
|
||||
mGutsManager = new NotificationGutsManager(mContext, mVisualStabilityManager);
|
||||
@@ -150,7 +152,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
|
||||
when(row.getWindowToken()).thenReturn(new Binder());
|
||||
when(row.getGuts()).thenReturn(guts);
|
||||
|
||||
assertTrue(mGutsManager.openGuts(row, 0, 0, menuItem));
|
||||
assertTrue(mGutsManager.openGutsInternal(row, 0, 0, menuItem));
|
||||
assertEquals(View.INVISIBLE, guts.getVisibility());
|
||||
mTestableLooper.processAllMessages();
|
||||
verify(guts).openControls(
|
||||
@@ -198,7 +200,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
|
||||
when(entry.getRow()).thenReturn(row);
|
||||
when(entry.getGuts()).thenReturn(guts);
|
||||
|
||||
assertTrue(mGutsManager.openGuts(row, 0, 0, menuItem));
|
||||
assertTrue(mGutsManager.openGutsInternal(row, 0, 0, menuItem));
|
||||
mTestableLooper.processAllMessages();
|
||||
verify(guts).openControls(
|
||||
eq(true),
|
||||
|
||||
Reference in New Issue
Block a user