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

Commit f75019b8 authored by Selim Cinek's avatar Selim Cinek Committed by Android (Google) Code Review
Browse files

Merge "Keep notification when sending smart reply." into pi-dev

parents f9491caf 8cc15d2e
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -983,6 +983,17 @@ public class Notification implements Parcelable
     */
    public static final String EXTRA_SHOW_REMOTE_INPUT_SPINNER = "android.remoteInputSpinner";

    /**
     * {@link #extras} key: boolean as supplied to
     * {@link Builder#setHideSmartReplies(boolean)}.
     *
     * If set to true, then any smart reply buttons will be hidden.
     *
     * @see Builder#setHideSmartReplies(boolean)
     * @hide
     */
    public static final String EXTRA_HIDE_SMART_REPLIES = "android.hideSmartReplies";

    /**
     * {@link #extras} key: this is a small piece of additional text as supplied to
     * {@link Builder#setContentInfo(CharSequence)}.
@@ -3594,6 +3605,15 @@ public class Notification implements Parcelable
            return this;
        }

        /**
         * Sets whether smart reply buttons should be hidden.
         * @hide
         */
        public Builder setHideSmartReplies(boolean hideSmartReplies) {
            mN.extras.putBoolean(EXTRA_HIDE_SMART_REPLIES, hideSmartReplies);
            return this;
        }

        /**
         * Sets the number of items this notification represents. May be displayed as a badge count
         * for Launchers that support badging.
+7 −0
Original line number Diff line number Diff line
@@ -1384,6 +1384,13 @@ public class NotificationContentView extends FrameLayout {
            smartReplyContainer.setVisibility(View.GONE);
            return null;
        }
        // If we are keeping the notification around while sending we don't want to add the buttons.
        boolean hideSmartReplies = entry.notification.getNotification()
                .extras.getBoolean(Notification.EXTRA_HIDE_SMART_REPLIES, false);
        if (hideSmartReplies) {
            smartReplyContainer.setVisibility(View.GONE);
            return null;
        }
        SmartReplyView smartReplyView = null;
        if (smartReplyContainer.getChildCount() == 0) {
            smartReplyView = SmartReplyView.inflate(mContext, smartReplyContainer);
+82 −11
Original line number Diff line number Diff line
@@ -113,6 +113,8 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
            Dependency.get(ForegroundServiceController.class);
    protected final NotificationListener mNotificationListener =
            Dependency.get(NotificationListener.class);
    private final SmartReplyController mSmartReplyController =
            Dependency.get(SmartReplyController.class);

    protected IStatusBarService mBarService;
    protected NotificationPresenter mPresenter;
@@ -127,6 +129,13 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
    protected boolean mDisableNotificationAlerts;
    protected NotificationListContainer mListContainer;
    private ExpandableNotificationRow.OnAppOpsClickListener mOnAppOpsClickListener;
    /**
     * Notifications with keys in this set are not actually around anymore. We kept them around
     * when they were canceled in response to a remote input interaction. This allows us to show
     * what you replied and allows you to continue typing into it.
     */
    private final ArraySet<String> mKeysKeptForRemoteInput = new ArraySet<>();


    private final class NotificationClicker implements View.OnClickListener {

@@ -220,6 +229,8 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
        }
        pw.print("  mUseHeadsUp=");
        pw.println(mUseHeadsUp);
        pw.print("  mKeysKeptForRemoteInput: ");
        pw.println(mKeysKeptForRemoteInput);
    }

    public NotificationEntryManager(Context context) {
@@ -374,6 +385,12 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
        final NotificationVisibility nv = NotificationVisibility.obtain(n.getKey(), rank, count,
                true);
        NotificationData.Entry entry = mNotificationData.get(n.getKey());

        if (FORCE_REMOTE_INPUT_HISTORY
                && mKeysKeptForRemoteInput.contains(n.getKey())) {
            mKeysKeptForRemoteInput.remove(n.getKey());
        }

        mRemoteInputManager.onPerformRemoveNotification(n, entry);
        final String pkg = n.getPackageName();
        final String tag = n.getTag();
@@ -491,10 +508,35 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
            }
            if (updated) {
                Log.w(TAG, "Keeping notification around after sending remote input "+ entry.key);
                mRemoteInputManager.getKeysKeptForRemoteInput().add(entry.key);
                addKeyKeptForRemoteInput(entry.key);
                return;
            }
        }

        if (FORCE_REMOTE_INPUT_HISTORY
                && shouldKeepForSmartReply(entry)
                && entry.row != null && !entry.row.isDismissed()) {
            // Turn off the spinner and hide buttons when an app cancels the notification.
            StatusBarNotification newSbn = rebuildNotificationForCanceledSmartReplies(entry);
            boolean updated = false;
            try {
                updateNotificationInternal(newSbn, null);
                updated = true;
            } catch (InflationException e) {
                // Ignore just don't keep the notification around.
            }
            // Treat the reply as longer sending.
            mSmartReplyController.stopSending(entry);
            if (updated) {
                Log.w(TAG, "Keeping notification around after sending smart reply " + entry.key);
                addKeyKeptForRemoteInput(entry.key);
                return;
            }
        }

        // Actually removing notification so smart reply controller can forget about it.
        mSmartReplyController.stopSending(entry);

        if (deferRemoval) {
            mLatestRankingMap = ranking;
            mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key));
@@ -536,6 +578,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.

        Notification.Builder b = Notification.Builder
                .recoverBuilder(mContext, sbn.getNotification().clone());
        if (remoteInputText != null) {
            CharSequence[] oldHistory = sbn.getNotification().extras
                    .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
            CharSequence[] newHistory;
@@ -547,7 +590,9 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
            }
            newHistory[0] = String.valueOf(remoteInputText);
            b.setRemoteInputHistory(newHistory);
        }
        b.setShowRemoteInputSpinner(showSpinner);
        b.setHideSmartReplies(true);

        Notification newNotification = b.build();

@@ -563,6 +608,17 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
        return newSbn;
    }

    @VisibleForTesting
    StatusBarNotification rebuildNotificationForCanceledSmartReplies(
            NotificationData.Entry entry) {
        return rebuildNotificationWithRemoteInput(entry, null /* remoteInputTest */,
                false /* showSpinner */);
    }

    private boolean shouldKeepForSmartReply(NotificationData.Entry entry) {
        return entry != null && mSmartReplyController.isSendingSmartReply(entry.key);
    }

    private boolean shouldKeepForRemoteInput(NotificationData.Entry entry) {
        if (entry == null) {
            return false;
@@ -792,6 +848,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
        }
        mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
        mRemoteInputManager.onUpdateNotification(entry);
        mSmartReplyController.stopSending(entry);

        if (key.equals(mGutsManager.getKeyToRemoveOnGutsClosed())) {
            mGutsManager.setKeyToRemoveOnGutsClosed(null);
@@ -955,6 +1012,20 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
        return mHeadsUpManager.isHeadsUp(key);
    }

    public boolean isNotificationKeptForRemoteInput(String key) {
        return mKeysKeptForRemoteInput.contains(key);
    }

    public void removeKeyKeptForRemoteInput(String key) {
        mKeysKeptForRemoteInput.remove(key);
    }

    public void addKeyKeptForRemoteInput(String key) {
        if (FORCE_REMOTE_INPUT_HISTORY) {
            mKeysKeptForRemoteInput.add(key);
        }
    }

    /**
     * Callback for NotificationEntryManager.
     */
+1 −1
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ public class NotificationListener extends NotificationListenerWithPlugins {
            mPresenter.getHandler().post(() -> {
                processForRemoteInput(sbn.getNotification(), mContext);
                String key = sbn.getKey();
                mRemoteInputManager.getKeysKeptForRemoteInput().remove(key);
                mEntryManager.removeKeyKeptForRemoteInput(key);
                boolean isUpdate =
                        mEntryManager.getNotificationData().get(key) != null;
                // In case we don't allow child notifications, we ignore children of
+2 −17
Original line number Diff line number Diff line
@@ -77,12 +77,6 @@ public class NotificationRemoteInputManager implements Dumpable {
    protected final NotificationLockscreenUserManager mLockscreenUserManager =
            Dependency.get(NotificationLockscreenUserManager.class);

    /**
     * Notifications with keys in this set are not actually around anymore. We kept them around
     * when they were canceled in response to a remote input interaction. This allows us to show
     * what you replied and allows you to continue typing into it.
     */
    protected final ArraySet<String> mKeysKeptForRemoteInput = new ArraySet<>();
    protected final Context mContext;
    private final UserManager mUserManager;

@@ -290,7 +284,8 @@ public class NotificationRemoteInputManager implements Dumpable {
        mRemoteInputController.addCallback(new RemoteInputController.Callback() {
            @Override
            public void onRemoteInputSent(NotificationData.Entry entry) {
                if (FORCE_REMOTE_INPUT_HISTORY && mKeysKeptForRemoteInput.contains(entry.key)) {
                if (FORCE_REMOTE_INPUT_HISTORY
                        && mEntryManager.isNotificationKeptForRemoteInput(entry.key)) {
                    mEntryManager.removeNotification(entry.key, null);
                } else if (mRemoteInputEntriesToRemoveOnCollapse.contains(entry)) {
                    // We're currently holding onto this notification, but from the apps point of
@@ -340,10 +335,6 @@ public class NotificationRemoteInputManager implements Dumpable {
        if (mRemoteInputController.isRemoteInputActive(entry)) {
            mRemoteInputController.removeRemoteInput(entry, null);
        }
        if (FORCE_REMOTE_INPUT_HISTORY
                && mKeysKeptForRemoteInput.contains(n.getKey())) {
            mKeysKeptForRemoteInput.remove(n.getKey());
        }
    }

    public void removeRemoteInputEntriesKeptUntilCollapsed() {
@@ -368,8 +359,6 @@ public class NotificationRemoteInputManager implements Dumpable {
        pw.println("NotificationRemoteInputManager state:");
        pw.print("  mRemoteInputEntriesToRemoveOnCollapse: ");
        pw.println(mRemoteInputEntriesToRemoveOnCollapse);
        pw.print("  mKeysKeptForRemoteInput: ");
        pw.println(mKeysKeptForRemoteInput);
    }

    public void bindRow(ExpandableNotificationRow row) {
@@ -377,10 +366,6 @@ public class NotificationRemoteInputManager implements Dumpable {
        row.setRemoteViewClickHandler(mOnClickHandler);
    }

    public Set<String> getKeysKeptForRemoteInput() {
        return mKeysKeptForRemoteInput;
    }

    @VisibleForTesting
    public Set<NotificationData.Entry> getRemoteInputEntriesToRemoveOnCollapse() {
        return mRemoteInputEntriesToRemoveOnCollapse;
Loading