1 /*
2  * Copyright (C) 2015 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 package com.android.packageinstaller.permission.ui.television;
17 
18 import android.annotation.Nullable;
19 import android.app.ActionBar;
20 import android.app.FragmentTransaction;
21 import android.content.ActivityNotFoundException;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.os.Bundle;
25 import android.support.v7.preference.Preference;
26 import android.support.v7.preference.Preference.OnPreferenceClickListener;
27 import android.support.v7.preference.PreferenceScreen;
28 import android.util.ArraySet;
29 import android.util.Log;
30 import android.view.MenuItem;
31 import android.view.View;
32 
33 import com.android.packageinstaller.R;
34 import com.android.packageinstaller.permission.model.PermissionApps;
35 import com.android.packageinstaller.permission.model.PermissionApps.PmCache;
36 import com.android.packageinstaller.permission.model.PermissionGroup;
37 import com.android.packageinstaller.permission.model.PermissionGroups;
38 import com.android.packageinstaller.permission.utils.Utils;
39 
40 import java.util.List;
41 
42 public final class ManagePermissionsFragment extends SettingsWithHeader
43         implements PermissionGroups.PermissionsGroupsChangeCallback, OnPreferenceClickListener {
44     private static final String LOG_TAG = "ManagePermissionsFragment";
45 
46     private static final String OS_PKG = "android";
47 
48     private static final String EXTRA_PREFS_KEY = "extra_prefs_key";
49 
50     private ArraySet<String> mLauncherPkgs;
51 
52     private PermissionGroups mPermissions;
53 
54     private PreferenceScreen mExtraScreen;
55 
newInstance()56     public static ManagePermissionsFragment newInstance() {
57         return new ManagePermissionsFragment();
58     }
59 
60     @Override
onCreate(Bundle icicle)61     public void onCreate(Bundle icicle) {
62         super.onCreate(icicle);
63         setLoading(true /* loading */, false /* animate */);
64         setHasOptionsMenu(true);
65         final ActionBar ab = getActivity().getActionBar();
66         if (ab != null) {
67             ab.setDisplayHomeAsUpEnabled(true);
68         }
69         mLauncherPkgs = Utils.getLauncherPackages(getContext());
70         mPermissions = new PermissionGroups(getActivity(), getLoaderManager(), this);
71     }
72 
73     @Override
onResume()74     public void onResume() {
75         super.onResume();
76         mPermissions.refresh();
77         updatePermissionsUi();
78     }
79 
80     @Override
onOptionsItemSelected(MenuItem item)81     public boolean onOptionsItemSelected(MenuItem item) {
82         if (item.getItemId() == android.R.id.home) {
83             getActivity().finish();
84             return true;
85         }
86         return super.onOptionsItemSelected(item);
87     }
88 
89     @Override
onPreferenceClick(Preference preference)90     public boolean onPreferenceClick(Preference preference) {
91         String key = preference.getKey();
92 
93         PermissionGroup group = mPermissions.getGroup(key);
94         if (group == null) {
95             return false;
96         }
97 
98         Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSION_APPS)
99                 .putExtra(Intent.EXTRA_PERMISSION_NAME, key);
100         try {
101             getActivity().startActivity(intent);
102         } catch (ActivityNotFoundException e) {
103             Log.w(LOG_TAG, "No app to handle " + intent);
104         }
105 
106         return true;
107     }
108 
109     @Override
onPermissionGroupsChanged()110     public void onPermissionGroupsChanged() {
111         updatePermissionsUi();
112     }
113 
114     @Override
onViewCreated(View view, Bundle savedInstanceState)115     public void onViewCreated(View view, Bundle savedInstanceState) {
116         super.onViewCreated(view, savedInstanceState);
117         bindPermissionUi(this, getView());
118     }
119 
bindPermissionUi(SettingsWithHeader fragment, @Nullable View rootView)120     private static void bindPermissionUi(SettingsWithHeader fragment, @Nullable View rootView) {
121         if (fragment == null || rootView == null) {
122             return;
123         }
124         fragment.setHeader(null, null, null, fragment.getString(
125                 R.string.manage_permissions_decor_title));
126     }
127 
updatePermissionsUi()128     private void updatePermissionsUi() {
129         Context context = getPreferenceManager().getContext();
130         if (context == null) {
131             return;
132         }
133 
134         List<PermissionGroup> groups = mPermissions.getGroups();
135         PreferenceScreen screen = getPreferenceScreen();
136 
137         // Use this to speed up getting the info for all of the PermissionApps below.
138         // Create a new one for each refresh to make sure it has fresh data.
139         PmCache cache = new PmCache(getContext().getPackageManager());
140         for (PermissionGroup group : groups) {
141             boolean isSystemPermission = group.getDeclaringPackage().equals(OS_PKG);
142 
143             Preference preference = findPreference(group.getName());
144             if (preference == null && mExtraScreen != null) {
145                 preference = mExtraScreen.findPreference(group.getName());
146             }
147             if (preference == null) {
148                 preference = new Preference(context);
149                 preference.setOnPreferenceClickListener(this);
150                 preference.setKey(group.getName());
151                 preference.setIcon(Utils.applyTint(context, group.getIcon(),
152                         android.R.attr.colorControlNormal));
153                 preference.setTitle(group.getLabel());
154                 // Set blank summary so that no resizing/jumping happens when the summary is loaded.
155                 preference.setSummary(" ");
156                 preference.setPersistent(false);
157                 if (isSystemPermission) {
158                     screen.addPreference(preference);
159                 } else {
160                     if (mExtraScreen == null) {
161                         mExtraScreen = getPreferenceManager().createPreferenceScreen(context);
162                     }
163                     mExtraScreen.addPreference(preference);
164                 }
165             }
166             final Preference finalPref = preference;
167 
168             new PermissionApps(getContext(), group.getName(), new PermissionApps.Callback() {
169                 @Override
170                 public void onPermissionsLoaded(PermissionApps permissionApps) {
171                     if (getActivity() == null) {
172                         return;
173                     }
174                     int granted = permissionApps.getGrantedCount(mLauncherPkgs);
175                     int total = permissionApps.getTotalCount(mLauncherPkgs);
176                     finalPref.setSummary(getString(R.string.app_permissions_group_summary,
177                             granted, total));
178                 }
179             }, cache).refresh(false);
180         }
181 
182         if (mExtraScreen != null && mExtraScreen.getPreferenceCount() > 0
183                 && screen.findPreference(EXTRA_PREFS_KEY) == null) {
184             Preference extraScreenPreference = new Preference(context);
185             extraScreenPreference.setKey(EXTRA_PREFS_KEY);
186             extraScreenPreference.setIcon(Utils.applyTint(context,
187                     R.drawable.ic_more_items,
188                     android.R.attr.colorControlNormal));
189             extraScreenPreference.setTitle(R.string.additional_permissions);
190             extraScreenPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
191                 @Override
192                 public boolean onPreferenceClick(Preference preference) {
193                     AdditionalPermissionsFragment frag = new AdditionalPermissionsFragment();
194                     frag.setTargetFragment(ManagePermissionsFragment.this, 0);
195                     FragmentTransaction ft = getFragmentManager().beginTransaction();
196                     ft.replace(android.R.id.content, frag);
197                     ft.addToBackStack(null);
198                     ft.commit();
199                     return true;
200                 }
201             });
202             int count = mExtraScreen.getPreferenceCount();
203             extraScreenPreference.setSummary(getResources().getQuantityString(
204                     R.plurals.additional_permissions_more, count, count));
205             screen.addPreference(extraScreenPreference);
206         }
207         if (screen.getPreferenceCount() != 0) {
208             setLoading(false /* loading */, true /* animate */);
209         }
210     }
211 
212     public static class AdditionalPermissionsFragment extends SettingsWithHeader {
213         @Override
onCreate(Bundle icicle)214         public void onCreate(Bundle icicle) {
215             setLoading(true /* loading */, false /* animate */);
216             super.onCreate(icicle);
217             getActivity().setTitle(R.string.additional_permissions);
218             setHasOptionsMenu(true);
219         }
220 
221         @Override
onDestroy()222         public void onDestroy() {
223             getActivity().setTitle(R.string.app_permissions);
224             super.onDestroy();
225         }
226 
227         @Override
onOptionsItemSelected(MenuItem item)228         public boolean onOptionsItemSelected(MenuItem item) {
229             switch (item.getItemId()) {
230                 case android.R.id.home:
231                     getFragmentManager().popBackStack();
232                     return true;
233             }
234             return super.onOptionsItemSelected(item);
235         }
236 
237         @Override
onViewCreated(View view, Bundle savedInstanceState)238         public void onViewCreated(View view, Bundle savedInstanceState) {
239             super.onViewCreated(view, savedInstanceState);
240             bindPermissionUi(this, getView());
241         }
242 
bindPermissionUi(SettingsWithHeader fragment, @Nullable View rootView)243         private static void bindPermissionUi(SettingsWithHeader fragment, @Nullable View rootView) {
244             if (fragment == null || rootView == null) {
245                 return;
246             }
247             fragment.setHeader(null, null, null,
248                     fragment.getString(R.string.additional_permissions_decor_title));
249         }
250 
251         @Override
onCreatePreferences(Bundle savedInstanceState, String rootKey)252         public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
253             setPreferenceScreen(((ManagePermissionsFragment) getTargetFragment()).mExtraScreen);
254             setLoading(false /* loading */, true /* animate */);
255         }
256     }
257 }
258