Merge "Extract NotificationClicker from NEM"
This commit is contained in:
committed by
Android (Google) Code Review
commit
f674b60e8d
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.systemui.statusbar.notification;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.os.SystemClock;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.systemui.DejankUtils;
|
||||
import com.android.systemui.bubbles.BubbleController;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.phone.ShadeController;
|
||||
|
||||
/**
|
||||
* Click handler for generic clicks on notifications. Clicks on specific areas (expansion caret,
|
||||
* app ops icon, etc) are handled elsewhere.
|
||||
*/
|
||||
public final class NotificationClicker implements View.OnClickListener {
|
||||
private static final String TAG = "NotificationClicker";
|
||||
|
||||
private final ShadeController mShadeController;
|
||||
private final BubbleController mBubbleController;
|
||||
private final NotificationActivityStarter mNotificationActivityStarter;
|
||||
|
||||
public NotificationClicker(ShadeController shadeController,
|
||||
BubbleController bubbleController,
|
||||
NotificationActivityStarter notificationActivityStarter) {
|
||||
mShadeController = shadeController;
|
||||
mBubbleController = bubbleController;
|
||||
mNotificationActivityStarter = notificationActivityStarter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
if (!(v instanceof ExpandableNotificationRow)) {
|
||||
Log.e(TAG, "NotificationClicker called on a view that is not a notification row.");
|
||||
return;
|
||||
}
|
||||
|
||||
mShadeController.wakeUpIfDozing(SystemClock.uptimeMillis(), v);
|
||||
|
||||
final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
|
||||
final StatusBarNotification sbn = row.getStatusBarNotification();
|
||||
if (sbn == null) {
|
||||
Log.e(TAG, "NotificationClicker called on an unclickable notification,");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the notification is displaying the menu, if so slide notification back
|
||||
if (isMenuVisible(row)) {
|
||||
row.animateTranslateNotification(0);
|
||||
return;
|
||||
} else if (row.isChildInGroup() && isMenuVisible(row.getNotificationParent())) {
|
||||
row.getNotificationParent().animateTranslateNotification(0);
|
||||
return;
|
||||
} else if (row.isSummaryWithChildren() && row.areChildrenExpanded()) {
|
||||
// We never want to open the app directly if the user clicks in between
|
||||
// the notifications.
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark notification for one frame.
|
||||
row.setJustClicked(true);
|
||||
DejankUtils.postAfterTraversal(() -> row.setJustClicked(false));
|
||||
|
||||
// If it was a bubble we should close it
|
||||
if (row.getEntry().isBubble()) {
|
||||
mBubbleController.collapseStack();
|
||||
}
|
||||
|
||||
mNotificationActivityStarter.onNotificationClicked(sbn, row);
|
||||
}
|
||||
|
||||
private boolean isMenuVisible(ExpandableNotificationRow row) {
|
||||
return row.getProvider() != null && row.getProvider().isMenuVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the click listener to the row if appropriate.
|
||||
*/
|
||||
public void register(ExpandableNotificationRow row, StatusBarNotification sbn) {
|
||||
Notification notification = sbn.getNotification();
|
||||
if (notification.contentIntent != null || notification.fullScreenIntent != null) {
|
||||
row.setOnClickListener(this);
|
||||
} else {
|
||||
row.setOnClickListener(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.systemui.statusbar.notification;
|
||||
|
||||
import static com.android.internal.util.Preconditions.checkNotNull;
|
||||
import static com.android.systemui.bubbles.BubbleController.DEBUG_DEMOTE_TO_NOTIF;
|
||||
import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
|
||||
import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY;
|
||||
@@ -36,7 +37,6 @@ import android.os.Handler;
|
||||
import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.service.dreams.DreamService;
|
||||
@@ -49,7 +49,6 @@ import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
@@ -57,7 +56,6 @@ import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.internal.statusbar.NotificationVisibility;
|
||||
import com.android.internal.util.NotificationMessagingUtil;
|
||||
import com.android.systemui.DejankUtils;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.EventLogTags;
|
||||
@@ -115,7 +113,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
|
||||
private final NotificationMessagingUtil mMessagingUtil;
|
||||
protected final Context mContext;
|
||||
protected final HashMap<String, NotificationData.Entry> mPendingNotifications = new HashMap<>();
|
||||
private final NotificationClicker mNotificationClicker = new NotificationClicker();
|
||||
|
||||
private final NotificationGroupManager mGroupManager =
|
||||
Dependency.get(NotificationGroupManager.class);
|
||||
@@ -146,7 +143,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
|
||||
protected IStatusBarService mBarService;
|
||||
private NotificationPresenter mPresenter;
|
||||
private Callback mCallback;
|
||||
private NotificationActivityStarter mNotificationActivityStarter;
|
||||
protected PowerManager mPowerManager;
|
||||
private NotificationListenerService.RankingMap mLatestRankingMap;
|
||||
protected HeadsUpManager mHeadsUpManager;
|
||||
@@ -161,63 +157,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
|
||||
private ExpandableNotificationRow.OnAppOpsClickListener mOnAppOpsClickListener;
|
||||
private NotificationViewHierarchyManager.StatusBarStateListener mStatusBarStateListener;
|
||||
@Nullable private AlertTransferListener mAlertTransferListener;
|
||||
|
||||
private final class NotificationClicker implements View.OnClickListener {
|
||||
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
if (!(v instanceof ExpandableNotificationRow)) {
|
||||
Log.e(TAG, "NotificationClicker called on a view that is not a notification row.");
|
||||
return;
|
||||
}
|
||||
|
||||
getShadeController().wakeUpIfDozing(SystemClock.uptimeMillis(), v);
|
||||
|
||||
final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
|
||||
final StatusBarNotification sbn = row.getStatusBarNotification();
|
||||
if (sbn == null) {
|
||||
Log.e(TAG, "NotificationClicker called on an unclickable notification,");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the notification is displaying the menu, if so slide notification back
|
||||
if (isMenuVisible(row)) {
|
||||
row.animateTranslateNotification(0);
|
||||
return;
|
||||
} else if (row.isChildInGroup() && isMenuVisible(row.getNotificationParent())) {
|
||||
row.getNotificationParent().animateTranslateNotification(0);
|
||||
return;
|
||||
} else if (row.isSummaryWithChildren() && row.areChildrenExpanded()) {
|
||||
// We never want to open the app directly if the user clicks in between
|
||||
// the notifications.
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark notification for one frame.
|
||||
row.setJustClicked(true);
|
||||
DejankUtils.postAfterTraversal(() -> row.setJustClicked(false));
|
||||
|
||||
// If it was a bubble we should close it
|
||||
if (row.getEntry().isBubble()) {
|
||||
mBubbleController.collapseStack();
|
||||
}
|
||||
|
||||
mNotificationActivityStarter.onNotificationClicked(sbn, row);
|
||||
}
|
||||
|
||||
private boolean isMenuVisible(ExpandableNotificationRow row) {
|
||||
return row.getProvider() != null && row.getProvider().isMenuVisible();
|
||||
}
|
||||
|
||||
public void register(ExpandableNotificationRow row, StatusBarNotification sbn) {
|
||||
Notification notification = sbn.getNotification();
|
||||
if (notification.contentIntent != null || notification.fullScreenIntent != null) {
|
||||
row.setOnClickListener(this);
|
||||
} else {
|
||||
row.setOnClickListener(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Nullable private NotificationClicker mNotificationClicker;
|
||||
|
||||
private final DeviceProvisionedController.DeviceProvisionedListener
|
||||
mDeviceProvisionedListener =
|
||||
@@ -269,6 +209,10 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
|
||||
mAlertTransferListener = listener;
|
||||
}
|
||||
|
||||
public void setNotificationClicker(NotificationClicker clicker) {
|
||||
mNotificationClicker = clicker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Our dependencies can have cyclic references, so some need to be lazy
|
||||
*/
|
||||
@@ -355,11 +299,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
|
||||
mOnAppOpsClickListener = mGutsManager::openGuts;
|
||||
}
|
||||
|
||||
public void setNotificationActivityStarter(
|
||||
NotificationActivityStarter notificationActivityStarter) {
|
||||
mNotificationActivityStarter = notificationActivityStarter;
|
||||
}
|
||||
|
||||
public NotificationData getNotificationData() {
|
||||
return mNotificationData;
|
||||
}
|
||||
@@ -757,7 +696,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
|
||||
row.setIsLowPriority(isLowPriority);
|
||||
row.setLowPriorityStateUpdated(isUpdate && (wasLowPriority != isLowPriority));
|
||||
// bind the click event to the content area
|
||||
mNotificationClicker.register(row, sbn);
|
||||
checkNotNull(mNotificationClicker).register(row, sbn);
|
||||
|
||||
// Extract target SDK version.
|
||||
try {
|
||||
|
||||
@@ -187,6 +187,7 @@ import com.android.systemui.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.VibratorHelper;
|
||||
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
|
||||
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
|
||||
import com.android.systemui.statusbar.notification.NotificationClicker;
|
||||
import com.android.systemui.statusbar.notification.NotificationData;
|
||||
import com.android.systemui.statusbar.notification.NotificationData.Entry;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
@@ -630,8 +631,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mBubbleController = Dependency.get(BubbleController.class);
|
||||
mBubbleController.setExpandListener(mBubbleExpandListener);
|
||||
|
||||
mGroupAlertTransferHelper.bind(mEntryManager, mGroupManager);
|
||||
|
||||
mColorExtractor.addOnColorsChangedListener(this);
|
||||
mStatusBarStateController.addCallback(this, StatusBarStateController.RANK_STATUS_BAR);
|
||||
|
||||
@@ -1018,7 +1017,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
return new QSFragment();
|
||||
}
|
||||
|
||||
protected void setUpPresenter() {
|
||||
private void setUpPresenter() {
|
||||
// Set up the initial notification state.
|
||||
mActivityLaunchAnimator = new ActivityLaunchAnimator(
|
||||
mStatusBarWindow, this, mNotificationPanel,
|
||||
@@ -1036,7 +1035,10 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mNotificationActivityStarter = new StatusBarNotificationActivityStarter(
|
||||
mContext, mNotificationPanel, mPresenter, mHeadsUpManager, mActivityLaunchAnimator);
|
||||
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
|
||||
mEntryManager.setNotificationActivityStarter(mNotificationActivityStarter);
|
||||
|
||||
mGroupAlertTransferHelper.bind(mEntryManager, mGroupManager);
|
||||
mEntryManager.setNotificationClicker(new NotificationClicker(
|
||||
this, Dependency.get(BubbleController.class), mNotificationActivityStarter));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -231,6 +231,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
|
||||
mEntryManager = new TestableNotificationEntryManager(mContext, mBarService);
|
||||
Dependency.get(InitController.class).executePostInitTasks();
|
||||
mEntryManager.setUpWithPresenter(mPresenter, mListContainer, mCallback, mHeadsUpManager);
|
||||
mEntryManager.setNotificationClicker(mock(NotificationClicker.class));
|
||||
|
||||
setUserSentiment(mEntry.key, NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user