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