• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.internal.widget;
18 
19 import android.app.ActivityManager;
20 import android.app.Notification;
21 import android.view.View;
22 
23 import java.util.ArrayList;
24 import java.util.Objects;
25 
26 /**
27  * A message or summary of a {@link MessagingLayout}.
28  */
29 public interface MessagingMessage extends MessagingLinearLayout.MessagingChild {
30 
31     /**
32      * Prefix for supported image MIME types
33      **/
34     String IMAGE_MIME_TYPE_PREFIX = "image/";
35 
createMessage(IMessagingLayout layout, Notification.MessagingStyle.Message m, ImageResolver resolver, boolean usePrecomputedText)36     static MessagingMessage createMessage(IMessagingLayout layout,
37             Notification.MessagingStyle.Message m, ImageResolver resolver,
38             boolean usePrecomputedText) {
39         if (hasImage(m) && !ActivityManager.isLowRamDeviceStatic()) {
40             return MessagingImageMessage.createMessage(layout, m, resolver, usePrecomputedText);
41         } else {
42             return MessagingTextMessage.createMessage(layout, m, usePrecomputedText);
43         }
44     }
45 
dropCache()46     static void dropCache() {
47         MessagingTextMessage.dropCache();
48         MessagingImageMessage.dropCache();
49     }
50 
hasImage(Notification.MessagingStyle.Message m)51     static boolean hasImage(Notification.MessagingStyle.Message m) {
52         return m.getDataUri() != null
53                 && m.getDataMimeType() != null
54                 && m.getDataMimeType().startsWith(IMAGE_MIME_TYPE_PREFIX);
55     }
56 
57     /**
58      * Set a message for this view.
59      *
60      * @return true if setting the message worked
61      */
setMessage(Notification.MessagingStyle.Message message, boolean usePrecomputedText)62     default boolean setMessage(Notification.MessagingStyle.Message message,
63             boolean usePrecomputedText) {
64         getState().setMessage(message);
65         return true;
66     }
67 
getMessage()68     default Notification.MessagingStyle.Message getMessage() {
69         return getState().getMessage();
70     }
71 
sameAs(Notification.MessagingStyle.Message message)72     default boolean sameAs(Notification.MessagingStyle.Message message) {
73         Notification.MessagingStyle.Message ownMessage = getMessage();
74         // We have to make sure both messages are not null to go further comparison
75         if (message == null || ownMessage == null) {
76             return message == ownMessage;
77         }
78         if (!Objects.equals(message.getText(), ownMessage.getText())) {
79             return false;
80         }
81         if (!Objects.equals(message.getSender(), ownMessage.getSender())) {
82             return false;
83         }
84         boolean hasRemoteInputHistoryChanged = message.isRemoteInputHistory()
85                 != ownMessage.isRemoteInputHistory();
86         // When the remote input history has changed, we want to regard messages equal even when
87         // the timestamp changes. The main reason is that the message that the system inserts
88         // will have a different time set than the one that the app will update us with and we
89         // still want to reuse that message.
90         if (!hasRemoteInputHistoryChanged
91                 && !Objects.equals(message.getTimestamp(), ownMessage.getTimestamp())) {
92             return false;
93         }
94         if (!Objects.equals(message.getDataMimeType(), ownMessage.getDataMimeType())) {
95             return false;
96         }
97         if (!Objects.equals(message.getDataUri(), ownMessage.getDataUri())) {
98             return false;
99         }
100         return true;
101     }
102 
sameAs(MessagingMessage message)103     default boolean sameAs(MessagingMessage message) {
104         return sameAs(message.getMessage());
105     }
106 
removeMessage(ArrayList<MessagingLinearLayout.MessagingChild> toRecycle)107     default void removeMessage(ArrayList<MessagingLinearLayout.MessagingChild> toRecycle) {
108         final MessagingGroup group = getGroup();
109         if (group != null) {
110             group.removeMessage(this, toRecycle);
111         }
112     }
113 
setMessagingGroup(MessagingGroup group)114     default void setMessagingGroup(MessagingGroup group) {
115         getState().setGroup(group);
116     }
117 
setIsHistoric(boolean isHistoric)118     default void setIsHistoric(boolean isHistoric) {
119         getState().setIsHistoric(isHistoric);
120     }
121 
getGroup()122     default MessagingGroup getGroup() {
123         return getState().getGroup();
124     }
125 
setIsHidingAnimated(boolean isHiding)126     default void setIsHidingAnimated(boolean isHiding) {
127         getState().setIsHidingAnimated(isHiding);
128     }
129 
130     @Override
isHidingAnimated()131     default boolean isHidingAnimated() {
132         return getState().isHidingAnimated();
133     }
134 
135     @Override
hideAnimated()136     default void hideAnimated() {
137         setIsHidingAnimated(true);
138         final MessagingGroup group = getGroup();
139         if (group != null) {
140             group.performRemoveAnimation(getView(), () -> setIsHidingAnimated(false));
141         } else {
142             setIsHidingAnimated(false);
143         }
144     }
145 
hasOverlappingRendering()146     default boolean hasOverlappingRendering() {
147         return false;
148     }
149 
recycle()150     default void recycle() {
151         getState().recycle();
152     }
153 
getView()154     default View getView() {
155         return (View) this;
156     }
157 
setColor(int textColor)158     default void setColor(int textColor) {}
159 
getState()160     MessagingMessageState getState();
161 
setVisibility(int visibility)162     void setVisibility(int visibility);
163 
getVisibility()164     int getVisibility();
165 
166     /**
167      * Finalize inflation of the MessagingMessages, which should be called on Main Thread.
168      * @hide
169      */
finalizeInflate()170     void finalizeInflate();
171 }
172