• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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.systemui.statusbar.notification.collection.inflation
18 
19 import android.app.Notification
20 import android.app.RemoteInput
21 import android.graphics.drawable.Icon
22 import android.text.TextUtils
23 import com.android.systemui.statusbar.NotificationLockscreenUserManager.RedactionType
24 import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation
25 import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation
26 
27 /**
28  * An immutable object which contains minimal state extracted from an entry that represents state
29  * which can change without a direct app update (e.g. with a ranking update). Diffing two entries
30  * determines if view re-inflation is needed.
31  */
32 class NotifUiAdjustment
33 internal constructor(
34     val key: String,
35     val smartActions: List<Notification.Action>,
36     val smartReplies: List<CharSequence>,
37     val isConversation: Boolean,
38     val isSnoozeEnabled: Boolean,
39     val isMinimized: Boolean,
40     @RedactionType val redactionType: Int,
41     val isChildInGroup: Boolean,
42     val isGroupSummary: Boolean,
43     val summarization: String?,
44 ) {
45     companion object {
46         @JvmStatic
needReinflatenull47         fun needReinflate(
48             oldAdjustment: NotifUiAdjustment,
49             newAdjustment: NotifUiAdjustment,
50         ): Boolean =
51             when {
52                 oldAdjustment === newAdjustment -> false
53                 oldAdjustment.isConversation != newAdjustment.isConversation -> true
54                 oldAdjustment.isSnoozeEnabled != newAdjustment.isSnoozeEnabled -> true
55                 oldAdjustment.isMinimized != newAdjustment.isMinimized -> true
56                 oldAdjustment.redactionType != newAdjustment.redactionType -> true
57                 areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions) -> true
58                 newAdjustment.smartReplies != oldAdjustment.smartReplies -> true
59                 AsyncHybridViewInflation.isEnabled &&
60                     !oldAdjustment.isChildInGroup &&
61                     newAdjustment.isChildInGroup -> true
62                 AsyncGroupHeaderViewInflation.isEnabled &&
63                     !oldAdjustment.isGroupSummary &&
64                     newAdjustment.isGroupSummary -> true
65                 oldAdjustment.summarization != newAdjustment.summarization -> true
66                 else -> false
67             }
68 
areDifferentnull69         private fun areDifferent(
70             first: List<Notification.Action>,
71             second: List<Notification.Action>,
72         ): Boolean =
73             when {
74                 first === second -> false
75                 first.size != second.size -> true
76                 else ->
77                     first.asSequence().zip(second.asSequence()).any {
78                         (!TextUtils.equals(it.first.title, it.second.title)) ||
79                             (areDifferent(it.first.getIcon(), it.second.getIcon())) ||
80                             (it.first.actionIntent != it.second.actionIntent) ||
81                             (areDifferent(it.first.remoteInputs, it.second.remoteInputs))
82                     }
83             }
84 
areDifferentnull85         private fun areDifferent(first: Icon?, second: Icon?): Boolean =
86             when {
87                 first === second -> false
88                 first == null || second == null -> true
89                 else -> !first.sameAs(second)
90             }
91 
areDifferentnull92         private fun areDifferent(first: Array<RemoteInput>?, second: Array<RemoteInput>?): Boolean =
93             when {
94                 first === second -> false
95                 first == null || second == null -> true
96                 first.size != second.size -> true
97                 else ->
98                     first.asSequence().zip(second.asSequence()).any {
99                         (!TextUtils.equals(it.first.label, it.second.label)) ||
100                             (areDifferent(it.first.choices, it.second.choices))
101                     }
102             }
103 
areDifferentnull104         private fun areDifferent(
105             first: Array<CharSequence>?,
106             second: Array<CharSequence>?,
107         ): Boolean =
108             when {
109                 first === second -> false
110                 first == null || second == null -> true
111                 first.size != second.size -> true
112                 else ->
113                     first.asSequence().zip(second.asSequence()).any {
114                         !TextUtils.equals(it.first, it.second)
115                     }
116             }
117     }
118 }
119