Make Safety groups expandable and collapsable
Test: manual
Bug: 241354578
Change-Id: Ice90b37a7cd534277c5ae763f001805fa772dc37
diff --git a/PermissionController/res/drawable-v33/ic_privacy.xml b/PermissionController/res/drawable-v33/ic_privacy.xml
index 60194f4..3e79456 100644
--- a/PermissionController/res/drawable-v33/ic_privacy.xml
+++ b/PermissionController/res/drawable-v33/ic_privacy.xml
@@ -20,8 +20,7 @@
android:height="20dp"
android:viewportWidth="16"
android:viewportHeight="20">
- <group>
- <clip-path android:pathData="M0 0H16V20H0V0Z" />
- <path android:pathData="M0 0V20H16V0" android:fillColor="?android:attr/textColorSecondary" />
- </group>
+ <path
+ android:pathData="M8,0L0,3V9.09C0,14.14 3.41,18.85 8,20C12.59,18.85 16,14.14 16,9.09V3L8,0ZM14,9.09C14,13.09 11.45,16.79 8,17.92C4.55,16.79 2,13.1 2,9.09V4.39L8,2.14L14,4.39V9.09ZM8.93,9.77L9.5,13H6.5L7.07,9.77C6.43,9.44 6,8.77 6,8C6,6.9 6.9,6 8,6C9.1,6 10,6.9 10,8C10,8.77 9.57,9.44 8.93,9.77Z"
+ android:fillColor="?android:attr/textColorPrimary"/>
</vector>
diff --git a/PermissionController/res/drawable-v33/ic_safety_group_expand.xml b/PermissionController/res/drawable-v33/ic_safety_group_expand.xml
new file mode 100644
index 0000000..bf0606d
--- /dev/null
+++ b/PermissionController/res/drawable-v33/ic_safety_group_expand.xml
@@ -0,0 +1,12 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M0,12C0,5.373 5.373,0 12,0C18.627,0 24,5.373 24,12C24,18.627 18.627,24 12,24C5.373,24 0,18.627 0,12Z"
+ android:fillColor="?attr/colorSurfaceVariant"/>
+ <path
+ android:pathData="M7.607,9.059L6.667,9.999L12,15.332L17.333,9.999L16.393,9.059L12,13.445"
+ android:fillColor="?android:attr/textColorPrimary"/>
+</vector>
diff --git a/PermissionController/res/layout-v33/preference_collapsed_group_entry.xml b/PermissionController/res/layout-v33/preference_collapsed_group_entry.xml
new file mode 100644
index 0000000..d4ad271
--- /dev/null
+++ b/PermissionController/res/layout-v33/preference_collapsed_group_entry.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ ~ 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
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/SafetyCenterEntry">
+
+ <FrameLayout
+ android:id="@+id/icon_frame"
+ style="@style/SafetyCenterEntryIconFrame">
+ <ImageView
+ android:id="@android:id/icon"
+ style="@style/SafetyCenterEntryIcon"/>
+ </FrameLayout>
+
+ <Space
+ android:id="@+id/empty_space"
+ style="@style/SafetyCenterEntryEmptySpace"/>
+
+ <LinearLayout
+ style="@style/SafetyCenterEntryTextContainer">
+
+ <TextView android:id="@android:id/title"
+ style="@style/SafetyCenterEntryTitle" />
+
+ <TextView android:id="@android:id/summary"
+ style="@style/SafetyCenterEntrySummary" />
+
+ </LinearLayout>
+
+ <ImageView android:id="@+id/chevron_icon"
+ android:layout_height="match_parent"
+ style="@style/SafetyCenterExpandedGroupIcon" />
+</LinearLayout>
diff --git a/PermissionController/res/layout-v33/preference_expanded_group_entry.xml b/PermissionController/res/layout-v33/preference_expanded_group_entry.xml
index 95fea69..f34da0d 100644
--- a/PermissionController/res/layout-v33/preference_expanded_group_entry.xml
+++ b/PermissionController/res/layout-v33/preference_expanded_group_entry.xml
@@ -21,7 +21,6 @@
<TextView android:id="@android:id/title"
style="@style/SafetyCenterGroupTitle"/>
- <!-- Preference could place its optional widget here. -->
- <LinearLayout android:id="@android:id/widget_frame"
- style="@style/SafetyCenterGroupWidgetFrame"/>
+ <ImageView android:id="@+id/chevron_icon"
+ style="@style/SafetyCenterExpandedGroupIcon" />
</LinearLayout>
diff --git a/PermissionController/res/layout-v33/preference_expanded_group_widget.xml b/PermissionController/res/layout-v33/preference_expanded_group_widget.xml
deleted file mode 100644
index e76cc59..0000000
--- a/PermissionController/res/layout-v33/preference_expanded_group_widget.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ 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.
- -->
-<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/expanded_icon"
- android:src="@drawable/ic_safety_group_collapse"
- style="@style/SafetyCenterExpandedGroupIcon"/>
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/CollapsableGroupCardHelper.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/CollapsableGroupCardHelper.kt
new file mode 100644
index 0000000..c2c4b92
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/CollapsableGroupCardHelper.kt
@@ -0,0 +1,71 @@
+/*
+ * 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.os.Build
+import android.os.Bundle
+import androidx.annotation.RequiresApi
+import androidx.preference.PreferenceGroup
+
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+internal class CollapsableGroupCardHelper {
+
+ private val expandedGroups = mutableSetOf<CharSequence>()
+
+ private companion object {
+ private const val EXPANDED_ENTRY_GROUPS_SAVED_INSTANCE_STATE_KEY =
+ "expanded_entry_groups_saved_instance_state_key"
+ }
+
+ fun restoreState(state: Bundle?) {
+ state?.getCharSequenceArray(EXPANDED_ENTRY_GROUPS_SAVED_INSTANCE_STATE_KEY)?.let {
+ expandedGroups.clear()
+ expandedGroups.addAll(it)
+ }
+ }
+
+ fun saveState(outState: Bundle) {
+ outState.putCharSequenceArray(
+ EXPANDED_ENTRY_GROUPS_SAVED_INSTANCE_STATE_KEY,
+ expandedGroups.toTypedArray()
+ )
+ }
+
+ fun collapseGroup(groupId: String) {
+ expandedGroups.remove(groupId)
+ }
+
+ fun expandGroup(groupId: String) {
+ expandedGroups.add(groupId)
+ }
+
+ fun updatePreferenceVisibility(group: PreferenceGroup) {
+ val preferenceCount = group.preferenceCount
+ for (i in 0 until preferenceCount) {
+ when (val preference = group.getPreference(i)) {
+ is SafetyGroupHeaderEntryPreference -> {
+ val shouldShowExpanded = expandedGroups.contains(preference.groupId)
+ preference.isVisible = preference.isExpanded == shouldShowExpanded
+ }
+ is SafetyEntryPreference -> {
+ preference.isVisible = preference.groupId == null ||
+ expandedGroups.contains(preference.groupId)
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/PositionInCardList.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/PositionInCardList.kt
index fbe9fa3..1b70f45 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/PositionInCardList.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/PositionInCardList.kt
@@ -50,9 +50,9 @@
fun getTopMargin(context: Context): Int =
when (this) {
- CARD_START, CARD_START_END ->
+ CARD_START, CARD_START_END, CARD_START_LIST_END ->
context.resources.getDimensionPixelSize(R.dimen.safety_center_card_margin)
- LIST_START, LIST_START_CARD_END ->
+ LIST_START, LIST_START_CARD_END, LIST_START_END ->
context.resources.getDimensionPixelSize(R.dimen.safety_center_list_margin)
else -> 0
}
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterDashboardFragment.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterDashboardFragment.java
index 148340f..f5dbe0f 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterDashboardFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterDashboardFragment.java
@@ -78,6 +78,8 @@
private SafetyStatusPreference mSafetyStatusPreference;
private CollapsableIssuesCardHelper mCollapsableIssuesCardHelper;
+ private final CollapsableGroupCardHelper mCollapsableGroupCardHelper =
+ new CollapsableGroupCardHelper();
private PreferenceGroup mIssuesGroup;
private PreferenceGroup mEntriesGroup;
private PreferenceGroup mStaticEntriesGroup;
@@ -160,6 +162,8 @@
mIsQuickSettingsFragment, parsedSafetyCenterIntent.getShouldExpandIssuesGroup());
mCollapsableIssuesCardHelper.restoreState(savedInstanceState);
+ mCollapsableGroupCardHelper.restoreState(savedInstanceState);
+
mSafetyStatusPreference =
requireNonNull(getPreferenceScreen().findPreference(SAFETY_STATUS_KEY));
// TODO: Use real strings here, or set more sensible defaults in the layout
@@ -217,6 +221,7 @@
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
mCollapsableIssuesCardHelper.saveState(outState);
+ mCollapsableGroupCardHelper.saveState(outState);
}
@Override
@@ -315,6 +320,8 @@
addGroupEntries(context, group, isFirstElement, isLastElement);
}
}
+
+ mCollapsableGroupCardHelper.updatePreferenceVisibility(mEntriesGroup);
}
private void addTopLevelEntry(
@@ -327,6 +334,7 @@
context,
getTaskIdForEntry(entry),
entry,
+ /* groupId */ null,
PositionInCardList.calculate(isFirstElement, isLastElement),
mViewModel));
}
@@ -336,34 +344,66 @@
SafetyCenterEntryGroup group,
boolean isFirstCard,
boolean isLastCard) {
+ // adding collapsed group entry, which will be visible initially
+ mEntriesGroup.addPreference(
+ new SafetyGroupHeaderEntryPreference(
+ context,
+ group,
+ isFirstCard
+ ? isLastCard ? PositionInCardList.LIST_START_END
+ : PositionInCardList.LIST_START_CARD_END
+ : isLastCard ? PositionInCardList.CARD_START_LIST_END
+ : PositionInCardList.CARD_START_END,
+ /* isExpanded */ false,
+ this::expandGroup
+ )
+ );
+
+ // adding expanded group entry, which will be hidden initially
mEntriesGroup.addPreference(
new SafetyGroupHeaderEntryPreference(
context,
group,
isFirstCard
? PositionInCardList.LIST_START
- : PositionInCardList.CARD_START));
+ : PositionInCardList.CARD_START,
+ /* isExpanded */ true,
+ this::collapseGroup
+ )
+ );
+ // adding group entries, but they are will be hidden initially until group is expanded
List<SafetyCenterEntry> entries = group.getEntries();
for (int i = 0, last = entries.size() - 1; i <= last; i++) {
boolean isCardEnd = i == last;
boolean isListEnd = isLastCard && isCardEnd;
PositionInCardList positionInCardList =
PositionInCardList.calculate(
- /* isListStart= */ false,
+ /* isListStart */ false,
isListEnd,
- /* isCardStart= */ false,
+ /* isCardStart */ false,
isCardEnd);
mEntriesGroup.addPreference(
new SafetyEntryPreference(
context,
getTaskIdForEntry(entries.get(i)),
entries.get(i),
+ group.getId(),
positionInCardList,
mViewModel));
}
}
+ private void expandGroup(String groupId) {
+ mCollapsableGroupCardHelper.expandGroup(groupId);
+ mCollapsableGroupCardHelper.updatePreferenceVisibility(mEntriesGroup);
+ }
+
+ private void collapseGroup(String groupId) {
+ mCollapsableGroupCardHelper.collapseGroup(groupId);
+ mCollapsableGroupCardHelper.updatePreferenceVisibility(mEntriesGroup);
+ }
+
private void updateStaticSafetyEntries(
Context context, List<SafetyCenterStaticEntryGroup> staticEntryGroups) {
mStaticEntriesGroup.removeAll();
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyEntryPreference.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyEntryPreference.java
index c52a115..320ddcf 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyEntryPreference.java
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyEntryPreference.java
@@ -46,11 +46,13 @@
private final PositionInCardList mPosition;
private final SafetyCenterEntry mEntry;
private final SafetyCenterViewModel mViewModel;
+ private final CharSequence mGroupId;
public SafetyEntryPreference(
Context context,
int taskId,
SafetyCenterEntry entry,
+ CharSequence groupId,
PositionInCardList position,
SafetyCenterViewModel viewModel) {
super(context);
@@ -58,12 +60,14 @@
mEntry = entry;
mPosition = position;
mViewModel = viewModel;
+ mGroupId = groupId;
setLayoutResource(R.layout.preference_entry);
setTitle(entry.getTitle());
setSummary(entry.getSummary());
- setIcon(selectIconResId(mEntry));
+ setIcon(SeverityIconPicker.selectIconResId(
+ mEntry.getSeverityLevel(), mEntry.getSeverityUnspecifiedIconType()));
PendingIntent pendingIntent = entry.getPendingIntent();
if (pendingIntent != null) {
@@ -116,7 +120,7 @@
boolean hideIcon =
mEntry.getSeverityLevel() == SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_UNSPECIFIED
&& mEntry.getSeverityUnspecifiedIconType()
- == SafetyCenterEntry.SEVERITY_UNSPECIFIED_ICON_TYPE_NO_ICON;
+ == SafetyCenterEntry.SEVERITY_UNSPECIFIED_ICON_TYPE_NO_ICON;
holder.findViewById(R.id.icon_frame).setVisibility(hideIcon ? View.GONE : View.VISIBLE);
holder.findViewById(R.id.empty_space).setVisibility(hideIcon ? View.VISIBLE : View.GONE);
enableOrDisableEntry(holder);
@@ -157,23 +161,6 @@
}
}
- private static int selectIconResId(SafetyCenterEntry entry) {
- switch (entry.getSeverityLevel()) {
- case SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_UNKNOWN:
- return R.drawable.ic_safety_null_state;
- case SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_UNSPECIFIED:
- return selectSeverityUnspecifiedIconResId(entry);
- case SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_OK:
- return R.drawable.ic_safety_info;
- case SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_RECOMMENDATION:
- return R.drawable.ic_safety_recommendation;
- case SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_CRITICAL_WARNING:
- return R.drawable.ic_safety_warn;
- }
- Log.e(TAG, String.format("Unexpected SafetyCenterEntry.EntrySeverityLevel: %s", entry));
- return R.drawable.ic_safety_null_state;
- }
-
/** We are doing this because we need some entries to look disabled but still be clickable. */
private void enableOrDisableEntry(@NonNull PreferenceViewHolder holder) {
holder.itemView.setEnabled(mEntry.getPendingIntent() != null);
@@ -186,23 +173,15 @@
}
}
- private static int selectSeverityUnspecifiedIconResId(SafetyCenterEntry entry) {
- switch (entry.getSeverityUnspecifiedIconType()) {
- case SafetyCenterEntry.SEVERITY_UNSPECIFIED_ICON_TYPE_NO_ICON:
- return R.drawable.ic_safety_empty;
- case SafetyCenterEntry.SEVERITY_UNSPECIFIED_ICON_TYPE_PRIVACY:
- return R.drawable.ic_privacy;
- case SafetyCenterEntry.SEVERITY_UNSPECIFIED_ICON_TYPE_NO_RECOMMENDATION:
- return R.drawable.ic_safety_null_state;
- }
- Log.e(TAG, String.format("Unexpected SafetyCenterEntry.SeverityNoneIconType: %s", entry));
- return R.drawable.ic_safety_null_state;
+ public CharSequence getGroupId() {
+ return mGroupId;
}
@Override
public boolean isSameItem(@NonNull Preference other) {
return other instanceof SafetyEntryPreference
- && TextUtils.equals(mEntry.getId(), ((SafetyEntryPreference) other).mEntry.getId());
+ && TextUtils.equals(mEntry.getId(), ((SafetyEntryPreference) other).mEntry.getId())
+ && TextUtils.equals(mGroupId, ((SafetyEntryPreference) other).mGroupId);
}
@Override
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyGroupHeaderEntryPreference.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyGroupHeaderEntryPreference.java
index e0247d0..1fc52f6 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyGroupHeaderEntryPreference.java
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyGroupHeaderEntryPreference.java
@@ -24,6 +24,7 @@
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
+import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
@@ -32,33 +33,60 @@
import com.android.permissioncontroller.R;
-/** A preference that displays a visual representation of a {@link SafetyCenterEntry}. */
+import java.util.function.Consumer;
+
+/**
+ * A preference that displays a visual representation of a header for
+ * {@link SafetyCenterEntryGroup}.
+ */
@RequiresApi(TIRAMISU)
public class SafetyGroupHeaderEntryPreference extends Preference implements ComparablePreference {
private static final String TAG = SafetyGroupHeaderEntryPreference.class.getSimpleName();
- private final String mId;
+ private final SafetyCenterEntryGroup mGroup;
private final PositionInCardList mPosition;
+ private final boolean mIsExpanded;
public SafetyGroupHeaderEntryPreference(
- Context context, SafetyCenterEntryGroup group, PositionInCardList position) {
+ Context context,
+ SafetyCenterEntryGroup group,
+ PositionInCardList position,
+ boolean isExpanded,
+ Consumer<String> onClick) {
super(context);
- mId = group.getId();
+ mGroup = group;
mPosition = position;
- setLayoutResource(R.layout.preference_expanded_group_entry);
- setWidgetLayoutResource(R.layout.preference_expanded_group_widget);
+ mIsExpanded = isExpanded;
+ setLayoutResource(
+ isExpanded
+ ? R.layout.preference_expanded_group_entry
+ : R.layout.preference_collapsed_group_entry);
+
setTitle(group.getTitle());
- // TODO(b/222126985): make back selectable to return the Ripple effect
- setSelectable(false);
+ if (!isExpanded) {
+ setSummary(group.getSummary());
+ setIcon(
+ SeverityIconPicker.selectIconResId(
+ group.getSeverityLevel(), group.getSeverityUnspecifiedIconType()));
+ }
+
setOnPreferenceClickListener(
unused -> {
- // TODO(b/222126985): implement collapsing UX
+ onClick.accept(group.getId());
return true;
});
}
+ public String getGroupId() {
+ return mGroup != null ? mGroup.getId() : null;
+ }
+
+ public boolean isExpanded() {
+ return mIsExpanded;
+ }
+
@Override
public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
@@ -71,22 +99,38 @@
holder.itemView.setLayoutParams(params);
}
- // TODO(b/222126985): show a proper icon based on current state
- holder.findViewById(R.id.expanded_icon).setVisibility(View.GONE);
+ if (!mIsExpanded) {
+ boolean hideIcon =
+ mGroup.getSeverityLevel() == SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_UNSPECIFIED
+ && mGroup.getSeverityUnspecifiedIconType()
+ == SafetyCenterEntry.SEVERITY_UNSPECIFIED_ICON_TYPE_NO_ICON;
+ holder.findViewById(R.id.icon_frame).setVisibility(hideIcon ? View.GONE : View.VISIBLE);
+ holder.findViewById(R.id.empty_space)
+ .setVisibility(hideIcon ? View.VISIBLE : View.GONE);
+ }
+
+ ImageView chevronIcon = (ImageView) holder.findViewById(R.id.chevron_icon);
+ chevronIcon.setImageResource(
+ mIsExpanded
+ ? R.drawable.ic_safety_group_collapse
+ : R.drawable.ic_safety_group_expand);
}
@Override
public boolean isSameItem(@NonNull Preference other) {
- return mId != null
+ return mGroup != null
&& other instanceof SafetyGroupHeaderEntryPreference
- && TextUtils.equals(mId, ((SafetyGroupHeaderEntryPreference) other).mId);
+ && TextUtils.equals(
+ getGroupId(), ((SafetyGroupHeaderEntryPreference) other).getGroupId());
}
@Override
public boolean hasSameContents(@NonNull Preference other) {
if (other instanceof SafetyGroupHeaderEntryPreference) {
SafetyGroupHeaderEntryPreference o = (SafetyGroupHeaderEntryPreference) other;
- return TextUtils.equals(getTitle(), o.getTitle()) && mPosition == o.mPosition;
+ return TextUtils.equals(getTitle(), o.getTitle())
+ && mPosition == o.mPosition
+ && mIsExpanded == o.mIsExpanded;
}
return false;
}
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SeverityIconPicker.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SeverityIconPicker.java
new file mode 100644
index 0000000..3c75309
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SeverityIconPicker.java
@@ -0,0 +1,63 @@
+/*
+ * 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.safetycenter.SafetyCenterEntry;
+import android.util.Log;
+
+import com.android.permissioncontroller.R;
+
+class SeverityIconPicker {
+
+ private static final String TAG = SeverityIconPicker.class.getSimpleName();
+
+ static int selectIconResId(int severityLevel, int severityUnspecifiedIconType) {
+ switch (severityLevel) {
+ case SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_UNKNOWN:
+ return R.drawable.ic_safety_null_state;
+ case SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_UNSPECIFIED:
+ return selectSeverityUnspecifiedIconResId(severityUnspecifiedIconType);
+ case SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_OK:
+ return R.drawable.ic_safety_info;
+ case SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_RECOMMENDATION:
+ return R.drawable.ic_safety_recommendation;
+ case SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_CRITICAL_WARNING:
+ return R.drawable.ic_safety_warn;
+ }
+ Log.e(TAG,
+ String.format(
+ "Unexpected SafetyCenterEntry.EntrySeverityLevel: %s", severityLevel));
+ return R.drawable.ic_safety_null_state;
+ }
+
+ private static int selectSeverityUnspecifiedIconResId(int severityUnspecifiedIconType) {
+ switch (severityUnspecifiedIconType) {
+ case SafetyCenterEntry.SEVERITY_UNSPECIFIED_ICON_TYPE_NO_ICON:
+ return R.drawable.ic_safety_empty;
+ case SafetyCenterEntry.SEVERITY_UNSPECIFIED_ICON_TYPE_PRIVACY:
+ return R.drawable.ic_privacy;
+ case SafetyCenterEntry.SEVERITY_UNSPECIFIED_ICON_TYPE_NO_RECOMMENDATION:
+ return R.drawable.ic_safety_null_state;
+ }
+ Log.e(TAG,
+ String.format(
+ "Unexpected SafetyCenterEntry.SeverityNoneIconType: %s",
+ severityUnspecifiedIconType));
+ return R.drawable.ic_safety_null_state;
+ }
+
+}