Home | History | Annotate | Download | only in widget
      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.Objects;
     24 
     25 /**
     26  * A message of a {@link MessagingLayout}.
     27  */
     28 public interface MessagingMessage extends MessagingLinearLayout.MessagingChild {
     29 
     30     /**
     31      * Prefix for supported image MIME types
     32      **/
     33     String IMAGE_MIME_TYPE_PREFIX = "image/";
     34 
     35     static MessagingMessage createMessage(MessagingLayout layout,
     36             Notification.MessagingStyle.Message m) {
     37         if (hasImage(m) && !ActivityManager.isLowRamDeviceStatic()) {
     38             return MessagingImageMessage.createMessage(layout, m);
     39         } else {
     40             return MessagingTextMessage.createMessage(layout, m);
     41         }
     42     }
     43 
     44     static void dropCache() {
     45         MessagingTextMessage.dropCache();
     46         MessagingImageMessage.dropCache();
     47     }
     48 
     49     static boolean hasImage(Notification.MessagingStyle.Message m) {
     50         return m.getDataUri() != null
     51                 && m.getDataMimeType() != null
     52                 && m.getDataMimeType().startsWith(IMAGE_MIME_TYPE_PREFIX);
     53     }
     54 
     55     /**
     56      * Set a message for this view.
     57      * @return true if setting the message worked
     58      */
     59     default boolean setMessage(Notification.MessagingStyle.Message message) {
     60         getState().setMessage(message);
     61         return true;
     62     }
     63 
     64     default Notification.MessagingStyle.Message getMessage() {
     65         return getState().getMessage();
     66     }
     67 
     68     default boolean sameAs(Notification.MessagingStyle.Message message) {
     69         Notification.MessagingStyle.Message ownMessage = getMessage();
     70         if (!Objects.equals(message.getText(), ownMessage.getText())) {
     71             return false;
     72         }
     73         if (!Objects.equals(message.getSender(), ownMessage.getSender())) {
     74             return false;
     75         }
     76         boolean hasRemoteInputHistoryChanged = message.isRemoteInputHistory()
     77                 != ownMessage.isRemoteInputHistory();
     78         // When the remote input history has changed, we want to regard messages equal even when
     79         // the timestamp changes. The main reason is that the message that the system inserts
     80         // will have a different time set than the one that the app will update us with and we
     81         // still want to reuse that message.
     82         if (!hasRemoteInputHistoryChanged
     83                 && !Objects.equals(message.getTimestamp(), ownMessage.getTimestamp())) {
     84             return false;
     85         }
     86         if (!Objects.equals(message.getDataMimeType(), ownMessage.getDataMimeType())) {
     87             return false;
     88         }
     89         if (!Objects.equals(message.getDataUri(), ownMessage.getDataUri())) {
     90             return false;
     91         }
     92         return true;
     93     }
     94 
     95     default boolean sameAs(MessagingMessage message) {
     96         return sameAs(message.getMessage());
     97     }
     98 
     99     default void removeMessage() {
    100         getGroup().removeMessage(this);
    101     }
    102 
    103     default void setMessagingGroup(MessagingGroup group) {
    104         getState().setGroup(group);
    105     }
    106 
    107     default void setIsHistoric(boolean isHistoric) {
    108         getState().setIsHistoric(isHistoric);
    109     }
    110 
    111     default MessagingGroup getGroup() {
    112         return getState().getGroup();
    113     }
    114 
    115     default void setIsHidingAnimated(boolean isHiding) {
    116         getState().setIsHidingAnimated(isHiding);
    117     }
    118 
    119     @Override
    120     default boolean isHidingAnimated() {
    121         return getState().isHidingAnimated();
    122     }
    123 
    124     @Override
    125     default void hideAnimated() {
    126         setIsHidingAnimated(true);
    127         getGroup().performRemoveAnimation(getView(), () -> setIsHidingAnimated(false));
    128     }
    129 
    130     default boolean hasOverlappingRendering() {
    131         return false;
    132     }
    133 
    134     default void recycle() {
    135         getState().recycle();
    136     }
    137 
    138     default View getView() {
    139         return (View) this;
    140     }
    141 
    142     default void setColor(int textColor) {}
    143 
    144     MessagingMessageState getState();
    145 
    146     void setVisibility(int visibility);
    147 
    148     int getVisibility();
    149 }
    150