1 /*
2  * Copyright (C) 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.permissioncontroller.permission.ui.model;
18 
19 import android.content.Context;
20 
21 import androidx.preference.Preference;
22 import androidx.preference.PreferenceGroup;
23 
24 import com.android.permissioncontroller.permission.model.livedatatypes.PermGroupPackagesUiInfo;
25 
26 import java.util.ArrayList;
27 import java.util.List;
28 import java.util.Objects;
29 
30 /**
31  * Utils related to displaying permission groups in preferences.
32  */
33 public final class PermissionGroupPreferenceUtils {
34 
35     /**
36      * Update a {@link PreferenceGroup} with the specified permission groups.
37      */
updateGroupOfPermissionPreferences(Context context, PreferenceGroup preferenceGroup, List<PermGroupPackagesUiInfo> permissionGroups)38     public static void updateGroupOfPermissionPreferences(Context context,
39             PreferenceGroup preferenceGroup,
40             List<PermGroupPackagesUiInfo> permissionGroups) {
41         if (!(permissionGroups instanceof ArrayList)) {
42             permissionGroups = new ArrayList<>(permissionGroups);
43         }
44         if (!hasPermissionsListChanged(preferenceGroup, permissionGroups)) {
45             // The list of the permission groups has NOT changed. Only need to update summaries.
46             updatePreferenceSummaries(preferenceGroup, permissionGroups);
47             return;
48         }
49 
50         // The list of the permission groups has changed.
51         // 1. Iterate through the list of the permission groups, for each one check if there is
52         //    already exists a PermissionGroupPreference in the PreferenceGroup. If so - hold on to
53         //    it. If not - create a new one.
54         // 2. Clean the PreferenceGroup of all the Preferences.
55         // 3. Add PermissionGroupPreference, we cached or created on the step 1.
56         final List<Preference> preferences = new ArrayList<>();
57         for (int i = 0; i < permissionGroups.size(); i++) {
58             final PermGroupPackagesUiInfo info = permissionGroups.get(i);
59             PermissionGroupPreference preference = preferenceGroup.findPreference(info.getName());
60             if (preference == null) {
61                 preference = new PermissionGroupPreference(context, info);
62             } else {
63                 preference.updateSummary(info);
64                 // Reset the ordering back to default, so that when we add it back it falls into the
65                 // right place, and the preferences are ordered as we add them.
66                 preference.setOrder(Preference.DEFAULT_ORDER);
67             }
68             preferences.add(preference);
69         }
70         preferenceGroup.removeAll();
71         for (Preference preference : preferences) {
72             preferenceGroup.addPreference(preference);
73         }
74     }
75 
hasPermissionsListChanged(PreferenceGroup preferenceGroup, List<PermGroupPackagesUiInfo> permissionGroups)76     private static boolean hasPermissionsListChanged(PreferenceGroup preferenceGroup,
77             List<PermGroupPackagesUiInfo> permissionGroups) {
78         if (preferenceGroup.getPreferenceCount() != permissionGroups.size()) {
79             return true;
80         }
81 
82         for (int i = 0, size = permissionGroups.size(); i < size; i++) {
83             final String key = permissionGroups.get(i).getName();
84             // The key of the Preference that is currently at the i-th position in the
85             // PreferenceGroup.
86             final String existingKey = preferenceGroup.getPreference(i).getKey();
87             if (!Objects.equals(key, existingKey)) {
88                 return true;
89             }
90         }
91 
92         return false;
93     }
94 
updatePreferenceSummaries(PreferenceGroup preferenceGroup, List<PermGroupPackagesUiInfo> permissionGroups)95     private static void updatePreferenceSummaries(PreferenceGroup preferenceGroup,
96             List<PermGroupPackagesUiInfo> permissionGroups) {
97         for (int i = 0, size = permissionGroups.size(); i < size; i++) {
98             final PermissionGroupPreference preference =
99                     (PermissionGroupPreference) preferenceGroup.getPreference(i);
100             final PermGroupPackagesUiInfo info = permissionGroups.get(i);
101             preference.updateSummary(info);
102         }
103     }
104 
PermissionGroupPreferenceUtils()105     private PermissionGroupPreferenceUtils() {
106     }
107 }
108