blob: 6e1f99d07ee4d4a1edbaab35e9d9d8b792e2a9ea [file] [log] [blame]
/*
* Copyright (C) 2022 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.permissioncontroller.safetycenter.ui
import android.content.Context
import android.safetycenter.SafetyCenterIssue
import android.util.Log
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.core.view.ViewCompat
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLICK
import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
import com.android.permissioncontroller.R
import com.android.permissioncontroller.permission.utils.StringUtils
/** A preference that displays a card linking to a list of more {@link SafetyCenterIssue}. */
class MoreIssuesCardPreference(
context: Context,
@DrawableRes val preferenceWidgetIconResourceId: Int,
val previousMoreIssuesCardData: MoreIssuesCardData?,
val newMoreIssuesCardData: MoreIssuesCardData,
val onClickListener: OnPreferenceClickListener
) : Preference(context), ComparablePreference {
private var moreIssuesCardAnimator = MoreIssuesCardAnimator()
init {
layoutResource = R.layout.preference_more_issues_card
widgetLayoutResource = R.layout.preference_expand_more_issues_widget
onPreferenceClickListener = onClickListener
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
val statusIcon = holder.findViewById(R.id.status_icon) as ImageView
setCurrentSeverityLevel(statusIcon)
val widgetIcon = holder.findViewById(R.id.widget_icon) as ImageView
widgetIcon.setImageResource(preferenceWidgetIconResourceId)
val widgetTitle = holder.findViewById(R.id.widget_title) as TextView
updateHiddenIssueCount(widgetTitle)
val expansionString =
StringUtils.getIcuPluralsString(
context,
R.string.safety_center_more_issues_card_expand_action,
newMoreIssuesCardData.hiddenIssueCount)
// Replacing the on-click label to indicate the number of hidden issues. The on-click
// command is set to null so that it uses the existing expansion behaviour.
ViewCompat.replaceAccessibilityAction(holder.itemView, ACTION_CLICK, expansionString, null)
}
private fun updateHiddenIssueCount(textView: TextView) {
moreIssuesCardAnimator.cancelTextChangeAnimation(textView)
val previousText = previousMoreIssuesCardData?.hiddenIssueCount.toString()
val newText = newMoreIssuesCardData.hiddenIssueCount.toString()
val animateTextChange = !previousText.isNullOrEmpty() && previousText != newText
if (animateTextChange) {
textView.text = previousText
moreIssuesCardAnimator.animateChangeText(textView, newText)
} else {
textView.text = newText
}
}
private fun setCurrentSeverityLevel(statusIcon: ImageView) {
moreIssuesCardAnimator.cancelStatusAnimation(statusIcon)
if (previousMoreIssuesCardData != null &&
previousMoreIssuesCardData.severityLevel != newMoreIssuesCardData.severityLevel) {
moreIssuesCardAnimator.animateStatusIconsChange(
statusIcon,
previousMoreIssuesCardData.severityLevel,
newMoreIssuesCardData.severityLevel,
selectIconResId(newMoreIssuesCardData.severityLevel))
} else {
statusIcon.setImageResource(selectIconResId(newMoreIssuesCardData.severityLevel))
}
}
@DrawableRes
private fun selectIconResId(severityLevel: Int): Int {
return when (severityLevel) {
SafetyCenterIssue.ISSUE_SEVERITY_LEVEL_OK -> R.drawable.ic_safety_info
SafetyCenterIssue.ISSUE_SEVERITY_LEVEL_RECOMMENDATION ->
R.drawable.ic_safety_recommendation
SafetyCenterIssue.ISSUE_SEVERITY_LEVEL_CRITICAL_WARNING -> R.drawable.ic_safety_warn
else -> {
Log.e(
TAG,
String.format(
"Unexpected SafetyCenterIssue.IssueSeverityLevel: %d", severityLevel))
R.drawable.ic_safety_null_state
}
}
}
override fun isSameItem(preference: Preference): Boolean {
return preference is MoreIssuesCardPreference
}
override fun hasSameContents(preference: Preference): Boolean {
return preference is MoreIssuesCardPreference &&
previousMoreIssuesCardData == preference.previousMoreIssuesCardData &&
newMoreIssuesCardData == preference.newMoreIssuesCardData &&
preferenceWidgetIconResourceId == preference.preferenceWidgetIconResourceId
}
companion object {
val TAG: String = MoreIssuesCardPreference::class.java.simpleName
}
}
data class MoreIssuesCardData(val severityLevel: Int, val hiddenIssueCount: Int)