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

Commit 8f330fef authored by Jeff DeCew's avatar Jeff DeCew Committed by Android (Google) Code Review
Browse files

Merge changes from topic "b203938360_remote_input"

* changes:
  New Pipeline: Remote Input 4/4: Add RemoteInputCoordinator
  New Pipeline: Remote Input 3/4: Extract notification rebuilder methods to a utility
  New Pipeline: Remote Input 2/4: Add ability to internally update notifications
  New Pipeline: Remote Input 1/4: Extract legacy pipeline logic within NotificationRemoteInputManager
parents 2fd0cc3f f20d265c
Loading
Loading
Loading
Loading
+328 −269

File changed.

Preview size limit exceeded, changes collapsed.

+3 −0
Original line number Diff line number Diff line
@@ -299,6 +299,9 @@ public class RemoteInputController {
        default void onRemoteInputSent(NotificationEntry entry) {}
    }

    /**
     * This is a delegate which implements some view controller pieces of the remote input process
     */
    public interface Delegate {
        /**
         * Activate remote input if necessary.
+141 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.statusbar;

import android.annotation.NonNull;
import android.app.Notification;
import android.app.RemoteInputHistoryItem;
import android.content.Context;
import android.net.Uri;
import android.os.Parcelable;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;

import java.util.Arrays;
import java.util.stream.Stream;

import javax.inject.Inject;

/**
 * A helper class which will augment the notifications using arguments and other information
 * accessible to the entry in order to provide intermediate remote input states.
 */
@SysUISingleton
public class RemoteInputNotificationRebuilder {

    private final Context mContext;

    @Inject
    RemoteInputNotificationRebuilder(Context context) {
        mContext = context;
    }

    /**
     * When a smart reply is sent off to the app, we insert the text into the remote input history,
     * and show a spinner to indicate that the app has yet to respond.
     */
    @NonNull
    public StatusBarNotification rebuildForSendingSmartReply(NotificationEntry entry,
            CharSequence reply) {
        return rebuildWithRemoteInputInserted(entry, reply,
                true /* showSpinner */,
                null /* mimeType */, null /* uri */);
    }

    /**
     * When the app cancels a notification in response to a smart reply, we remove the spinner
     * and leave the previously-added reply.  This is the lifetime-extended appearance of the
     * notification.
     */
    @NonNull
    public StatusBarNotification rebuildForCanceledSmartReplies(
            NotificationEntry entry) {
        return rebuildWithRemoteInputInserted(entry, null /* remoteInputTest */,
                false /* showSpinner */, null /* mimeType */, null /* uri */);
    }

    /**
     * When the app cancels a notification in response to a remote input reply, we update the
     * notification with the reply text and/or attachment. This is the lifetime-extended
     * appearance of the notification.
     */
    @NonNull
    public StatusBarNotification rebuildForRemoteInputReply(NotificationEntry entry) {
        CharSequence remoteInputText = entry.remoteInputText;
        if (TextUtils.isEmpty(remoteInputText)) {
            remoteInputText = entry.remoteInputTextWhenReset;
        }
        String remoteInputMimeType = entry.remoteInputMimeType;
        Uri remoteInputUri = entry.remoteInputUri;
        StatusBarNotification newSbn = rebuildWithRemoteInputInserted(entry,
                remoteInputText, false /* showSpinner */, remoteInputMimeType,
                remoteInputUri);
        return newSbn;
    }

    /** Inner method for generating the SBN */
    @VisibleForTesting
    @NonNull
    StatusBarNotification rebuildWithRemoteInputInserted(NotificationEntry entry,
            CharSequence remoteInputText, boolean showSpinner, String mimeType, Uri uri) {
        StatusBarNotification sbn = entry.getSbn();

        Notification.Builder b = Notification.Builder
                .recoverBuilder(mContext, sbn.getNotification().clone());
        if (remoteInputText != null || uri != null) {
            RemoteInputHistoryItem newItem = uri != null
                    ? new RemoteInputHistoryItem(mimeType, uri, remoteInputText)
                    : new RemoteInputHistoryItem(remoteInputText);
            Parcelable[] oldHistoryItems = sbn.getNotification().extras
                    .getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS);
            RemoteInputHistoryItem[] newHistoryItems = oldHistoryItems != null
                    ? Stream.concat(
                    Stream.of(newItem),
                    Arrays.stream(oldHistoryItems).map(p -> (RemoteInputHistoryItem) p))
                    .toArray(RemoteInputHistoryItem[]::new)
                    : new RemoteInputHistoryItem[] { newItem };
            b.setRemoteInputHistory(newHistoryItems);
        }
        b.setShowRemoteInputSpinner(showSpinner);
        b.setHideSmartReplies(true);

        Notification newNotification = b.build();

        // Undo any compatibility view inflation
        newNotification.contentView = sbn.getNotification().contentView;
        newNotification.bigContentView = sbn.getNotification().bigContentView;
        newNotification.headsUpContentView = sbn.getNotification().headsUpContentView;

        return new StatusBarNotification(
                sbn.getPackageName(),
                sbn.getOpPkg(),
                sbn.getId(),
                sbn.getTag(),
                sbn.getUid(),
                sbn.getInitialPid(),
                newNotification,
                sbn.getUser(),
                sbn.getOverrideGroupKey(),
                sbn.getPostTime());
    }


}
+5 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
import com.android.systemui.statusbar.RemoteInputNotificationRebuilder;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
@@ -96,9 +97,11 @@ public interface StatusBarDependenciesModule {
    @Provides
    static NotificationRemoteInputManager provideNotificationRemoteInputManager(
            Context context,
            FeatureFlags featureFlags,
            NotificationLockscreenUserManager lockscreenUserManager,
            SmartReplyController smartReplyController,
            NotificationEntryManager notificationEntryManager,
            RemoteInputNotificationRebuilder rebuilder,
            Lazy<Optional<StatusBar>> statusBarOptionalLazy,
            StatusBarStateController statusBarStateController,
            Handler mainHandler,
@@ -108,9 +111,11 @@ public interface StatusBarDependenciesModule {
            DumpManager dumpManager) {
        return new NotificationRemoteInputManager(
                context,
                featureFlags,
                lockscreenUserManager,
                smartReplyController,
                notificationEntryManager,
                rebuilder,
                statusBarOptionalLazy,
                statusBarStateController,
                mainHandler,
+2 −1
Original line number Diff line number Diff line
@@ -689,8 +689,9 @@ public class NotificationEntryManager implements
        for (NotificationEntryListener listener : mNotificationEntryListeners) {
            listener.onPreEntryUpdated(entry);
        }
        final boolean fromSystem = ranking != null;
        for (NotifCollectionListener listener : mNotifCollectionListeners) {
            listener.onEntryUpdated(entry);
            listener.onEntryUpdated(entry, fromSystem);
        }

        if (!mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
Loading