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

Commit ae679ca7 authored by Ibrahim Yilmaz's avatar Ibrahim Yilmaz
Browse files

Create data extraction helper for Messaging Layouts

This CL introduces data extraction helper methods and MessagingData which represents the data in MessagingLayouts. MessagingLayouts parse Bundle object and create MessagingData object.

Bug: 289250881
Test: Manual. Check Messaging and Conversation Notif work as is.

Change-Id: I3fcac0317fae5779cad1dd43524444a9783d5ebf
parent 9ac1d7c9
Loading
Loading
Loading
Loading
+27 −57
Original line number Diff line number Diff line
@@ -390,36 +390,37 @@ public class ConversationLayout extends FrameLayout
     */
    @RemotableViewMethod(asyncImpl = "setDataAsync")
    public void setData(Bundle extras) {
        bind(parseMessagingData(extras, /* usePrecomputedText= */ false));
    }

    @NonNull
    private MessagingData parseMessagingData(Bundle extras, boolean usePrecomputedText) {
        Parcelable[] messages = extras.getParcelableArray(Notification.EXTRA_MESSAGES);
        List<Notification.MessagingStyle.Message> newMessages
                = Notification.MessagingStyle.Message.getMessagesFromBundleArray(messages);
        List<Notification.MessagingStyle.Message> newMessages =
                Notification.MessagingStyle.Message.getMessagesFromBundleArray(messages);
        Parcelable[] histMessages = extras.getParcelableArray(Notification.EXTRA_HISTORIC_MESSAGES);
        List<Notification.MessagingStyle.Message> newHistoricMessages
                = Notification.MessagingStyle.Message.getMessagesFromBundleArray(histMessages);
        List<Notification.MessagingStyle.Message> newHistoricMessages =
                Notification.MessagingStyle.Message.getMessagesFromBundleArray(histMessages);

        // mUser now set (would be nice to avoid the side effect but WHATEVER)
        final Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON, Person.class);
        // Append remote input history to newMessages (again, side effect is lame but WHATEVS)
        RemoteInputHistoryItem[] history = (RemoteInputHistoryItem[])
                extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, android.app.RemoteInputHistoryItem.class);
                extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS,
                        RemoteInputHistoryItem.class);
        addRemoteInputHistoryToMessages(newMessages, history);

        boolean showSpinner =
                extras.getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false);
        int unreadCount = extras.getInt(Notification.EXTRA_CONVERSATION_UNREAD_MESSAGE_COUNT);

        // convert MessagingStyle.Message to MessagingMessage, re-using ones from a previous binding
        // if they exist
        final List<MessagingMessage> newMessagingMessages =
                createMessages(newMessages, /* isHistoric= */false,
                        /* usePrecomputedText= */false);
                createMessages(newMessages, /* isHistoric= */false, usePrecomputedText);
        final List<MessagingMessage> newHistoricMessagingMessages =
                createMessages(newHistoricMessages, /* isHistoric= */true,
                        /* usePrecomputedText= */false);
        // bind it, baby
        bindViews(user, showSpinner, unreadCount,
                newMessagingMessages,
                newHistoricMessagingMessages);
                createMessages(newHistoricMessages, /* isHistoric= */true, usePrecomputedText);

        return new MessagingData(user, showSpinner, unreadCount,
                newHistoricMessagingMessages, newMessagingMessages);
    }

    /**
@@ -435,43 +436,17 @@ public class ConversationLayout extends FrameLayout
            return () -> setData(extras);
        }

        Parcelable[] messages = extras.getParcelableArray(Notification.EXTRA_MESSAGES);
        List<Notification.MessagingStyle.Message> newMessages =
                Notification.MessagingStyle.Message.getMessagesFromBundleArray(messages);
        Parcelable[] histMessages = extras.getParcelableArray(Notification.EXTRA_HISTORIC_MESSAGES);
        List<Notification.MessagingStyle.Message> newHistoricMessages =
                Notification.MessagingStyle.Message.getMessagesFromBundleArray(histMessages);

        // mUser now set (would be nice to avoid the side effect but WHATEVER)
        final Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON, Person.class);
        // Append remote input history to newMessages (again, side effect is lame but WHATEVS)
        RemoteInputHistoryItem[] history = (RemoteInputHistoryItem[])
                extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS,
                        android.app.RemoteInputHistoryItem.class);
        addRemoteInputHistoryToMessages(newMessages, history);

        boolean showSpinner =
                extras.getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false);
        int unreadCount = extras.getInt(Notification.EXTRA_CONVERSATION_UNREAD_MESSAGE_COUNT);

        // bind it, baby
        final List<MessagingMessage> newMessagingMessages =
                createMessages(newMessages, /* isHistoric= */false, /* usePrecomputedText= */true);
        final List<MessagingMessage> newHistoricMessagingMessages =
                createMessages(newHistoricMessages, /* isHistoric= */true,
                        /* usePrecomputedText= */true);
        final MessagingData messagingData =
                parseMessagingData(extras, /* usePrecomputedText= */ true);

        return () -> {
            finalizeInflate(newHistoricMessagingMessages);
            finalizeInflate(newMessagingMessages);
            finalizeInflate(messagingData.getHistoricMessagingMessages());
            finalizeInflate(messagingData.getNewMessagingMessages());

            bindViews(user, showSpinner, unreadCount,
                    newMessagingMessages,
                    newHistoricMessagingMessages);
            bind(messagingData);
        };
    }


    /**
     * enable/disable precomputed text usage
     * @hide
@@ -513,17 +488,12 @@ public class ConversationLayout extends FrameLayout
        }
    }

    private void bind(MessagingData messagingData) {
        setUser(messagingData.getUser());
        setUnreadCount(messagingData.getUnreadCount());

    private void bindViews(Person user,
            boolean showSpinner, int unreadCount, List<MessagingMessage> newMessagingMessages,
            List<MessagingMessage> newHistoricMessagingMessages) {
        setUser(user);
        setUnreadCount(unreadCount);
        bind(showSpinner, newMessagingMessages, newHistoricMessagingMessages);
    }

    private void bind(boolean showSpinner, List<MessagingMessage> messages,
            List<MessagingMessage> historicMessages) {
        List<MessagingMessage> messages = messagingData.getNewMessagingMessages();
        List<MessagingMessage> historicMessages = messagingData.getHistoricMessagingMessages();
        // Copy our groups, before they get clobbered
        ArrayList<MessagingGroup> oldGroups = new ArrayList<>(mGroups);

@@ -536,7 +506,7 @@ public class ConversationLayout extends FrameLayout

        // Let's now create the views and reorder them accordingly
        //   side-effect: updates mGroups, mAddedGroups
        createGroupViews(groups, senders, showSpinner);
        createGroupViews(groups, senders, messagingData.getShowSpinner());

        // Let's first check which groups were removed altogether and remove them in one animation
        removeGroups(oldGroups);
+70 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.internal.widget;

import android.app.Person;

import java.util.List;

/**
 * @hide
 */
final class MessagingData {
    private final Person mUser;
    private final boolean mShowSpinner;
    private final List<MessagingMessage> mHistoricMessagingMessages;
    private final List<MessagingMessage> mNewMessagingMessages;
    private final int mUnreadCount;

    MessagingData(Person user, boolean showSpinner,
            List<MessagingMessage> historicMessagingMessages,
            List<MessagingMessage> newMessagingMessages) {
        this(user, showSpinner, /* unreadCount= */0,
                historicMessagingMessages, newMessagingMessages);
    }

    MessagingData(Person user, boolean showSpinner,
            int unreadCount,
            List<MessagingMessage> historicMessagingMessages,
            List<MessagingMessage> newMessagingMessages) {
        mUser = user;
        mShowSpinner = showSpinner;
        mUnreadCount = unreadCount;
        mHistoricMessagingMessages = historicMessagingMessages;
        mNewMessagingMessages = newMessagingMessages;
    }

    public Person getUser() {
        return mUser;
    }

    public boolean getShowSpinner() {
        return mShowSpinner;
    }

    public List<MessagingMessage> getHistoricMessagingMessages() {
        return mHistoricMessagingMessages;
    }

    public List<MessagingMessage> getNewMessagingMessages() {
        return mNewMessagingMessages;
    }

    public int getUnreadCount() {
        return mUnreadCount;
    }
}
+30 −45
Original line number Diff line number Diff line
@@ -162,15 +162,23 @@ public class MessagingLayout extends FrameLayout
     */
    @RemotableViewMethod(asyncImpl = "setDataAsync")
    public void setData(Bundle extras) {
        bind(parseMessagingData(extras, /* usePrecomputedText= */false));
    }

    @NonNull
    private MessagingData parseMessagingData(Bundle extras, boolean usePrecomputedText) {
        Parcelable[] messages = extras.getParcelableArray(Notification.EXTRA_MESSAGES);
        List<Notification.MessagingStyle.Message> newMessages
                = Notification.MessagingStyle.Message.getMessagesFromBundleArray(messages);
        List<Notification.MessagingStyle.Message> newMessages =
                Notification.MessagingStyle.Message.getMessagesFromBundleArray(messages);
        Parcelable[] histMessages = extras.getParcelableArray(Notification.EXTRA_HISTORIC_MESSAGES);
        List<Notification.MessagingStyle.Message> newHistoricMessages
                = Notification.MessagingStyle.Message.getMessagesFromBundleArray(histMessages);
        setUser(extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON, android.app.Person.class));
        RemoteInputHistoryItem[] history = (RemoteInputHistoryItem[])
                extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, android.app.RemoteInputHistoryItem.class);
        List<Notification.MessagingStyle.Message> newHistoricMessages =
                Notification.MessagingStyle.Message.getMessagesFromBundleArray(histMessages);
        setUser(extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON,
                Person.class));
        RemoteInputHistoryItem[] history =
                (RemoteInputHistoryItem[]) extras.getParcelableArray(
                        Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS,
                        RemoteInputHistoryItem.class);
        addRemoteInputHistoryToMessages(newMessages, history);

        final Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON, Person.class);
@@ -178,10 +186,12 @@ public class MessagingLayout extends FrameLayout
                extras.getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false);

        final List<MessagingMessage> historicMessagingMessages = createMessages(newHistoricMessages,
                /* isHistoric= */true, /* usePrecomputedText= */ false);
                /* isHistoric= */true, usePrecomputedText);
        final List<MessagingMessage> newMessagingMessages =
                createMessages(newMessages, /* isHistoric= */false, /* usePrecomputedText= */false);
        bindViews(user, showSpinner, historicMessagingMessages, newMessagingMessages);
                createMessages(newMessages, /* isHistoric */false, usePrecomputedText);

        return new MessagingData(user, showSpinner,
                historicMessagingMessages, newMessagingMessages);
    }

    /**
@@ -197,37 +207,16 @@ public class MessagingLayout extends FrameLayout
            return () -> setData(extras);
        }

        Parcelable[] messages = extras.getParcelableArray(Notification.EXTRA_MESSAGES);
        List<Notification.MessagingStyle.Message> newMessages =
                Notification.MessagingStyle.Message.getMessagesFromBundleArray(messages);
        Parcelable[] histMessages = extras.getParcelableArray(Notification.EXTRA_HISTORIC_MESSAGES);
        List<Notification.MessagingStyle.Message> newHistoricMessages =
                Notification.MessagingStyle.Message.getMessagesFromBundleArray(histMessages);
        setUser(extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON,
                android.app.Person.class));
        RemoteInputHistoryItem[] history =
                (RemoteInputHistoryItem[]) extras.getParcelableArray(
                        Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS,
                        android.app.RemoteInputHistoryItem.class);
        addRemoteInputHistoryToMessages(newMessages, history);

        final Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON, Person.class);
        boolean showSpinner =
                extras.getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false);

        final List<MessagingMessage> historicMessagingMessages = createMessages(newHistoricMessages,
                        /* isHistoric= */true, /* usePrecomputedText= */ true);
        final List<MessagingMessage> newMessagingMessages =
                createMessages(newMessages, /* isHistoric */false, /* usePrecomputedText= */true);
        final MessagingData messagingData =
                parseMessagingData(extras, /* usePrecomputedText= */true);

        return () -> {
            finalizeInflate(historicMessagingMessages);
            finalizeInflate(newMessagingMessages);
            bindViews(user, showSpinner, historicMessagingMessages, newMessagingMessages);
            finalizeInflate(messagingData.getHistoricMessagingMessages());
            finalizeInflate(messagingData.getNewMessagingMessages());
            bind(messagingData);
        };
    }


    /**
     * enable/disable precomputed text usage
     * @hide
@@ -264,17 +253,13 @@ public class MessagingLayout extends FrameLayout
        }
    }

    private void bindViews(Person user, boolean showSpinner,
            List<MessagingMessage> historicMessagingMessages,
            List<MessagingMessage> newMessagingMessages) {
        setUser(user);
        bind(showSpinner, historicMessagingMessages, newMessagingMessages);
    }
    private void bind(MessagingData messagingData) {
        setUser(messagingData.getUser());

    private void bind(boolean showSpinner, List<MessagingMessage> historicMessages,
            List<MessagingMessage> messages) {
        List<MessagingMessage> historicMessages = messagingData.getHistoricMessagingMessages();
        List<MessagingMessage> messages = messagingData.getNewMessagingMessages();
        ArrayList<MessagingGroup> oldGroups = new ArrayList<>(mGroups);
        addMessagesToGroups(historicMessages, messages, showSpinner);
        addMessagesToGroups(historicMessages, messages, messagingData.getShowSpinner());

        // Let's first check which groups were removed altogether and remove them in one animation
        removeGroups(oldGroups);