ManagePermissionsFragment.java revision f9ffffb3b507a797ad1ead81cbff5f4935956e4c
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.Activity;
21267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.app.FragmentTransaction;
22267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.content.ActivityNotFoundException;
23267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.content.Intent;
24f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkertimport android.graphics.drawable.Drawable;
25267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.os.Bundle;
26267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.preference.Preference;
27267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.preference.Preference.OnPreferenceClickListener;
28267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.preference.PreferenceFragment;
29267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.preference.PreferenceScreen;
309f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monkimport android.util.ArraySet;
31267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.util.Log;
32f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkertimport android.view.LayoutInflater;
33267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.view.Menu;
34267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.view.MenuInflater;
35267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport android.view.MenuItem;
36f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkertimport android.view.View;
37f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkertimport android.view.ViewGroup;
38f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkertimport android.widget.ImageView;
39f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkertimport android.widget.ListView;
40f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkertimport android.widget.TextView;
41267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
42267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport com.android.packageinstaller.R;
4393568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monkimport com.android.packageinstaller.permission.model.PermissionApps;
44f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monkimport com.android.packageinstaller.permission.model.PermissionApps.PmCache;
45267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport com.android.packageinstaller.permission.model.PermissionGroup;
46267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport com.android.packageinstaller.permission.model.PermissionGroups;
47267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport com.android.packageinstaller.permission.utils.Utils;
48267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
49267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport java.util.List;
50267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
51267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovpublic final class ManagePermissionsFragment extends PreferenceFragment
52267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        implements PermissionGroups.PermissionsGroupsChangeCallback, OnPreferenceClickListener {
53267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    private static final String LOG_TAG = "ManagePermissionsFragment";
54267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
55267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    private static final String OS_PKG = "android";
56267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
57f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk    private static final String EXTRA_PREFS_KEY = "extra_prefs_key";
58f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk
599f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monk    private ArraySet<String> mLauncherPkgs;
609f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monk
61267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    private PermissionGroups mPermissions;
62267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
63267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    private PreferenceScreen mExtraScreen;
64267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
65267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    private boolean mShowLegacyPermissions;
66267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
67267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public static ManagePermissionsFragment newInstance() {
68267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        return new ManagePermissionsFragment();
69267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
70267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
71267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    @Override
72267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public void onCreate(Bundle icicle) {
73267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        super.onCreate(icicle);
74267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        setHasOptionsMenu(true);
75267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        final ActionBar ab = getActivity().getActionBar();
76267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        if (ab != null) {
77267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            ab.setDisplayHomeAsUpEnabled(true);
78267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
799f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monk        mLauncherPkgs = Utils.getLauncherPackages(getContext());
80267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        mPermissions = new PermissionGroups(getActivity(), getLoaderManager(), this);
81267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
82267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
83267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    @Override
84267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public void onResume() {
85267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        super.onResume();
86267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        mPermissions.refresh();
87b8fa280183c0e893f194ce162ccfe8845f60e347Jason Monk        updatePermissionsUi();
88267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
89267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
90267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    @Override
91267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
92267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        super.onCreateOptionsMenu(menu, inflater);
93267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        inflater.inflate(R.menu.toggle_legacy_permissions, menu);
94267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
95267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
96267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    @Override
97267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public void onPrepareOptionsMenu(Menu menu) {
98267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        MenuItem item = menu.findItem(R.id.toggle_legacy_permissions);
99267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        if (!mShowLegacyPermissions) {
100267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            item.setTitle(R.string.show_legacy_permissions);
101267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        } else {
102267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            item.setTitle(R.string.hide_legacy_permissions);
103267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
104267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
105267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
106267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    @Override
107267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public boolean onOptionsItemSelected(MenuItem item) {
108267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        switch (item.getItemId()) {
109267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            case android.R.id.home: {
110267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                getActivity().finish();
111267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                return true;
112267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            }
113267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
114267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            case R.id.toggle_legacy_permissions: {
115267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                mShowLegacyPermissions = !mShowLegacyPermissions;
116267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                updatePermissionsUi();
117267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                return true;
118267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            }
119267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
120267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        return super.onOptionsItemSelected(item);
121267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
122267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
123267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    @Override
124267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public boolean onPreferenceClick(Preference preference) {
125267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        String key = preference.getKey();
126267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
127267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        PermissionGroup group = mPermissions.getGroup(key);
128267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        if (group == null) {
129267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            return false;
130267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
131267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
132267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSION_APPS)
133267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                .putExtra(Intent.EXTRA_PERMISSION_NAME, key);
134267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        try {
135267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            getActivity().startActivity(intent);
136267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        } catch (ActivityNotFoundException e) {
137267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            Log.w(LOG_TAG, "No app to handle " + intent);
138267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
139267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
140267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        return true;
141267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
142267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
143267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    @Override
144267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    public void onPermissionGroupsChanged() {
145267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        updatePermissionsUi();
146267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
147267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
148f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert    @Override
149f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert    public View onCreateView(LayoutInflater inflater, ViewGroup container,
150f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert            Bundle savedInstanceState) {
151f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.permissions_frame, container,
152f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert                false);
153f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        ViewGroup prefsContainer = (ViewGroup) rootView.findViewById(R.id.prefs_container);
154f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        if (prefsContainer == null) {
155f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert            prefsContainer = rootView;
156f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        }
157f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        prefsContainer.addView(super.onCreateView(inflater, prefsContainer, savedInstanceState));
158f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        View emptyView = rootView.findViewById(R.id.no_permissions);
159f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        ((ListView) rootView.findViewById(android.R.id.list)).setEmptyView(emptyView);
160f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        return rootView;
161f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert    }
162f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert
163f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert    @Override
164f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
165f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        super.onViewCreated(view, savedInstanceState);
166f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        updatePermissionsUi();
167f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert    }
168f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert
169267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    private void updatePermissionsUi() {
170267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        Activity activity = getActivity();
171267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
172267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        if (activity == null) {
173267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            return;
174267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
175267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
176f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        final ViewGroup rootView = (ViewGroup) getView();
177f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        if (rootView != null) {
178f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert            final ImageView iconView = (ImageView) rootView.findViewById(R.id.lb_icon);
179f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert            if (iconView != null) {
180f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert                // Set the icon as the background instead of the image because ImageView
181f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert                // doesn't properly scale vector drawables beyond their intrinsic size
182f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert                Drawable icon = activity.getDrawable(R.drawable.ic_lock);
183f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert                icon.setTint(activity.getColor(R.color.off_white));
184f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert                iconView.setBackground(icon);
185f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert            }
186f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert            final TextView titleView = (TextView) rootView.findViewById(R.id.lb_title);
187f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert            if (titleView != null) {
188f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert                titleView.setText(R.string.app_permissions);
189f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert            }
190f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert            final TextView breadcrumbView = (TextView) rootView.findViewById(R.id.lb_breadcrumb);
191f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert            if (breadcrumbView != null) {
192f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert                breadcrumbView.setText(R.string.app_permissions_breadcrumb);
193f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert            }
194f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert        }
195f9ffffb3b507a797ad1ead81cbff5f4935956e4cTodd Volkert
196267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        List<PermissionGroup> groups = mPermissions.getGroups();
197267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
198267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        PreferenceScreen screen = getPreferenceScreen();
199267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        if (screen == null) {
200267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            screen = getPreferenceManager().createPreferenceScreen(activity);
201267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            setPreferenceScreen(screen);
202267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
203267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
20493568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk        // Use this to speed up getting the info for all of the PermissionApps below.
20593568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk        // Create a new one for each refresh to make sure it has fresh data.
20693568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk        PmCache cache = new PmCache(getContext().getPackageManager());
207267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        for (PermissionGroup group : groups) {
208267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            // Show legacy permissions only if the user chose that.
209267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            if (!mShowLegacyPermissions && group.getDeclaringPackage().equals(OS_PKG)
210267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    && !Utils.isModernPermissionGroup(group.getName())) {
211267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                continue;
212267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            }
213267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
214f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            Preference preference = findPreference(group.getName());
215f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            if (preference == null && mExtraScreen != null) {
216f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                preference = mExtraScreen.findPreference(group.getName());
217f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            }
218f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            if (preference == null) {
219f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                preference = new Preference(activity, null);
220f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                preference.setOnPreferenceClickListener(this);
221f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                preference.setKey(group.getName());
222f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                preference.setIcon(Utils.applyTint(activity, group.getIcon(),
223f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                        android.R.attr.colorControlNormal));
224f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                preference.setTitle(group.getLabel());
225140154b8965eb599ea79991462fce46daa4ce8dbJason Monk                // Set blank summary so that no resizing/jumping happens when the summary is loaded.
226140154b8965eb599ea79991462fce46daa4ce8dbJason Monk                preference.setSummary(" ");
227f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                preference.setPersistent(false);
228f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                if (group.getDeclaringPackage().equals(OS_PKG)) {
229f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                    screen.addPreference(preference);
230f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                } else {
231f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                    if (mExtraScreen == null) {
232f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                        mExtraScreen = getPreferenceManager().createPreferenceScreen(activity);
233f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                    }
234f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                    mExtraScreen.addPreference(preference);
235f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                }
236f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            }
237f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            final Preference finalPref = preference;
238f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk
23993568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk            new PermissionApps(getContext(), group.getName(), new PermissionApps.Callback() {
24093568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk                @Override
24193568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk                public void onPermissionsLoaded(PermissionApps permissionApps) {
242ac39d5041cc12eb83d71261ad33e936bc53d96b1Svet Ganov                    if (getActivity() == null) {
243ac39d5041cc12eb83d71261ad33e936bc53d96b1Svet Ganov                        return;
244ac39d5041cc12eb83d71261ad33e936bc53d96b1Svet Ganov                    }
2459f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monk                    int granted = permissionApps.getGrantedCount(mLauncherPkgs);
2469f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monk                    int total = permissionApps.getTotalCount(mLauncherPkgs);
247f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                    finalPref.setSummary(getString(R.string.app_permissions_group_summary,
24893568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk                            granted, total));
24993568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk                }
25093568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk            }, cache).refresh(false);
251267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
252267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
253f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk        if (mExtraScreen != null && mExtraScreen.getPreferenceCount() > 0
254f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                && screen.findPreference(EXTRA_PREFS_KEY) == null) {
255267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            Preference extraScreenPreference = new Preference(activity);
256f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            extraScreenPreference.setKey(EXTRA_PREFS_KEY);
257267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            extraScreenPreference.setIcon(R.drawable.ic_toc);
258267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            extraScreenPreference.setTitle(R.string.additional_permissions);
259267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            extraScreenPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
260267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                @Override
261267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                public boolean onPreferenceClick(Preference preference) {
262267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    AdditionalPermissionsFragment frag = new AdditionalPermissionsFragment();
263267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    frag.setTargetFragment(ManagePermissionsFragment.this, 0);
264267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    FragmentTransaction ft = getFragmentManager().beginTransaction();
265267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    ft.replace(android.R.id.content, frag);
266267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    ft.addToBackStack("AdditionalPerms");
267267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    ft.commit();
268267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    return true;
269267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                }
270267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            });
271267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            extraScreenPreference.setSummary(getString(R.string.additional_permissions_more,
272267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov                    mExtraScreen.getPreferenceCount()));
273267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            screen.addPreference(extraScreenPreference);
274267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
275267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
276267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
277f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk    public static class AdditionalPermissionsFragment extends PreferenceFragment {
278267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        @Override
279267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        public void onCreate(Bundle icicle) {
280267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            super.onCreate(icicle);
281f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            getActivity().setTitle(R.string.additional_permissions);
282267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov            setPreferenceScreen(((ManagePermissionsFragment) getTargetFragment()).mExtraScreen);
283f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            setHasOptionsMenu(true);
284267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
285267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov
286267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        @Override
287f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk        public void onDestroy() {
288f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            getActivity().setTitle(R.string.app_permissions);
289f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            super.onDestroy();
290267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov        }
291f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk
292f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk        @Override
293f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk        public boolean onOptionsItemSelected(MenuItem item) {
294f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            switch (item.getItemId()) {
295f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                case android.R.id.home:
296f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                    getFragmentManager().popBackStack();
297f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk                    return true;
298f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            }
299f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk            return super.onOptionsItemSelected(item);
300f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk        }
301f589a098e175c9779aa4ba9d4c40eea6cdafde2eJason Monk
302267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov    }
303267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov}
304