blob: dfdfeaa57c7fad8d2c3404cd78e1abdcb2bdeb5d [file] [log] [blame]
package com.android.car.notification;
import android.car.CarNotConnectedException;
import android.car.drivingstate.CarUxRestrictions;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import java.util.List;
/**
* This class is a bridge to collect signals from the notification and ux restriction services and
* trigger the correct UI updates.
*/
public class NotificationViewController {
private static final String TAG = "NotificationViewControl";
private final CarNotificationView mCarNotificationView;
private final PreprocessingManager mPreprocessingManager;
private final CarNotificationListener mCarNotificationListener;
private CarUxRestrictionManagerWrapper mUxResitrictionListener;
private NotificationDataManager mNotificationDataManager;
private NotificationUpdateHandler mNotificationUpdateHandler = new NotificationUpdateHandler();
private boolean mShowLessImportantNotifications;
private boolean mIsInForeground;
public NotificationViewController(CarNotificationView carNotificationView,
PreprocessingManager preprocessingManager,
CarNotificationListener carNotificationListener,
CarUxRestrictionManagerWrapper uxResitrictionListener,
NotificationDataManager notificationDataManager) {
mCarNotificationView = carNotificationView;
mPreprocessingManager = preprocessingManager;
mCarNotificationListener = carNotificationListener;
mUxResitrictionListener = uxResitrictionListener;
mNotificationDataManager = notificationDataManager;
// Long clicking on the notification center title toggles hiding media, navigation, and
// less important (< IMPORTANCE_DEFAULT) ongoing foreground service notifications.
// This is only available for ENG and USERDEBUG builds.
View view = mCarNotificationView.findViewById(R.id.notification_center_title);
if (view != null && (Build.IS_ENG || Build.IS_USERDEBUG)) {
view.setOnLongClickListener(v -> {
mShowLessImportantNotifications = !mShowLessImportantNotifications;
Toast.makeText(
carNotificationView.getContext(),
"Foreground, navigation and media notifications " + (
mShowLessImportantNotifications ? "ENABLED" : "DISABLED"),
Toast.LENGTH_SHORT).show();
resetNotifications(mShowLessImportantNotifications);
return true;
});
}
}
/**
* Updates UI and registers required listeners
*/
public void enable() {
mCarNotificationListener.setHandler(mNotificationUpdateHandler);
mUxResitrictionListener.setCarNotificationView(mCarNotificationView);
try {
CarUxRestrictions currentRestrictions =
mUxResitrictionListener.getCurrentCarUxRestrictions();
mCarNotificationView.onUxRestrictionsChanged(currentRestrictions);
} catch (CarNotConnectedException e) {
Log.e(TAG, "Car not connected", e);
}
}
/**
* Remove listeners.
*/
public void disable() {
mCarNotificationListener.setHandler(null);
mUxResitrictionListener.setCarNotificationView(null);
}
/**
* Reset the list view. Called when the notification list is not in the foreground.
*/
public void setIsInForeground(boolean isInForeground) {
mIsInForeground = isInForeground;
// Reset and collapse all groups when notification view disappears.
if (!mIsInForeground) {
resetNotifications(mShowLessImportantNotifications);
mCarNotificationView.collapseAllGroups();
}
}
/**
* Reset notifications to the latest state.
*/
private void resetNotifications(boolean showLessImportantNotifications) {
mPreprocessingManager.init(
mCarNotificationListener.getNotifications(),
mCarNotificationListener.getCurrentRanking());
List<NotificationGroup> notificationGroups = mPreprocessingManager.process(
showLessImportantNotifications,
mCarNotificationListener.getNotifications(),
mCarNotificationListener.getCurrentRanking());
mNotificationDataManager.updateUnseenNotification(notificationGroups);
mCarNotificationView.setNotifications(notificationGroups);
}
/**
* Update notifications: no grouping/ranking updates will go through.
* Insertion, deletion and content update will apply immediately.
*/
private void updateNotifications(
boolean showLessImportantNotifications, int what, StatusBarNotification sbn) {
if (mPreprocessingManager.shouldFilter(sbn, mCarNotificationListener.getCurrentRanking())) {
// if the new notification should be filtered out, return early
return;
}
mCarNotificationView.setNotifications(
mPreprocessingManager.updateNotifications(
showLessImportantNotifications,
sbn,
what,
mCarNotificationListener.getCurrentRanking()));
}
private class NotificationUpdateHandler extends Handler {
@Override
public void handleMessage(Message message) {
if (mIsInForeground) {
updateNotifications(
mShowLessImportantNotifications,
message.what,
(StatusBarNotification) message.obj);
} else {
resetNotifications(mShowLessImportantNotifications);
}
}
}
}