/* * Copyright 2021 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.systemui.statusbar.notification.collection.inflation import android.app.Notification import android.app.RemoteInput import android.graphics.drawable.Icon import android.text.TextUtils import com.android.systemui.statusbar.NotificationLockscreenUserManager.RedactionType import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation /** * An immutable object which contains minimal state extracted from an entry that represents state * which can change without a direct app update (e.g. with a ranking update). Diffing two entries * determines if view re-inflation is needed. */ class NotifUiAdjustment internal constructor( val key: String, val smartActions: List, val smartReplies: List, val isConversation: Boolean, val isSnoozeEnabled: Boolean, val isMinimized: Boolean, @RedactionType val redactionType: Int, val isChildInGroup: Boolean, val isGroupSummary: Boolean, val summarization: String?, val isBundled: Boolean, ) { companion object { @JvmStatic fun needReinflate( oldAdjustment: NotifUiAdjustment, newAdjustment: NotifUiAdjustment, ): Boolean = when { oldAdjustment === newAdjustment -> false oldAdjustment.isConversation != newAdjustment.isConversation -> true oldAdjustment.isSnoozeEnabled != newAdjustment.isSnoozeEnabled -> true oldAdjustment.isMinimized != newAdjustment.isMinimized -> true oldAdjustment.redactionType != newAdjustment.redactionType -> true areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions) -> true newAdjustment.smartReplies != oldAdjustment.smartReplies -> true !oldAdjustment.isChildInGroup && newAdjustment.isChildInGroup -> true AsyncGroupHeaderViewInflation.isEnabled && !oldAdjustment.isGroupSummary && newAdjustment.isGroupSummary -> true oldAdjustment.summarization != newAdjustment.summarization -> true oldAdjustment.isBundled != newAdjustment.isBundled -> true else -> false } private fun areDifferent( first: List, second: List, ): Boolean = when { first === second -> false first.size != second.size -> true else -> first.asSequence().zip(second.asSequence()).any { (!TextUtils.equals(it.first.title, it.second.title)) || (areDifferent(it.first.getIcon(), it.second.getIcon())) || (it.first.actionIntent != it.second.actionIntent) || (areDifferent(it.first.remoteInputs, it.second.remoteInputs)) } } private fun areDifferent(first: Icon?, second: Icon?): Boolean = when { first === second -> false first == null || second == null -> true else -> !first.sameAs(second) } private fun areDifferent(first: Array?, second: Array?): Boolean = when { first === second -> false first == null || second == null -> true first.size != second.size -> true else -> first.asSequence().zip(second.asSequence()).any { (!TextUtils.equals(it.first.label, it.second.label)) || (areDifferent(it.first.choices, it.second.choices)) } } private fun areDifferent( first: Array?, second: Array?, ): Boolean = when { first === second -> false first == null || second == null -> true first.size != second.size -> true else -> first.asSequence().zip(second.asSequence()).any { !TextUtils.equals(it.first, it.second) } } } }