1 /*
2  * Copyright (C) 2019 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.auto;
18 
19 import android.content.ActivityNotFoundException;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.os.Bundle;
23 import android.util.Log;
24 
25 import androidx.annotation.Nullable;
26 import androidx.annotation.StringRes;
27 import androidx.preference.Preference;
28 
29 import com.android.permissioncontroller.R;
30 import com.android.permissioncontroller.auto.AutoSettingsFrameFragment;
31 import com.android.permissioncontroller.permission.model.legacy.PermissionGroup;
32 import com.android.permissioncontroller.permission.model.legacy.PermissionGroups;
33 import com.android.permissioncontroller.permission.utils.Utils;
34 
35 import java.text.Collator;
36 import java.util.ArrayList;
37 
38 /** Base class to show the list of permissions that can be granted/denied. */
39 abstract class AutoManagePermissionsFragment extends AutoSettingsFrameFragment implements
40         PermissionGroups.PermissionsGroupsChangeCallback, Preference.OnPreferenceClickListener {
41 
42     private static final String LOG_TAG = "ManagePermissionsFragment";
43 
44     static final String OS_PKG = "android";
45 
46     private PermissionGroups mPermissions;
47 
48     private Collator mCollator;
49 
50     @Override
onCreate(@ullable Bundle savedInstanceState)51     public void onCreate(@Nullable Bundle savedInstanceState) {
52         super.onCreate(savedInstanceState);
53         setLoading(true);
54 
55         mPermissions = new PermissionGroups(getContext(), requireActivity().getLoaderManager(),
56                 /* callback= */ this, /* getAppUiInfo= */ false,
57                 /* getNonPlatformPermissions= */ true);
58         mCollator = Collator.getInstance(
59                 getContext().getResources().getConfiguration().getLocales().get(0));
60 
61         setHeaderLabel(getString(getScreenHeaderRes()));
62     }
63 
64     @Override
onCreatePreferences(Bundle bundle, String s)65     public void onCreatePreferences(Bundle bundle, String s) {
66         setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getContext()));
67     }
68 
69     @Override
onPreferenceClick(Preference preference)70     public boolean onPreferenceClick(Preference preference) {
71         String key = preference.getKey();
72 
73         PermissionGroup group = mPermissions.getGroup(key);
74         if (group == null) {
75             return false;
76         }
77 
78         Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSION_APPS)
79                 .putExtra(Intent.EXTRA_PERMISSION_NAME, key);
80         try {
81             getActivity().startActivity(intent);
82         } catch (ActivityNotFoundException e) {
83             Log.w(LOG_TAG, "No app to handle " + intent);
84         }
85 
86         return true;
87     }
88 
89     /** Returns the header string resource. */
90     @StringRes
getScreenHeaderRes()91     protected abstract int getScreenHeaderRes();
92 
93     /** Returns the current permissions. */
getPermissions()94     protected PermissionGroups getPermissions() {
95         return mPermissions;
96     }
97 
98     @Override
onPermissionGroupsChanged()99     public void onPermissionGroupsChanged() {
100         updatePermissionsUi();
101     }
102 
103     /** Update the preferences to show the new {@link #getPermissions() permissions}. */
updatePermissionsUi()104     protected abstract void updatePermissionsUi();
105 
106     /**
107      * Add preferences for all permissions of a type to the preference screen.
108      */
updatePermissionsUi(boolean addSystemPermissions)109     protected void updatePermissionsUi(boolean addSystemPermissions) {
110         Context context = getPreferenceManager().getContext();
111         if (context == null || getActivity() == null) {
112             return;
113         }
114 
115         ArrayList<PermissionGroup> groups = new ArrayList<>(mPermissions.getGroups());
116         groups.sort((x, y) -> mCollator.compare(x.getLabel(), y.getLabel()));
117         getPreferenceScreen().removeAll();
118         getPreferenceScreen().setOrderingAsAdded(true);
119 
120         // Use this to speed up getting the info for all of the PermissionApps below.
121         // Create a new one for each refresh to make sure it has fresh data.
122         for (int i = 0; i < groups.size(); i++) {
123             PermissionGroup group = groups.get(i);
124             boolean isSystemPermission = group.getDeclaringPackage().equals(OS_PKG);
125 
126             if (addSystemPermissions == isSystemPermission) {
127                 Preference preference = findPreference(group.getName());
128 
129                 if (preference == null) {
130                     preference = new Preference(context);
131                     preference.setOnPreferenceClickListener(this);
132                     preference.setKey(group.getName());
133                     preference.setIcon(Utils.applyTint(context, group.getIcon(),
134                             android.R.attr.colorControlNormal));
135                     preference.setTitle(group.getLabel());
136                     // Set blank summary so that no resizing/jumping happens when the summary is
137                     // loaded.
138                     preference.setSummary(" ");
139                     preference.setPersistent(false);
140                     getPreferenceScreen().addPreference(preference);
141                 }
142                 preference.setSummary(
143                         getString(R.string.app_permissions_group_summary, group.getGranted(),
144                                 group.getTotal()));
145             }
146         }
147         if (getPreferenceScreen().getPreferenceCount() != 0) {
148             setLoading(false);
149         }
150     }
151 }
152