1 /* 2 * Copyright 2018 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 package com.android.systemui.statusbar; 17 18 import android.annotation.NonNull; 19 import android.annotation.Nullable; 20 import android.app.Notification; 21 import android.app.RemoteInput; 22 import android.graphics.drawable.Icon; 23 import android.text.TextUtils; 24 25 import androidx.annotation.VisibleForTesting; 26 27 import com.android.systemui.statusbar.notification.collection.NotificationEntry; 28 29 import java.util.ArrayList; 30 import java.util.Arrays; 31 import java.util.Collections; 32 import java.util.List; 33 import java.util.Objects; 34 35 /** 36 * By diffing two entries, determines is view reinflation needed. 37 */ 38 public class NotificationUiAdjustment { 39 40 public final String key; 41 public final List<Notification.Action> smartActions; 42 public final CharSequence[] smartReplies; 43 44 @VisibleForTesting NotificationUiAdjustment( String key, List<Notification.Action> smartActions, CharSequence[] smartReplies)45 NotificationUiAdjustment( 46 String key, List<Notification.Action> smartActions, CharSequence[] smartReplies) { 47 this.key = key; 48 this.smartActions = smartActions == null 49 ? Collections.emptyList() 50 : new ArrayList<>(smartActions); 51 this.smartReplies = smartReplies == null ? new CharSequence[0] : smartReplies.clone(); 52 } 53 extractFromNotificationEntry( NotificationEntry entry)54 public static NotificationUiAdjustment extractFromNotificationEntry( 55 NotificationEntry entry) { 56 return new NotificationUiAdjustment( 57 entry.key, entry.systemGeneratedSmartActions, entry.systemGeneratedSmartReplies); 58 } 59 needReinflate( @onNull NotificationUiAdjustment oldAdjustment, @NonNull NotificationUiAdjustment newAdjustment)60 public static boolean needReinflate( 61 @NonNull NotificationUiAdjustment oldAdjustment, 62 @NonNull NotificationUiAdjustment newAdjustment) { 63 if (oldAdjustment == newAdjustment) { 64 return false; 65 } 66 if (areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions)) { 67 return true; 68 } 69 if (!Arrays.equals(oldAdjustment.smartReplies, newAdjustment.smartReplies)) { 70 return true; 71 } 72 return false; 73 } 74 areDifferent( @onNull List<Notification.Action> first, @NonNull List<Notification.Action> second)75 public static boolean areDifferent( 76 @NonNull List<Notification.Action> first, @NonNull List<Notification.Action> second) { 77 if (first == second) { 78 return false; 79 } 80 if (first == null || second == null) { 81 return true; 82 } 83 if (first.size() != second.size()) { 84 return true; 85 } 86 for (int i = 0; i < first.size(); i++) { 87 Notification.Action firstAction = first.get(i); 88 Notification.Action secondAction = second.get(i); 89 90 if (!TextUtils.equals(firstAction.title, secondAction.title)) { 91 return true; 92 } 93 94 if (areDifferent(firstAction.getIcon(), secondAction.getIcon())) { 95 return true; 96 } 97 98 if (!Objects.equals(firstAction.actionIntent, secondAction.actionIntent)) { 99 return true; 100 } 101 102 if (areDifferent(firstAction.getRemoteInputs(), secondAction.getRemoteInputs())) { 103 return true; 104 } 105 } 106 return false; 107 } 108 areDifferent(@ullable Icon first, @Nullable Icon second)109 private static boolean areDifferent(@Nullable Icon first, @Nullable Icon second) { 110 if (first == second) { 111 return false; 112 } 113 if (first == null || second == null) { 114 return true; 115 } 116 return !first.sameAs(second); 117 } 118 areDifferent( @ullable RemoteInput[] first, @Nullable RemoteInput[] second)119 private static boolean areDifferent( 120 @Nullable RemoteInput[] first, @Nullable RemoteInput[] second) { 121 if (first == second) { 122 return false; 123 } 124 if (first == null || second == null) { 125 return true; 126 } 127 if (first.length != second.length) { 128 return true; 129 } 130 for (int i = 0; i < first.length; i++) { 131 RemoteInput firstRemoteInput = first[i]; 132 RemoteInput secondRemoteInput = second[i]; 133 134 if (!TextUtils.equals(firstRemoteInput.getLabel(), secondRemoteInput.getLabel())) { 135 return true; 136 } 137 if (areDifferent(firstRemoteInput.getChoices(), secondRemoteInput.getChoices())) { 138 return true; 139 } 140 } 141 return false; 142 } 143 areDifferent( @ullable CharSequence[] first, @Nullable CharSequence[] second)144 private static boolean areDifferent( 145 @Nullable CharSequence[] first, @Nullable CharSequence[] second) { 146 if (first == second) { 147 return false; 148 } 149 if (first == null || second == null) { 150 return true; 151 } 152 if (first.length != second.length) { 153 return true; 154 } 155 for (int i = 0; i < first.length; i++) { 156 CharSequence firstCharSequence = first[i]; 157 CharSequence secondCharSequence = second[i]; 158 if (!TextUtils.equals(firstCharSequence, secondCharSequence)) { 159 return true; 160 } 161 } 162 return false; 163 } 164 } 165