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

Commit 8cfe436b authored by Selim Cinek's avatar Selim Cinek Committed by android-build-merger
Browse files

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

am: f75019b8

Change-Id: Idb981e0977880c6bf47267b4ecef793adad3e6d3
parents 4c7cb790 f75019b8
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