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

Commit b1bd8bde authored by Steven Kester Yuwono's avatar Steven Kester Yuwono
Browse files

If there are system phishing actions, we clear all other (non-phishing) smart...

If there are system phishing actions, we clear all other (non-phishing) smart replies and actions (regardless whether they are app or system generated).

Also added a notification.action not null check before iterating it to suppress remote input actions. Searched the code base and there is a bunch of action not null checks in Notification.java which indicates it can be null.

Flag: EXEMPT bugfix
Test: atest SystemUITests
Bug: 407890979
Change-Id: I8152330cb43eaefa28faa7b8ed3ab8f6ba46d5b5
parent 97a845b6
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -319,14 +319,23 @@ constructor(
                smartActions = SmartActions(systemGeneratedActions, true /* fromAssistant */)
            }
        }
        val hasPhishingAction =
            smartActions?.actions?.any {

        val phishingSystemGeneratedActions =
            entry.smartActions.filter {
                it.isContextual &&
                    it.semanticAction ==
                        Notification.Action.SEMANTIC_ACTION_CONVERSATION_IS_PHISHING
            } ?: false
        var suppressedActions: SuppressedActions? = null
            }
        val hasPhishingAction = phishingSystemGeneratedActions.isNotEmpty()
        if (hasPhishingAction) {
            // If there are system phishing actions, remove all smart replies and other
            // non-phishing smart actions (regardless whether they are app or system generated).
            smartReplies = null
            smartActions = SmartActions(phishingSystemGeneratedActions, true /* fromAssistant */)
        }

        var suppressedActions: SuppressedActions? = null
        if (hasPhishingAction && notification.actions != null) {
            // If there is a phishing action, calculate the indices of the actions with RemoteInput
            //  as those need to be hidden from the view.
            val suppressedActionIndices =
+134 −15
Original line number Diff line number Diff line
@@ -241,7 +241,34 @@ public class InflatedSmartRepliesTest extends SysuiTestCase {
    }

    @Test
    public void chooseSmartRepliesAndActions_sysGeneratedPhishingSmartAction() {
    public void chooseSmartRepliesAndActions_appGenPreferredOverSysGen() {
        CharSequence[] appGenSmartReplies = new String[] {"Reply1", "Reply2"};
        // Pass a null-array as app-generated smart replies, so that we use NAS-generated smart
        // replies.
        List<Notification.Action> appGenSmartActions =
                createActions("Test Action 1", "Test Action 2");
        setupAppGeneratedSuggestions(appGenSmartReplies, appGenSmartActions);

        modifyRanking(mEntry)
                .setSmartReplies(createReplies("Sys Smart Reply 1", "Sys Smart Reply 2"))
                .setSmartActions(createActions("Sys Smart Action 1", "Sys Smart Action 2"))
                .build();

        InflatedSmartReplyState smartReplyState =
                mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry);

        assertThat(smartReplyState.getSmartReplies().choices)
                .containsExactlyElementsIn(Arrays.asList(appGenSmartReplies)).inOrder();
        assertThat(smartReplyState.getSmartReplies().fromAssistant).isFalse();
        assertThat(smartReplyState.getSmartActions().actions)
                .containsExactlyElementsIn(appGenSmartActions).inOrder();
        assertThat(smartReplyState.getSmartActions().fromAssistant).isFalse();
        assertThat(smartReplyState.getSuppressedActions()).isNull();
        assertThat(smartReplyState.getHasPhishingAction()).isFalse();
    }

    @Test
    public void chooseSmartRepliesAndActions_phishingActionsRemovesSysGenSmartRepliesAndActions() {
        // Pass a null-array as app-generated smart replies, so that we use NAS-generated smart
        // actions.
        setupAppGeneratedReplies(null /* smartReplies */);
@@ -253,6 +280,7 @@ public class InflatedSmartRepliesTest extends SysuiTestCase {
        };

        modifyRanking(mEntry)
                .setSmartReplies(createReplies("Sys Smart Reply 1", "Sys Smart Reply 2"))
                .setSmartActions(
                        createAction("Sys Smart Action 1"),
                        createActionBuilder("Sys Smart Action 2")
@@ -265,6 +293,46 @@ public class InflatedSmartRepliesTest extends SysuiTestCase {
        InflatedSmartReplyState smartReplyState =
                mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry);

        assertThat(smartReplyState.getSmartReplies()).isNull();
        assertThat(smartReplyState.getSmartActions().actions)
                .containsExactly(mEntry.getSmartActions().get(1));
        assertThat(smartReplyState.getSmartActions().fromAssistant).isTrue();
        assertThat(smartReplyState.getSuppressedActions()).isNotNull();
        assertThat(smartReplyState.getSuppressedActions().getSuppressedActionIndices())
                .containsExactly(1);
        assertThat(smartReplyState.getHasPhishingAction()).isTrue();
    }

    @Test
    public void chooseSmartRepliesAndActions_phishingActionsRemovesAppGenSmartRepliesAndActions() {
        CharSequence[] smartReplies = new String[] {"Reply1", "Reply2"};
        List<Notification.Action> smartActions =
                createActions("Test Action 1", "Test Action 2");
        setupAppGeneratedSuggestions(smartReplies, smartActions);

        mNotification.actions = new Notification.Action[]{
                createAction("Details"),
                createActionBuilder("Reply").addRemoteInput(
                        new RemoteInput.Builder("key").build()).build()
        };

        modifyRanking(mEntry)
                .setSmartActions(
                        createActionBuilder("Sys Smart Action 1")
                                .setContextual(true)
                                .setSemanticAction(Notification.Action
                                        .SEMANTIC_ACTION_CONVERSATION_IS_PHISHING)
                                .build(),
                        createActionBuilder("Sys Smart Action 2")
                                .setContextual(true)
                                .setSemanticAction(Notification.Action
                                        .SEMANTIC_ACTION_CONVERSATION_IS_PHISHING)
                                .build())
                .build();

        InflatedSmartReplyState smartReplyState =
                mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry);

        assertThat(smartReplyState.getSmartReplies()).isNull();
        assertThat(smartReplyState.getSmartActions().actions)
                .containsExactlyElementsIn(mEntry.getSmartActions()).inOrder();
@@ -276,30 +344,46 @@ public class InflatedSmartRepliesTest extends SysuiTestCase {
    }

    @Test
    public void chooseSmartRepliesAndActions_appGenPreferredOverSysGen() {
        CharSequence[] appGenSmartReplies = new String[] {"Reply1", "Reply2"};
        // Pass a null-array as app-generated smart replies, so that we use NAS-generated smart
        // replies.
        List<Notification.Action> appGenSmartActions =
    public void chooseSmartRepliesAndActions_phishingActionsRemovesAllSmartRepliesAndActions() {
        CharSequence[] smartReplies = new String[] {"Reply1", "Reply2"};
        List<Notification.Action> smartActions =
                createActions("Test Action 1", "Test Action 2");
        setupAppGeneratedSuggestions(appGenSmartReplies, appGenSmartActions);
        setupAppGeneratedSuggestions(smartReplies, smartActions);

        mNotification.actions = new Notification.Action[]{
                createAction("Details"),
                createActionBuilder("Reply").addRemoteInput(
                        new RemoteInput.Builder("key").build()).build()
        };

        modifyRanking(mEntry)
                .setSmartReplies(createReplies("Sys Smart Reply 1", "Sys Smart Reply 2"))
                .setSmartActions(createActions("Sys Smart Action 1", "Sys Smart Action 2"))
                .setSmartActions(
                        createAction("Sys Smart Action 1"),
                        createActionBuilder("Sys Smart Action 2")
                                .setContextual(true)
                                .setSemanticAction(Notification.Action
                                        .SEMANTIC_ACTION_CONVERSATION_IS_PHISHING)
                                .build(),
                        createAction("Sys Smart Action 3"),
                        createActionBuilder("Sys Smart Action 4")
                                .setContextual(true)
                                .setSemanticAction(Notification.Action
                                        .SEMANTIC_ACTION_CONVERSATION_IS_PHISHING)
                                .build())
                .build();

        InflatedSmartReplyState smartReplyState =
                mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry);

        assertThat(smartReplyState.getSmartReplies().choices)
                .containsExactlyElementsIn(Arrays.asList(appGenSmartReplies)).inOrder();
        assertThat(smartReplyState.getSmartReplies().fromAssistant).isFalse();
        assertThat(smartReplyState.getSmartReplies()).isNull();
        assertThat(smartReplyState.getSmartActions().actions)
                .containsExactlyElementsIn(appGenSmartActions).inOrder();
        assertThat(smartReplyState.getSmartActions().fromAssistant).isFalse();
        assertThat(smartReplyState.getSuppressedActions()).isNull();
        assertThat(smartReplyState.getHasPhishingAction()).isFalse();
                .containsExactly(mEntry.getSmartActions().get(1), mEntry.getSmartActions().get(3));
        assertThat(smartReplyState.getSmartActions().fromAssistant).isTrue();
        assertThat(smartReplyState.getSuppressedActions()).isNotNull();
        assertThat(smartReplyState.getSuppressedActions().getSuppressedActionIndices())
                .containsExactly(1);
        assertThat(smartReplyState.getHasPhishingAction()).isTrue();
    }

    @Test
@@ -323,6 +407,41 @@ public class InflatedSmartRepliesTest extends SysuiTestCase {
        assertThat(smartReplyState.getHasPhishingAction()).isFalse();
    }

    @Test
    public void chooseSmartRepliesAndActions_disallowSysGenSmartActions_exceptPhishingActions() {
        // Pass a null-array as app-generated smart replies, so that we use NAS-generated smart
        // actions.
        setupAppGeneratedReplies(null /* smartReplies */, false /* allowSystemGeneratedReplies */);
        when(mNotification.getAllowSystemGeneratedContextualActions()).thenReturn(false);

        modifyRanking(mEntry)
                .setSmartReplies(createReplies("Sys Smart Reply 1", "Sys Smart Reply 2"))
                .setSmartActions(
                        createAction("Sys Smart Action 1"),
                        createActionBuilder("Sys Smart Action 2")
                                .setContextual(true)
                                .setSemanticAction(Notification.Action
                                        .SEMANTIC_ACTION_CONVERSATION_IS_PHISHING)
                                .build(),
                        createAction("Sys Smart Action 3"),
                        createActionBuilder("Sys Smart Action 4")
                                .setContextual(true)
                                .setSemanticAction(Notification.Action
                                        .SEMANTIC_ACTION_CONVERSATION_IS_PHISHING)
                                .build())
                .build();

        InflatedSmartReplyState smartReplyState =
                mSmartReplyStateInflater.chooseSmartRepliesAndActions(mEntry);

        assertThat(smartReplyState.getSmartReplies()).isNull();
        assertThat(smartReplyState.getSmartActions().actions)
                .containsExactly(mEntry.getSmartActions().get(1), mEntry.getSmartActions().get(3));
        assertThat(smartReplyState.getSmartActions().fromAssistant).isTrue();
        assertThat(smartReplyState.getSuppressedActions()).isNull();
        assertThat(smartReplyState.getHasPhishingAction()).isTrue();
    }

    @Test
    public void chooseSmartRepliesAndActions_lockTaskKioskModeEnabled_smartRepliesUnaffected() {
        when(mActivityManagerWrapper.isLockTaskKioskModeActive()).thenReturn(true);