ManagePermissionsFragment.java revision f5f6b1b113bb39a268948c19a39833d3ff839d32
1267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov/*
2267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov * Copyright (C) 2015 The Android Open Source Project
3267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov *
4267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov * Licensed under the Apache License, Version 2.0 (the "License");
5267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov * you may not use this file except in compliance with the License.
6267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov * You may obtain a copy of the License at
7267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov *
8267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov *      http://www.apache.org/licenses/LICENSE-2.0
9267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov *
10267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov * Unless required by applicable law or agreed to in writing, software
11267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov * distributed under the License is distributed on an "AS IS" BASIS,
12267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov * See the License for the specific language governing permissions and
14267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov * limitations under the License.
15267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov */
16267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovpackage com.android.packageinstaller.permission.ui;
17267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
18f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkertimport android.annotation.Nullable;
19267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.app.ActionBar;
20267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.app.FragmentTransaction;
21267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.content.ActivityNotFoundException;
22f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkertimport android.content.Context;
23267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.content.Intent;
24f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkertimport android.graphics.drawable.Drawable;
25267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.os.Bundle;
26f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkertimport android.support.v7.preference.Preference;
27f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkertimport android.support.v7.preference.Preference.OnPreferenceClickListener;
28f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkertimport android.support.v7.preference.PreferenceScreen;
299f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monkimport android.util.ArraySet;
30267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.util.Log;
31267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.view.Menu;
32267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.view.MenuInflater;
33267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.view.MenuItem;
34f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkertimport android.view.View;
35f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkertimport android.widget.ImageView;
36f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkertimport android.widget.TextView;
37267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
38267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport com.android.packageinstaller.R;
3993568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monkimport com.android.packageinstaller.permission.model.PermissionApps;
40f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monkimport com.android.packageinstaller.permission.model.PermissionApps.PmCache;
41267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport com.android.packageinstaller.permission.model.PermissionGroup;
42267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport com.android.packageinstaller.permission.model.PermissionGroups;
43267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport com.android.packageinstaller.permission.utils.Utils;
44267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
45267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport java.util.List;
46267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
47f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkertpublic final class ManagePermissionsFragment extends PermissionsFrameFragment
48267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        implements PermissionGroups.PermissionsGroupsChangeCallback, OnPreferenceClickListener {
49267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    private static final String LOG_TAG = "ManagePermissionsFragment";
50267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
51267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    private static final String OS_PKG = "android";
52267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
53f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk    private static final String EXTRA_PREFS_KEY = "extra_prefs_key";
54f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk
559f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monk    private ArraySet<String> mLauncherPkgs;
569f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monk
57267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    private PermissionGroups mPermissions;
58267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
59267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    private PreferenceScreen mExtraScreen;
60267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
61267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    private boolean mShowLegacyPermissions;
62267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
63267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public static ManagePermissionsFragment newInstance() {
64267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        return new ManagePermissionsFragment();
65267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
66267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
67267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    @Override
68267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public void onCreate(Bundle icicle) {
69267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        super.onCreate(icicle);
70a11e73b95ac5d664d57e860fa41a00c7a50720b7Todd Volkert        setLoading(true /* loading */, false /* animate */);
71267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        setHasOptionsMenu(true);
72267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        final ActionBar ab = getActivity().getActionBar();
73267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        if (ab != null) {
74267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            ab.setDisplayHomeAsUpEnabled(true);
75267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
769f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monk        mLauncherPkgs = Utils.getLauncherPackages(getContext());
77267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        mPermissions = new PermissionGroups(getActivity(), getLoaderManager(), this);
78267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
79267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
80267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    @Override
81267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public void onResume() {
82267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        super.onResume();
83267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        mPermissions.refresh();
84b8fa280183c0e893f194ce162ccfe8845f60e347Jason Monk        updatePermissionsUi();
85267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
86267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
87267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    @Override
88267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
89267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        super.onCreateOptionsMenu(menu, inflater);
90267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        inflater.inflate(R.menu.toggle_legacy_permissions, menu);
91267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
92267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
93267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    @Override
94267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public void onPrepareOptionsMenu(Menu menu) {
95267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        MenuItem item = menu.findItem(R.id.toggle_legacy_permissions);
96267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        if (!mShowLegacyPermissions) {
97267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            item.setTitle(R.string.show_legacy_permissions);
98267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        } else {
99267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            item.setTitle(R.string.hide_legacy_permissions);
100267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
101267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
102267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
103267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    @Override
104267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public boolean onOptionsItemSelected(MenuItem item) {
105267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        switch (item.getItemId()) {
106267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            case android.R.id.home: {
107267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                getActivity().finish();
108267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                return true;
109267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            }
110267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
111267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            case R.id.toggle_legacy_permissions: {
112267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                mShowLegacyPermissions = !mShowLegacyPermissions;
113267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                updatePermissionsUi();
114267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                return true;
115267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            }
116267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
117267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        return super.onOptionsItemSelected(item);
118267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
119267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
120267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    @Override
121267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public boolean onPreferenceClick(Preference preference) {
122267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        String key = preference.getKey();
123267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
124267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        PermissionGroup group = mPermissions.getGroup(key);
125267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        if (group == null) {
126267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            return false;
127267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
128267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
129267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSION_APPS)
130267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                .putExtra(Intent.EXTRA_PERMISSION_NAME, key);
131267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        try {
132267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            getActivity().startActivity(intent);
133267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        } catch (ActivityNotFoundException e) {
134267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            Log.w(LOG_TAG, "No app to handle " + intent);
135267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
136267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
137267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        return true;
138267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
139267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
140267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    @Override
141267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public void onPermissionGroupsChanged() {
142267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        updatePermissionsUi();
143267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
144267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
145f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert    @Override
146f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
147f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        super.onViewCreated(view, savedInstanceState);
14830366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert        bindPermissionUi(getActivity(), getView());
14930366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert    }
150f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert
15130366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert    private static void bindPermissionUi(@Nullable Context context, @Nullable View rootView) {
15230366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert        if (context == null || rootView == null) {
153f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert            return;
154f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        }
155f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert
156f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        ImageView iconView = (ImageView) rootView.findViewById(R.id.lb_icon);
157f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        if (iconView != null) {
158f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert            // Set the icon as the background instead of the image because ImageView
159f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert            // doesn't properly scale vector drawables beyond their intrinsic size
16030366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert            Drawable icon = context.getDrawable(R.drawable.ic_lock);
16130366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert            icon.setTint(context.getColor(R.color.off_white));
162f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert            iconView.setBackground(icon);
163f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        }
164f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        TextView titleView = (TextView) rootView.findViewById(R.id.lb_title);
165f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        if (titleView != null) {
166f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert            titleView.setText(R.string.app_permissions);
167f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        }
168f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        TextView breadcrumbView = (TextView) rootView.findViewById(R.id.lb_breadcrumb);
169f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        if (breadcrumbView != null) {
170f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert            breadcrumbView.setText(R.string.app_permissions_breadcrumb);
171f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        }
172f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert    }
173f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert
174f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert    private void updatePermissionsUi() {
175f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        Context context = getPreferenceManager().getContext();
176f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        if (context == null) {
177f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert            return;
178f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        }
179f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert
180267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        List<PermissionGroup> groups = mPermissions.getGroups();
181267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        PreferenceScreen screen = getPreferenceScreen();
182f5f6b1b113bb39a268948c19a39833d3ff839d32Todd Volkert        boolean isTelevision = Utils.isTelevision(context);
183267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
18493568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk        // Use this to speed up getting the info for all of the PermissionApps below.
18593568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk        // Create a new one for each refresh to make sure it has fresh data.
18693568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk        PmCache cache = new PmCache(getContext().getPackageManager());
187267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        for (PermissionGroup group : groups) {
18830366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert            boolean isModernGroup = Utils.isModernPermissionGroup(group.getName());
18930366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert            boolean isSystemPermission = group.getDeclaringPackage().equals(OS_PKG);
19030366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert
19130366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert            // Show legacy permissions only if the user chose that, except
19230366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert            // on TV, where they get grouped into the extra screen.
19330366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert            if (!mShowLegacyPermissions && !isTelevision && isSystemPermission && !isModernGroup) {
194267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                continue;
195267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            }
196267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
197f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            Preference preference = findPreference(group.getName());
198f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            if (preference == null && mExtraScreen != null) {
199f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                preference = mExtraScreen.findPreference(group.getName());
200f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            }
201f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            if (preference == null) {
202f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert                preference = new Preference(context);
203f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                preference.setOnPreferenceClickListener(this);
204f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                preference.setKey(group.getName());
205f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert                preference.setIcon(Utils.applyTint(context, group.getIcon(),
206f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                        android.R.attr.colorControlNormal));
207f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                preference.setTitle(group.getLabel());
208140154b8965eb599ea79991462fce46daa4ce8dbJason Monk                // Set blank summary so that no resizing/jumping happens when the summary is loaded.
209140154b8965eb599ea79991462fce46daa4ce8dbJason Monk                preference.setSummary(" ");
210f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                preference.setPersistent(false);
21130366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert                if (isSystemPermission && (isModernGroup || !isTelevision)) {
212f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                    screen.addPreference(preference);
213f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                } else {
214f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                    if (mExtraScreen == null) {
215f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert                        mExtraScreen = getPreferenceManager().createPreferenceScreen(context);
216f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                    }
217f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                    mExtraScreen.addPreference(preference);
218f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                }
219f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            }
220f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            final Preference finalPref = preference;
221f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk
22293568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk            new PermissionApps(getContext(), group.getName(), new PermissionApps.Callback() {
22393568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk                @Override
22493568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk                public void onPermissionsLoaded(PermissionApps permissionApps) {
225ac39d5041cc12eb83d71261ad33e936bc53d96b1Svet Ganov                    if (getActivity() == null) {
226ac39d5041cc12eb83d71261ad33e936bc53d96b1Svet Ganov                        return;
227ac39d5041cc12eb83d71261ad33e936bc53d96b1Svet Ganov                    }
2289f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monk                    int granted = permissionApps.getGrantedCount(mLauncherPkgs);
2299f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monk                    int total = permissionApps.getTotalCount(mLauncherPkgs);
230f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                    finalPref.setSummary(getString(R.string.app_permissions_group_summary,
23193568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk                            granted, total));
23293568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk                }
23393568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk            }, cache).refresh(false);
234267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
235267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
236f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk        if (mExtraScreen != null && mExtraScreen.getPreferenceCount() > 0
237f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                && screen.findPreference(EXTRA_PREFS_KEY) == null) {
238f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert            Preference extraScreenPreference = new Preference(context);
239f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            extraScreenPreference.setKey(EXTRA_PREFS_KEY);
240f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert            extraScreenPreference.setIcon(Utils.applyTint(context, R.drawable.ic_toc,
241f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert                    android.R.attr.colorControlNormal));
242267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            extraScreenPreference.setTitle(R.string.additional_permissions);
243267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            extraScreenPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
244267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                @Override
245267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                public boolean onPreferenceClick(Preference preference) {
246267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    AdditionalPermissionsFragment frag = new AdditionalPermissionsFragment();
247267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    frag.setTargetFragment(ManagePermissionsFragment.this, 0);
248267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    FragmentTransaction ft = getFragmentManager().beginTransaction();
249267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    ft.replace(android.R.id.content, frag);
250f5f6b1b113bb39a268948c19a39833d3ff839d32Todd Volkert                    ft.addToBackStack(null);
251267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    ft.commit();
252267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    return true;
253267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                }
254267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            });
25591bc7980041628fb807ee19f5588abe5615be26bJason Monk            int count = mExtraScreen.getPreferenceCount();
25691bc7980041628fb807ee19f5588abe5615be26bJason Monk            extraScreenPreference.setSummary(getResources().getQuantityString(
25791bc7980041628fb807ee19f5588abe5615be26bJason Monk                    R.plurals.additional_permissions_more, count, count));
258267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            screen.addPreference(extraScreenPreference);
259267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
26039e9a82e0d5ea964f6ad187669e4358da40a132aJason Monk        if (screen.getPreferenceCount() != 0) {
261a11e73b95ac5d664d57e860fa41a00c7a50720b7Todd Volkert            setLoading(false /* loading */, true /* animate */);
26239e9a82e0d5ea964f6ad187669e4358da40a132aJason Monk        }
263267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
264267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
26530366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert    public static class AdditionalPermissionsFragment extends PermissionsFrameFragment {
266267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        @Override
267267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        public void onCreate(Bundle icicle) {
268a11e73b95ac5d664d57e860fa41a00c7a50720b7Todd Volkert            setLoading(true /* loading */, false /* animate */);
269267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            super.onCreate(icicle);
270f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            getActivity().setTitle(R.string.additional_permissions);
271f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            setHasOptionsMenu(true);
272267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
273267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
274267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        @Override
275f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk        public void onDestroy() {
276f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            getActivity().setTitle(R.string.app_permissions);
277f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            super.onDestroy();
278267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
279f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk
280f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk        @Override
281f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk        public boolean onOptionsItemSelected(MenuItem item) {
282f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            switch (item.getItemId()) {
283f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                case android.R.id.home:
284f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                    getFragmentManager().popBackStack();
285f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                    return true;
286f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            }
287f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            return super.onOptionsItemSelected(item);
288f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk        }
289f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk
290f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        @Override
29130366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert        public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
29230366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert            super.onViewCreated(view, savedInstanceState);
29330366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert            bindPermissionUi(getActivity(), getView());
29430366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert        }
29530366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert
29630366743234bbdcbd2f6f638e3d6c364207a9400Todd Volkert        @Override
297f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
298f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert            setPreferenceScreen(((ManagePermissionsFragment) getTargetFragment()).mExtraScreen);
299a11e73b95ac5d664d57e860fa41a00c7a50720b7Todd Volkert            setLoading(false /* loading */, true /* animate */);
300f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert        }
301267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
302267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov}
303