Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a01520b3 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Create a shim for StatusBarManager click methods" into rvc-dev

parents defcfd0b 9b2a480c
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -23,10 +23,13 @@ import android.os.Looper;
import android.util.ArraySet;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.statusbar.NotificationInteractionTracker;
import com.android.systemui.statusbar.NotificationLifetimeExtender;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.util.time.SystemClock;

import javax.inject.Inject;

/**
 * Extends the lifetime of foreground notification services such that they show for at least
 * five seconds
@@ -41,9 +44,14 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx
    private ArraySet<NotificationEntry> mManagedEntries = new ArraySet<>();
    private Handler mHandler = new Handler(Looper.getMainLooper());
    private final SystemClock mSystemClock;
    private final NotificationInteractionTracker mInteractionTracker;

    public ForegroundServiceLifetimeExtender(SystemClock systemClock) {
    @Inject
    public ForegroundServiceLifetimeExtender(
            NotificationInteractionTracker interactionTracker,
            SystemClock systemClock) {
        mSystemClock = systemClock;
        mInteractionTracker = interactionTracker;
    }

    @Override
@@ -58,8 +66,9 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx
            return false;
        }

        long currentTime = mSystemClock.uptimeMillis();
        return currentTime - entry.getCreationTime() < MIN_FGS_TIME_MS;
        boolean hasInteracted = mInteractionTracker.hasUserInteractedWith(entry.getKey());
        long aliveTime = mSystemClock.uptimeMillis() - entry.getCreationTime();
        return aliveTime < MIN_FGS_TIME_MS && !hasInteracted;
    }

    @Override
+2 −2
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ public class ForegroundServiceNotificationListener {
            ForegroundServiceController foregroundServiceController,
            NotificationEntryManager notificationEntryManager,
            NotifPipeline notifPipeline,
            ForegroundServiceLifetimeExtender fgsLifetimeExtender,
            SystemClock systemClock) {
        mContext = context;
        mForegroundServiceController = foregroundServiceController;
@@ -78,8 +79,7 @@ public class ForegroundServiceNotificationListener {
                removeNotification(entry.getSbn());
            }
        });
        mEntryManager.addNotificationLifetimeExtender(
                new ForegroundServiceLifetimeExtender(systemClock));
        mEntryManager.addNotificationLifetimeExtender(fgsLifetimeExtender);

        notifPipeline.addCollectionListener(new NotifCollectionListener() {
            @Override
+87 −0
Original line number Diff line number Diff line
package com.android.systemui.statusbar

import android.app.Notification
import android.os.RemoteException
import com.android.internal.statusbar.IStatusBarService
import com.android.internal.statusbar.NotificationVisibility
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.util.Assert
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Class to shim calls to IStatusBarManager#onNotificationClick/#onNotificationActionClick that
 * allow an in-process notification to go out (e.g., for tracking interactions) as well as
 * sending the messages along to system server.
 *
 * NOTE: this class eats exceptions from system server, as no current client of these APIs cares
 * about errors
 */
@Singleton
public class NotificationClickNotifier @Inject constructor(
    val barService: IStatusBarService,
    @Main val mainExecutor: Executor
) {
    val listeners = mutableListOf<NotificationInteractionListener>()

    fun addNotificationInteractionListener(listener: NotificationInteractionListener) {
        Assert.isMainThread()
        listeners.add(listener)
    }

    fun removeNotificationInteractionListener(listener: NotificationInteractionListener) {
        Assert.isMainThread()
        listeners.remove(listener)
    }

    private fun notifyListenersAboutInteraction(key: String) {
        for (l in listeners) {
            l.onNotificationInteraction(key)
        }
    }

    fun onNotificationActionClick(
        key: String,
        actionIndex: Int,
        action: Notification.Action,
        visibility: NotificationVisibility,
        generatedByAssistant: Boolean
    ) {
        try {
            barService.onNotificationActionClick(
                    key, actionIndex, action, visibility, generatedByAssistant)
        } catch (e: RemoteException) {
            // nothing
        }

        mainExecutor.execute {
            notifyListenersAboutInteraction(key)
        }
    }

    fun onNotificationClick(
        key: String,
        visibility: NotificationVisibility
    ) {
        try {
            barService.onNotificationClick(key, visibility)
        } catch (e: RemoteException) {
            // nothing
        }

        mainExecutor.execute {
            notifyListenersAboutInteraction(key)
        }
    }
}

/**
 * Interface for listeners to get notified when a notification is interacted with via a click or
 * interaction with remote input or actions
 */
interface NotificationInteractionListener {
    fun onNotificationInteraction(key: String)
}

private const val TAG = "NotificationClickNotifier"
+40 −0
Original line number Diff line number Diff line
package com.android.systemui.statusbar

import com.android.systemui.statusbar.notification.NotificationEntryManager
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Class to track user interaction with notifications. It's a glorified map of key : bool that can
 * merge multiple "user interacted with notification" signals into a single place.
 */
@Singleton
class NotificationInteractionTracker @Inject constructor(
    private val clicker: NotificationClickNotifier,
    private val entryManager: NotificationEntryManager
) : NotifCollectionListener, NotificationInteractionListener {
    private val interactions = mutableMapOf<String, Boolean>()

    init {
        clicker.addNotificationInteractionListener(this)
        entryManager.addCollectionListener(this)
    }

    fun hasUserInteractedWith(key: String): Boolean = key in interactions

    override fun onEntryAdded(entry: NotificationEntry) {
        interactions[entry.key] = false
    }

    override fun onEntryCleanUp(entry: NotificationEntry) {
        interactions.remove(entry.key)
    }

    override fun onNotificationInteraction(key: String) {
        interactions[key] = true
    }
}

private const val TAG = "NotificationInteractionTracker"
+4 −10
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ import android.content.IntentSender;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -43,7 +42,6 @@ import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;

import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -92,9 +90,9 @@ public class NotificationLockscreenUserManagerImpl implements
    private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray();
    private final SparseBooleanArray mUsersAllowingNotifications = new SparseBooleanArray();
    private final UserManager mUserManager;
    private final IStatusBarService mBarService;
    private final List<UserChangedListener> mListeners = new ArrayList<>();
    private final BroadcastDispatcher mBroadcastDispatcher;
    private final NotificationClickNotifier mClickNotifier;

    private boolean mShowLockscreenNotifications;
    private boolean mAllowLockscreenRemoteInput;
@@ -170,11 +168,7 @@ public class NotificationLockscreenUserManagerImpl implements
                        final NotificationVisibility nv = NotificationVisibility.obtain(
                                notificationKey,
                                rank, count, true, location);
                        try {
                            mBarService.onNotificationClick(notificationKey, nv);
                        } catch (RemoteException exception) {
                            /* ignore */
                        }
                        mClickNotifier.onNotificationClick(notificationKey, nv);
                    }
                    break;
            }
@@ -203,7 +197,7 @@ public class NotificationLockscreenUserManagerImpl implements
            BroadcastDispatcher broadcastDispatcher,
            DevicePolicyManager devicePolicyManager,
            UserManager userManager,
            IStatusBarService iStatusBarService,
            NotificationClickNotifier clickNotifier,
            KeyguardManager keyguardManager,
            StatusBarStateController statusBarStateController,
            @Main Handler mainHandler,
@@ -214,7 +208,7 @@ public class NotificationLockscreenUserManagerImpl implements
        mDevicePolicyManager = devicePolicyManager;
        mUserManager = userManager;
        mCurrentUserId = ActivityManager.getCurrentUser();
        mBarService = iStatusBarService;
        mClickNotifier = clickNotifier;
        statusBarStateController.addCallback(this);
        mLockPatternUtils = new LockPatternUtils(context);
        mKeyguardManager = keyguardManager;
Loading