Merge "Extract NotificationClicker from NEM"

This commit is contained in:
TreeHugger Robot
2018-12-18 21:45:52 +00:00
committed by Android (Google) Code Review
4 changed files with 118 additions and 72 deletions

View File

@@ -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);
}
}
}

View File

@@ -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 {

View File

@@ -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));
}
/**

View File

@@ -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);
}