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

Commit 1463d83d authored by Gustav Sennton's avatar Gustav Sennton
Browse files

Add a Notifications API for contextual (smart) actions.

With this CL we add a new semantic action to Notification.Action to
represent contextual actions - i.e. actions specific to the current
notification. Contextual actions will be displayed differnently to
regular actions.

If the app itself does not provide smart replies or smart actions the
framework will generate smart replies and actions and put those in the
notification.

The UI for smart actions will be added in a separate CL.

With this CL we also remove a couple of unnecessary fields, namely:
NotificationInflater.mSmartActions
NotificationInflater.AsyncInflationTask.mSmartActions
the actions stored in these fields are stored in
NotificationData.Entry anyway.

Bug: 119010281
Test: write an app adding an Action with the new semantic type and
ensure that (contextual) action doesn't show up with the other actions.
Test: atest SystemUITests

Change-Id: Icd192fe2273b0474729dd4e413e0a6c2d75ff0fa
parent 4d1f5830
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5370,6 +5370,7 @@ package android.app {
    field public static final android.os.Parcelable.Creator<android.app.Notification.Action> CREATOR;
    field public static final int SEMANTIC_ACTION_ARCHIVE = 5; // 0x5
    field public static final int SEMANTIC_ACTION_CALL = 10; // 0xa
    field public static final int SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION = 11; // 0xb
    field public static final int SEMANTIC_ACTION_DELETE = 4; // 0x4
    field public static final int SEMANTIC_ACTION_MARK_AS_READ = 2; // 0x2
    field public static final int SEMANTIC_ACTION_MARK_AS_UNREAD = 3; // 0x3
+29 −4
Original line number Diff line number Diff line
@@ -207,7 +207,8 @@ public class Notification implements Parcelable
    private static final int MAX_REPLY_HISTORY = 5;

    /**
     * Maximum numbers of action buttons in a notification.
     * Maximum number of (generic) action buttons in a notification (contextual action buttons are
     * handled separately).
     * @hide
     */
    public static final int MAX_ACTION_BUTTONS = 3;
@@ -1421,6 +1422,12 @@ public class Notification implements Parcelable
         */
        public static final int SEMANTIC_ACTION_CALL = 10;

        /**
         * {@code SemanticAction}: Contextual action - dependent on the current notification. E.g.
         * open a Map application with an address shown in the notification.
         */
        public static final int SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION = 11;

        private final Bundle mExtras;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
        private Icon mIcon;
@@ -2042,7 +2049,8 @@ public class Notification implements Parcelable
                SEMANTIC_ACTION_UNMUTE,
                SEMANTIC_ACTION_THUMBS_UP,
                SEMANTIC_ACTION_THUMBS_DOWN,
                SEMANTIC_ACTION_CALL
                SEMANTIC_ACTION_CALL,
                SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION
        })
        @Retention(RetentionPolicy.SOURCE)
        public @interface SemanticAction {}
@@ -4962,6 +4970,18 @@ public class Notification implements Parcelable
                    result);
        }

        private static List<Notification.Action> filterOutContextualActions(
                List<Notification.Action> actions) {
            List<Notification.Action> nonContextualActions = new ArrayList<>();
            for (Notification.Action action : actions) {
                if (action.getSemanticAction()
                        != Action.SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION) {
                    nonContextualActions.add(action);
                }
            }
            return nonContextualActions;
        }

        private RemoteViews applyStandardTemplateWithActions(int layoutId,
                StandardTemplateParams p, TemplateBindResult result) {
            RemoteViews big = applyStandardTemplate(layoutId, p, result);
@@ -4970,7 +4990,11 @@ public class Notification implements Parcelable

            boolean validRemoteInput = false;

            int N = mActions.size();
            // In the UI contextual actions appear separately from the standard actions, so we
            // filter them out here.
            List<Notification.Action> nonContextualActions = filterOutContextualActions(mActions);

            int N = nonContextualActions.size();
            boolean emphazisedMode = mN.fullScreenIntent != null && !p.ambient;
            big.setBoolean(R.id.actions, "setEmphasizedMode", emphazisedMode);
            if (N > 0) {
@@ -4979,7 +5003,8 @@ public class Notification implements Parcelable
                big.setViewLayoutMarginBottomDimen(R.id.notification_action_list_margin_target, 0);
                if (N>MAX_ACTION_BUTTONS) N=MAX_ACTION_BUTTONS;
                for (int i=0; i<N; i++) {
                    Action action = mActions.get(i);
                    Action action = nonContextualActions.get(i);

                    boolean actionHasValidInput = hasValidRemoteInput(action);
                    validRemoteInput |= actionHasValidInput;

+4 −3
Original line number Diff line number Diff line
@@ -22,10 +22,10 @@ import android.app.RemoteInput;
import android.graphics.drawable.Icon;
import android.text.TextUtils;

import com.android.systemui.statusbar.notification.NotificationData;

import androidx.annotation.VisibleForTesting;

import com.android.systemui.statusbar.notification.NotificationData;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -53,7 +53,8 @@ public class NotificationUiAdjustment {

    public static NotificationUiAdjustment extractFromNotificationEntry(
            NotificationData.Entry entry) {
        return new NotificationUiAdjustment(entry.key, entry.smartActions, entry.smartReplies);
        return new NotificationUiAdjustment(
                entry.key, entry.systemGeneratedSmartActions, entry.smartReplies);
    }

    public static boolean needReinflate(
+3 −2
Original line number Diff line number Diff line
@@ -114,8 +114,9 @@ public class NotificationData {
        public CharSequence remoteInputText;
        public List<SnoozeCriterion> snoozeCriteria;
        public int userSentiment = Ranking.USER_SENTIMENT_NEUTRAL;
        /** Smart Actions provided by the NotificationAssistantService. */
        @NonNull
        public List<Notification.Action> smartActions = Collections.emptyList();
        public List<Notification.Action> systemGeneratedSmartActions = Collections.emptyList();
        public CharSequence[] smartReplies = new CharSequence[0];

        private int mCachedContrastColor = COLOR_INVALID;
@@ -171,7 +172,7 @@ public class NotificationData {
            importance = ranking.getImportance();
            snoozeCriteria = ranking.getSnoozeCriteria();
            userSentiment = ranking.getUserSentiment();
            smartActions = ranking.getSmartActions() == null
            systemGeneratedSmartActions = ranking.getSmartActions() == null
                    ? Collections.emptyList() : ranking.getSmartActions();
            smartReplies = ranking.getSmartReplies() == null
                    ? new CharSequence[0]
+0 −1
Original line number Diff line number Diff line
@@ -702,7 +702,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
                && !mPresenter.isPresenterFullyCollapsed();
        row.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
        row.setUseIncreasedHeadsUpHeight(useIncreasedHeadsUp);
        row.setSmartActions(entry.smartActions);
        row.setEntry(entry);

        row.updateInflationFlag(FLAG_CONTENT_VIEW_HEADS_UP, shouldHeadsUp(entry));
Loading