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.auto;
18 
19 import android.app.Application;
20 import android.content.Context;
21 import android.os.Bundle;
22 import android.view.View;
23 
24 import androidx.annotation.NonNull;
25 import androidx.annotation.Nullable;
26 import androidx.lifecycle.ViewModelProvider;
27 import androidx.preference.PreferenceCategory;
28 import androidx.preference.PreferenceScreen;
29 
30 import com.android.permissioncontroller.R;
31 import com.android.permissioncontroller.auto.AutoSettingsFrameFragment;
32 import com.android.permissioncontroller.permission.model.livedatatypes.PermGroupPackagesUiInfo;
33 import com.android.permissioncontroller.permission.ui.model.ManagePermissionsViewModel;
34 import com.android.permissioncontroller.permission.ui.model.PermissionGroupPreferenceUtils;
35 
36 import java.util.List;
37 
38 /**
39  * Shows additional non-system permissions that can be granted/denied.
40  *
41  * Largely based on
42  * {@link com.android.permissioncontroller.permission.ui.television.ManagePermissionsOtherFragment}.
43  */
44 public class AutoManageOtherPermissionsFragment extends AutoSettingsFrameFragment {
45     private static final String KEY_UNUSED_CATEGORY = "category_unused";
46     private static final String KEY_ADDITIONAL_CATEGORY = "category_additional";
47 
48     private PreferenceCategory mUnusedCategory;
49     private PreferenceCategory mAdditionalCategory;
50 
51     @Override
onCreate(@ullable Bundle savedInstanceState)52     public void onCreate(@Nullable Bundle savedInstanceState) {
53         super.onCreate(savedInstanceState);
54         setLoading(true);
55         setHeaderLabel(getString(R.string.other_permissions_label));
56 
57         final Application application = getActivity().getApplication();
58         final ViewModelProvider.Factory factory =
59                 ViewModelProvider.AndroidViewModelFactory.getInstance(application);
60         final ManagePermissionsViewModel viewModel = new ViewModelProvider(this, factory)
61                 .get(ManagePermissionsViewModel.class);
62 
63         viewModel.getUnusedPermissionGroups().observe(this, this::onUnusedPermissionGroupsChanged);
64         viewModel.getAdditionalPermissionGroups().observe(this,
65                 this::onAdditionalPermissionGroupsChanged);
66         viewModel.hasUnusedOrAdditionalPermissionGroups().observe(this,
67                 this::onHasUnusedOrAdditionalPermissionGroups);
68     }
69 
70     @Override
onCreatePreferences(Bundle bundle, String s)71     public void onCreatePreferences(Bundle bundle, String s) {
72         setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getContext()));
73     }
74 
75     @Override
onViewCreated(@onNull View view, @Nullable Bundle savedInstanceState)76     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
77         super.onViewCreated(view, savedInstanceState);
78 
79         final Context context = getPreferenceManager().getContext();
80         final PreferenceScreen screen = getPreferenceScreen();
81         // We add categories here, but make them invisible until the data is loaded.
82         mUnusedCategory = new PreferenceCategory(context);
83         mUnusedCategory.setKey(KEY_UNUSED_CATEGORY);
84         mUnusedCategory.setTitle(R.string.not_used_permissions_label);
85         mUnusedCategory.setSummary(R.string.not_used_permissions_description);
86         mUnusedCategory.setVisible(false);
87         screen.addPreference(mUnusedCategory);
88 
89         mAdditionalCategory = new PreferenceCategory(context);
90         mAdditionalCategory.setKey(KEY_ADDITIONAL_CATEGORY);
91         mAdditionalCategory.setTitle(R.string.additional_permissions_label);
92         mAdditionalCategory.setSummary(R.string.additional_permissions_description);
93         mAdditionalCategory.setVisible(false);
94         screen.addPreference(mAdditionalCategory);
95     }
96 
onUnusedPermissionGroupsChanged(List<PermGroupPackagesUiInfo> permissionGroups)97     private void onUnusedPermissionGroupsChanged(List<PermGroupPackagesUiInfo> permissionGroups) {
98         updateCategory(mUnusedCategory, permissionGroups);
99     }
100 
onAdditionalPermissionGroupsChanged( List<PermGroupPackagesUiInfo> permissionGroups)101     private void onAdditionalPermissionGroupsChanged(
102             List<PermGroupPackagesUiInfo> permissionGroups) {
103         updateCategory(mAdditionalCategory, permissionGroups);
104     }
105 
onHasUnusedOrAdditionalPermissionGroups(Boolean hasPGs)106     private void onHasUnusedOrAdditionalPermissionGroups(Boolean hasPGs) {
107         if (!hasPGs) {
108             // There are not more permissions on this screen - go back.
109             getParentFragmentManager().popBackStack();
110         }
111     }
112 
updateCategory(PreferenceCategory category, List<PermGroupPackagesUiInfo> permissionGroups)113     private void updateCategory(PreferenceCategory category,
114             List<PermGroupPackagesUiInfo> permissionGroups) {
115         final Context context = getPreferenceManager().getContext();
116         if (context == null) {
117             return;
118         }
119 
120         PermissionGroupPreferenceUtils.updateGroupOfPermissionPreferences(context, category,
121                 permissionGroups);
122         // Only show the category if it's not empty.
123         category.setVisible(!permissionGroups.isEmpty());
124 
125         setLoading(false);
126     }
127 }
128