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

Commit 202f25d6 authored by Tony Mak's avatar Tony Mak
Browse files

onNotificationExpansionChanged is called only when the expansion change...

is visible to users.

For example, if the notification is expanded in the background,
onNotificationExpansionChanged will be called only when the expanded
notification is visible to users.

Reason: we should only care about expansion change that is visible
to users, and at the moment that it is shown to user.
This also allows us to determine "has been visually expanded"
easily. With this change, our NotificationAssistantService can know
whether a notification has been visually expanded and calculate the CTR
of smart actions accordingly.

This should not break existing stuff in NMS.onNotificationExpansionChanged
because codes there checked isUserAction == True anyway,
which means the change must be also visible to users.

BUG: 120803809

Test: atest ExtServicesUnitTest
Test: atest ExpansionStateLoggerTest
Test: Manual test, try to expand and collapse notification.

Change-Id: Ibc6f939b2560b845de6a8a35b4557423b8a074f7
parent f6f46ce6
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -173,7 +173,8 @@ public abstract class NotificationAssistantService extends NotificationListenerS
    }

    /**
     * Implement this to know when a notification is expanded / collapsed.
     * Implement this to know when a notification change (expanded / collapsed) is visible to user.
     *
     * @param key the notification key
     * @param isUserAction whether the expanded change is caused by user action.
     * @param isExpanded whether the notification is expanded.
+0 −1
Original line number Diff line number Diff line
@@ -344,7 +344,6 @@ public class Assistant extends NotificationAssistantService {
                if (entry != null) {
                    entry.setSeen();
                    mAgingHelper.onNotificationSeen(entry);
                    mSmartActionsHelper.onNotificationSeen(entry);
                }
            }
        } catch (Throwable e) {
+0 −4
Original line number Diff line number Diff line
@@ -236,10 +236,6 @@ public class NotificationEntry {
        return mSeen;
    }

    public boolean isExpanded() {
        return mExpanded;
    }

    public boolean isShowActionEventLogged() {
        return mIsShowActionEventLogged;
    }
+17 −29
Original line number Diff line number Diff line
@@ -152,18 +152,26 @@ public class SmartActionsHelper {
        return replies;
    }

    void onNotificationSeen(@NonNull NotificationEntry entry) {
        if (entry.isExpanded()) {
            maybeSendActionShownEvent(entry);
        }
    }

    void onNotificationExpansionChanged(@NonNull NotificationEntry entry, boolean isUserAction,
            boolean isExpanded) {
        // Notification can be expanded in the background, and thus the isUserAction check.
        if (isUserAction && isExpanded) {
            maybeSendActionShownEvent(entry);
        if (!isExpanded) {
            return;
        }
        String resultId = mNotificationKeyToResultIdCache.get(entry.getSbn().getKey());
        if (resultId == null) {
            return;
        }
        // Only report if this is the first time the user sees these suggestions.
        if (entry.isShowActionEventLogged()) {
            return;
        }
        entry.setShowActionEventLogged();
        TextClassifierEvent textClassifierEvent =
                createTextClassifierEventBuilder(TextClassifierEvent.TYPE_ACTIONS_SHOWN,
                        resultId)
                        .build();
        // TODO: If possible, report which replies / actions are actually seen by user.
        mTextClassifier.onTextClassifierEvent(textClassifierEvent);
    }

    void onNotificationDirectReplied(@NonNull String key) {
@@ -234,26 +242,6 @@ public class SmartActionsHelper {
                .setResultId(resultId);
    }

    private void maybeSendActionShownEvent(@NonNull NotificationEntry entry) {
        if (mTextClassifier == null) {
            return;
        }
        String resultId = mNotificationKeyToResultIdCache.get(entry.getSbn().getKey());
        if (resultId == null) {
            return;
        }
        // Only report if this is the first time the user sees these suggestions.
        if (entry.isShowActionEventLogged()) {
            return;
        }
        entry.setShowActionEventLogged();
        TextClassifierEvent textClassifierEvent =
                createTextClassifierEventBuilder(TextClassifierEvent.TYPE_ACTIONS_SHOWN, resultId)
                        .build();
        // TODO: If possible, report which replies / actions are actually seen by user.
        mTextClassifier.onTextClassifierEvent(textClassifierEvent);
    }

    /**
     * Returns whether a notification is eligible for action adjustments.
     *
+3 −5
Original line number Diff line number Diff line
@@ -273,24 +273,22 @@ public class SmartActionHelperTest {
        final String message = "Where are you?";
        Notification notification = mNotificationBuilder.setContentText(message).build();
        when(mNotificationEntry.getNotification()).thenReturn(notification);
        when(mNotificationEntry.isExpanded()).thenReturn(false);

        mSmartActionsHelper.suggestReplies(mNotificationEntry);
        mSmartActionsHelper.onNotificationSeen(mNotificationEntry);
        mSmartActionsHelper.onNotificationExpansionChanged(mNotificationEntry, false, false);

        verify(mTextClassifier, never()).onTextClassifierEvent(
                Mockito.any(TextClassifierEvent.class));
    }

    @Test
    public void testOnNotificationsSeen_expanded() {
    public void testOnNotifications_expanded() {
        final String message = "Where are you?";
        Notification notification = mNotificationBuilder.setContentText(message).build();
        when(mNotificationEntry.getNotification()).thenReturn(notification);
        when(mNotificationEntry.isExpanded()).thenReturn(true);

        mSmartActionsHelper.suggestReplies(mNotificationEntry);
        mSmartActionsHelper.onNotificationSeen(mNotificationEntry);
        mSmartActionsHelper.onNotificationExpansionChanged(mNotificationEntry, false, true);

        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
                ArgumentCaptor.forClass(TextClassifierEvent.class);
Loading