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

Commit ce68fef7 authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Move action click logging to the background

and simplify it. One of the binder calls has been removed,
and the other is now called on the background thread. The
background logging has also been enhanced so we don't lose
debugability.

See bug for examples of the new logging

Test: Performed the actions that call the ActionClickLogger
methods, and validated the logs in a BR
Test: NotificationManagerServiceTest
Fixes: 281512997

Change-Id: I10fafcb1003848500d4dca20e9fddab34fe84772
parent f86743bf
Loading
Loading
Loading
Loading
+25 −13
Original line number Original line Diff line number Diff line
@@ -31,56 +31,68 @@ class ActionClickLogger @Inject constructor(
) {
) {
    fun logInitialClick(
    fun logInitialClick(
        entry: NotificationEntry?,
        entry: NotificationEntry?,
        index: Integer?,
        pendingIntent: PendingIntent
        pendingIntent: PendingIntent
    ) {
    ) {
        buffer.log(TAG, LogLevel.DEBUG, {
        buffer.log(TAG, LogLevel.DEBUG, {
            str1 = entry?.key
            str1 = entry?.key
            str2 = entry?.ranking?.channel?.id
            str2 = entry?.ranking?.channel?.id
            str3 = pendingIntent.intent.toString()
            str3 = pendingIntent.toString()
            int1 = index?.toInt() ?: Int.MIN_VALUE
        }, {
        }, {
            "ACTION CLICK $str1 (channel=$str2) for pending intent $str3"
            "ACTION CLICK $str1 (channel=$str2) for pending intent $str3 at index $int1"
        })
        })
    }
    }


    fun logRemoteInputWasHandled(
    fun logRemoteInputWasHandled(
        entry: NotificationEntry?
        entry: NotificationEntry?,
        index: Int?
    ) {
    ) {
        buffer.log(TAG, LogLevel.DEBUG, {
        buffer.log(TAG, LogLevel.DEBUG, {
            str1 = entry?.key
            str1 = entry?.key
            int1 = index ?: Int.MIN_VALUE
        }, {
        }, {
            "  [Action click] Triggered remote input (for $str1))"
            "  [Action click] Triggered remote input (for $str1) at index $int1"
        })
        })
    }
    }


    fun logStartingIntentWithDefaultHandler(
    fun logStartingIntentWithDefaultHandler(
        entry: NotificationEntry?,
        entry: NotificationEntry?,
        pendingIntent: PendingIntent
        pendingIntent: PendingIntent,
        index: Int?
    ) {
    ) {
        buffer.log(TAG, LogLevel.DEBUG, {
        buffer.log(TAG, LogLevel.DEBUG, {
            str1 = entry?.key
            str1 = entry?.key
            str2 = pendingIntent.intent.toString()
            str2 = pendingIntent.toString()
            int1 = index ?: Int.MIN_VALUE
        }, {
        }, {
            "  [Action click] Launching intent $str2 via default handler (for $str1)"
            "  [Action click] Launching intent $str2 via default handler (for $str1 at index $int1)"
        })
        })
    }
    }


    fun logWaitingToCloseKeyguard(
    fun logWaitingToCloseKeyguard(
        pendingIntent: PendingIntent
        pendingIntent: PendingIntent,
        index: Int?
    ) {
    ) {
        buffer.log(TAG, LogLevel.DEBUG, {
        buffer.log(TAG, LogLevel.DEBUG, {
            str1 = pendingIntent.intent.toString()
            str1 = pendingIntent.toString()
            int1 = index ?: Int.MIN_VALUE
        }, {
        }, {
            "  [Action click] Intent $str1 launches an activity, dismissing keyguard first..."
            "  [Action click] Intent $str1 at index $int1 launches an activity, dismissing " +
                    "keyguard first..."
        })
        })
    }
    }


    fun logKeyguardGone(
    fun logKeyguardGone(
        pendingIntent: PendingIntent
        pendingIntent: PendingIntent,
        index: Int?
    ) {
    ) {
        buffer.log(TAG, LogLevel.DEBUG, {
        buffer.log(TAG, LogLevel.DEBUG, {
            str1 = pendingIntent.intent.toString()
            str1 = pendingIntent.toString()
            int1 = index ?: Int.MIN_VALUE
        }, {
        }, {
            "  [Action click] Keyguard dismissed, calling default handler for intent $str1"
            "  [Action click] Keyguard dismissed, calling default handler for intent $str1 at " +
                    "index $int1"
        })
        })
    }
    }
}
}
+11 −7
Original line number Original line Diff line number Diff line
@@ -2,10 +2,12 @@ package com.android.systemui.statusbar


import android.app.Notification
import android.app.Notification
import android.os.RemoteException
import android.os.RemoteException
import android.util.Log
import com.android.internal.statusbar.IStatusBarService
import com.android.internal.statusbar.IStatusBarService
import com.android.internal.statusbar.NotificationVisibility
import com.android.internal.statusbar.NotificationVisibility
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dagger.qualifiers.UiBackground
import com.android.systemui.util.Assert
import com.android.systemui.util.Assert
import java.util.concurrent.Executor
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Inject
@@ -21,7 +23,8 @@ import javax.inject.Inject
@SysUISingleton
@SysUISingleton
public class NotificationClickNotifier @Inject constructor(
public class NotificationClickNotifier @Inject constructor(
    val barService: IStatusBarService,
    val barService: IStatusBarService,
    @Main val mainExecutor: Executor
    @Main val mainExecutor: Executor,
    @UiBackground val backgroundExecutor: Executor
) {
) {
    val listeners = mutableListOf<NotificationInteractionListener>()
    val listeners = mutableListOf<NotificationInteractionListener>()


@@ -48,13 +51,14 @@ public class NotificationClickNotifier @Inject constructor(
        visibility: NotificationVisibility,
        visibility: NotificationVisibility,
        generatedByAssistant: Boolean
        generatedByAssistant: Boolean
    ) {
    ) {
        backgroundExecutor.execute {
            try {
            try {
                barService.onNotificationActionClick(
                barService.onNotificationActionClick(
                        key, actionIndex, action, visibility, generatedByAssistant)
                        key, actionIndex, action, visibility, generatedByAssistant)
            } catch (e: RemoteException) {
            } catch (e: RemoteException) {
                // nothing
                // nothing
            }
            }

        }
        mainExecutor.execute {
        mainExecutor.execute {
            notifyListenersAboutInteraction(key)
            notifyListenersAboutInteraction(key)
        }
        }
+10 −5
Original line number Original line Diff line number Diff line
@@ -119,11 +119,14 @@ public class NotificationRemoteInputManager implements Dumpable {
            mPowerInteractor.wakeUpIfDozing(
            mPowerInteractor.wakeUpIfDozing(
                    "NOTIFICATION_CLICK", PowerManager.WAKE_REASON_GESTURE);
                    "NOTIFICATION_CLICK", PowerManager.WAKE_REASON_GESTURE);


            Integer actionIndex = (Integer)
                    view.getTag(com.android.internal.R.id.notification_action_index_tag);

            final NotificationEntry entry = getNotificationForParent(view.getParent());
            final NotificationEntry entry = getNotificationForParent(view.getParent());
            mLogger.logInitialClick(entry, pendingIntent);
            mLogger.logInitialClick(entry, actionIndex, pendingIntent);


            if (handleRemoteInput(view, pendingIntent)) {
            if (handleRemoteInput(view, pendingIntent)) {
                mLogger.logRemoteInputWasHandled(entry);
                mLogger.logRemoteInputWasHandled(entry, actionIndex);
                return true;
                return true;
            }
            }


@@ -141,9 +144,9 @@ public class NotificationRemoteInputManager implements Dumpable {
            }
            }
            Notification.Action action = getActionFromView(view, entry, pendingIntent);
            Notification.Action action = getActionFromView(view, entry, pendingIntent);
            return mCallback.handleRemoteViewClick(view, pendingIntent,
            return mCallback.handleRemoteViewClick(view, pendingIntent,
                    action == null ? false : action.isAuthenticationRequired(), () -> {
                    action == null ? false : action.isAuthenticationRequired(), actionIndex, () -> {
                    Pair<Intent, ActivityOptions> options = response.getLaunchOptions(view);
                    Pair<Intent, ActivityOptions> options = response.getLaunchOptions(view);
                    mLogger.logStartingIntentWithDefaultHandler(entry, pendingIntent);
                    mLogger.logStartingIntentWithDefaultHandler(entry, pendingIntent, actionIndex);
                    boolean started = RemoteViews.startPendingIntent(view, pendingIntent, options);
                    boolean started = RemoteViews.startPendingIntent(view, pendingIntent, options);
                    if (started) releaseNotificationIfKeptForRemoteInputHistory(entry);
                    if (started) releaseNotificationIfKeptForRemoteInputHistory(entry);
                    return started;
                    return started;
@@ -692,11 +695,13 @@ public class NotificationRemoteInputManager implements Dumpable {
         * @param view
         * @param view
         * @param pendingIntent
         * @param pendingIntent
         * @param appRequestedAuth
         * @param appRequestedAuth
         * @param actionIndex
         * @param defaultHandler
         * @param defaultHandler
         * @return  true iff the click was handled
         * @return  true iff the click was handled
         */
         */
        boolean handleRemoteViewClick(View view, PendingIntent pendingIntent,
        boolean handleRemoteViewClick(View view, PendingIntent pendingIntent,
                boolean appRequestedAuth, ClickHandler defaultHandler);
                boolean appRequestedAuth, @Nullable Integer actionIndex,
                ClickHandler defaultHandler);
    }
    }


    /**
    /**
+5 −3
Original line number Original line Diff line number Diff line
@@ -32,6 +32,8 @@ import android.os.UserHandle;
import android.view.View;
import android.view.View;
import android.view.ViewParent;
import android.view.ViewParent;


import androidx.annotation.Nullable;

import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.Main;
@@ -254,16 +256,16 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks,


    @Override
    @Override
    public boolean handleRemoteViewClick(View view, PendingIntent pendingIntent,
    public boolean handleRemoteViewClick(View view, PendingIntent pendingIntent,
            boolean appRequestedAuth,
            boolean appRequestedAuth, @Nullable Integer actionIndex,
            NotificationRemoteInputManager.ClickHandler defaultHandler) {
            NotificationRemoteInputManager.ClickHandler defaultHandler) {
        final boolean isActivity = pendingIntent.isActivity();
        final boolean isActivity = pendingIntent.isActivity();
        if (isActivity || appRequestedAuth) {
        if (isActivity || appRequestedAuth) {
            mActionClickLogger.logWaitingToCloseKeyguard(pendingIntent);
            mActionClickLogger.logWaitingToCloseKeyguard(pendingIntent, actionIndex);
            final boolean afterKeyguardGone = mActivityIntentHelper
            final boolean afterKeyguardGone = mActivityIntentHelper
                    .wouldPendingLaunchResolverActivity(pendingIntent,
                    .wouldPendingLaunchResolverActivity(pendingIntent,
                            mLockscreenUserManager.getCurrentUserId());
                            mLockscreenUserManager.getCurrentUserId());
            mActivityStarter.dismissKeyguardThenExecute(() -> {
            mActivityStarter.dismissKeyguardThenExecute(() -> {
                mActionClickLogger.logKeyguardGone(pendingIntent);
                mActionClickLogger.logKeyguardGone(pendingIntent, actionIndex);


                try {
                try {
                    ActivityManager.getService().resumeAppSwitches();
                    ActivityManager.getService().resumeAppSwitches();
+1 −1
Original line number Original line Diff line number Diff line
@@ -81,7 +81,7 @@ option java_package com.android.server
# when a notification has been clicked
# when a notification has been clicked
27520 notification_clicked (key|3),(lifespan|1),(freshness|1),(exposure|1),(rank|1),(count|1)
27520 notification_clicked (key|3),(lifespan|1),(freshness|1),(exposure|1),(rank|1),(count|1)
# when a notification action button has been clicked
# when a notification action button has been clicked
27521 notification_action_clicked (key|3),(action_index|1),(lifespan|1),(freshness|1),(exposure|1),(rank|1),(count|1)
27521 notification_action_clicked (key|3),(piIdentifier|3),(pendingIntent|3),(action_index|1),(lifespan|1),(freshness|1),(exposure|1),(rank|1),(count|1)
# when a notification has been canceled
# when a notification has been canceled
27530 notification_canceled (key|3),(reason|1),(lifespan|1),(freshness|1),(exposure|1),(rank|1),(count|1),(listener|3)
27530 notification_canceled (key|3),(reason|1),(lifespan|1),(freshness|1),(exposure|1),(rank|1),(count|1),(listener|3)
# replaces 27510 with a row per notification
# replaces 27510 with a row per notification
Loading