AppSecurityPermissions.java revision 99222d212f9ff5081d4ce6eef09dbe8eff85b83a
1/*
2**
3** Copyright 2007, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17package android.widget;
18
19import com.android.internal.R;
20
21import android.app.AlertDialog;
22import android.content.Context;
23import android.content.pm.ApplicationInfo;
24import android.content.pm.PackageInfo;
25import android.content.pm.PackageManager;
26import android.content.pm.PackageManager.NameNotFoundException;
27import android.content.pm.PackageParser;
28import android.content.pm.PermissionGroupInfo;
29import android.content.pm.PermissionInfo;
30import android.graphics.drawable.Drawable;
31import android.os.Parcel;
32import android.text.SpannableStringBuilder;
33import android.text.TextUtils;
34import android.util.AttributeSet;
35import android.util.Log;
36import android.view.LayoutInflater;
37import android.view.View;
38import android.view.ViewGroup;
39
40import java.text.Collator;
41import java.util.ArrayList;
42import java.util.Collections;
43import java.util.Comparator;
44import java.util.HashMap;
45import java.util.HashSet;
46import java.util.List;
47import java.util.Map;
48import java.util.Set;
49
50/**
51 * This class contains the SecurityPermissions view implementation.
52 * Initially the package's advanced or dangerous security permissions
53 * are displayed under categorized
54 * groups. Clicking on the additional permissions presents
55 * extended information consisting of all groups and permissions.
56 * To use this view define a LinearLayout or any ViewGroup and add this
57 * view by instantiating AppSecurityPermissions and invoking getPermissionsView.
58 *
59 * {@hide}
60 */
61public class AppSecurityPermissions {
62
63    public static final int WHICH_PERSONAL = 1<<0;
64    public static final int WHICH_DEVICE = 1<<1;
65    public static final int WHICH_NEW = 1<<2;
66    public static final int WHICH_ALL = 0xffff;
67
68    private final static String TAG = "AppSecurityPermissions";
69    private boolean localLOGV = false;
70    private Context mContext;
71    private LayoutInflater mInflater;
72    private PackageManager mPm;
73    private PackageInfo mInstalledPackageInfo;
74    private final Map<String, MyPermissionGroupInfo> mPermGroups
75            = new HashMap<String, MyPermissionGroupInfo>();
76    private final List<MyPermissionGroupInfo> mPermGroupsList
77            = new ArrayList<MyPermissionGroupInfo>();
78    private final PermissionGroupInfoComparator mPermGroupComparator;
79    private final PermissionInfoComparator mPermComparator;
80    private List<MyPermissionInfo> mPermsList;
81    private CharSequence mNewPermPrefix;
82    private Drawable mNormalIcon;
83    private Drawable mDangerousIcon;
84
85    static class MyPermissionGroupInfo extends PermissionGroupInfo {
86        CharSequence mLabel;
87
88        final ArrayList<MyPermissionInfo> mNewPermissions = new ArrayList<MyPermissionInfo>();
89        final ArrayList<MyPermissionInfo> mPersonalPermissions = new ArrayList<MyPermissionInfo>();
90        final ArrayList<MyPermissionInfo> mDevicePermissions = new ArrayList<MyPermissionInfo>();
91        final ArrayList<MyPermissionInfo> mAllPermissions = new ArrayList<MyPermissionInfo>();
92
93        MyPermissionGroupInfo(PermissionInfo perm) {
94            name = perm.packageName;
95            packageName = perm.packageName;
96        }
97
98        MyPermissionGroupInfo(PermissionGroupInfo info) {
99            super(info);
100        }
101
102        public Drawable loadGroupIcon(PackageManager pm) {
103            if (icon != 0) {
104                return loadIcon(pm);
105            } else {
106                ApplicationInfo appInfo;
107                try {
108                    appInfo = pm.getApplicationInfo(packageName, 0);
109                    return appInfo.loadIcon(pm);
110                } catch (NameNotFoundException e) {
111                }
112            }
113            return null;
114        }
115    }
116
117    static class MyPermissionInfo extends PermissionInfo {
118        CharSequence mLabel;
119
120        /**
121         * PackageInfo.requestedPermissionsFlags for the new package being installed.
122         */
123        int mNewReqFlags;
124
125        /**
126         * PackageInfo.requestedPermissionsFlags for the currently installed
127         * package, if it is installed.
128         */
129        int mExistingReqFlags;
130
131        /**
132         * True if this should be considered a new permission.
133         */
134        boolean mNew;
135
136        MyPermissionInfo() {
137        }
138
139        MyPermissionInfo(PermissionInfo info) {
140            super(info);
141        }
142
143        MyPermissionInfo(MyPermissionInfo info) {
144            super(info);
145            mNewReqFlags = info.mNewReqFlags;
146            mExistingReqFlags = info.mExistingReqFlags;
147            mNew = info.mNew;
148        }
149    }
150
151    public static class PermissionItemView extends LinearLayout implements View.OnClickListener {
152        MyPermissionGroupInfo mGroup;
153        MyPermissionInfo mPerm;
154        AlertDialog mDialog;
155
156        public PermissionItemView(Context context, AttributeSet attrs) {
157            super(context, attrs);
158            setClickable(true);
159        }
160
161        public void setPermission(MyPermissionGroupInfo grp, MyPermissionInfo perm,
162                boolean first, CharSequence newPermPrefix) {
163            mGroup = grp;
164            mPerm = perm;
165
166            ImageView permGrpIcon = (ImageView) findViewById(R.id.perm_icon);
167            TextView permNameView = (TextView) findViewById(R.id.perm_name);
168
169            PackageManager pm = getContext().getPackageManager();
170            Drawable icon = null;
171            if (first) {
172                icon = grp.loadGroupIcon(pm);
173            }
174            CharSequence label = perm.mLabel;
175            if (perm.mNew && newPermPrefix != null) {
176                // If this is a new permission, format it appropriately.
177                SpannableStringBuilder builder = new SpannableStringBuilder();
178                Parcel parcel = Parcel.obtain();
179                TextUtils.writeToParcel(newPermPrefix, parcel, 0);
180                parcel.setDataPosition(0);
181                CharSequence newStr = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
182                parcel.recycle();
183                builder.append(newStr);
184                builder.append(label);
185                label = builder;
186            }
187
188            permGrpIcon.setImageDrawable(icon);
189            permNameView.setText(label);
190            setOnClickListener(this);
191        }
192
193        @Override
194        public void onClick(View v) {
195            if (mGroup != null && mPerm != null) {
196                if (mDialog != null) {
197                    mDialog.dismiss();
198                }
199                PackageManager pm = getContext().getPackageManager();
200                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
201                builder.setTitle(mGroup.mLabel);
202                if (mPerm.descriptionRes != 0) {
203                    builder.setMessage(mPerm.loadDescription(pm));
204                } else {
205                    CharSequence appName;
206                    try {
207                        ApplicationInfo app = pm.getApplicationInfo(mPerm.packageName, 0);
208                        appName = app.loadLabel(pm);
209                    } catch (NameNotFoundException e) {
210                        appName = mPerm.packageName;
211                    }
212                    StringBuilder sbuilder = new StringBuilder(128);
213                    sbuilder.append(getContext().getString(
214                            R.string.perms_description_app, appName));
215                    sbuilder.append("\n\n");
216                    sbuilder.append(mPerm.name);
217                    builder.setMessage(sbuilder.toString());
218                }
219                builder.setCancelable(true);
220                builder.setIcon(mGroup.loadGroupIcon(pm));
221                mDialog = builder.show();
222                mDialog.setCanceledOnTouchOutside(true);
223            }
224        }
225
226        @Override
227        protected void onDetachedFromWindow() {
228            super.onDetachedFromWindow();
229            if (mDialog != null) {
230                mDialog.dismiss();
231            }
232        }
233    }
234
235    public AppSecurityPermissions(Context context, List<PermissionInfo> permList) {
236        mContext = context;
237        mPm = mContext.getPackageManager();
238        loadResources();
239        mPermComparator = new PermissionInfoComparator();
240        mPermGroupComparator = new PermissionGroupInfoComparator();
241        for (PermissionInfo pi : permList) {
242            mPermsList.add(new MyPermissionInfo(pi));
243        }
244        setPermissions(mPermsList);
245    }
246
247    public AppSecurityPermissions(Context context, String packageName) {
248        mContext = context;
249        mPm = mContext.getPackageManager();
250        loadResources();
251        mPermComparator = new PermissionInfoComparator();
252        mPermGroupComparator = new PermissionGroupInfoComparator();
253        mPermsList = new ArrayList<MyPermissionInfo>();
254        Set<MyPermissionInfo> permSet = new HashSet<MyPermissionInfo>();
255        PackageInfo pkgInfo;
256        try {
257            pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
258        } catch (NameNotFoundException e) {
259            Log.w(TAG, "Could'nt retrieve permissions for package:"+packageName);
260            return;
261        }
262        // Extract all user permissions
263        if((pkgInfo.applicationInfo != null) && (pkgInfo.applicationInfo.uid != -1)) {
264            getAllUsedPermissions(pkgInfo.applicationInfo.uid, permSet);
265        }
266        for(MyPermissionInfo tmpInfo : permSet) {
267            mPermsList.add(tmpInfo);
268        }
269        setPermissions(mPermsList);
270    }
271
272    public AppSecurityPermissions(Context context, PackageParser.Package pkg) {
273        mContext = context;
274        mPm = mContext.getPackageManager();
275        loadResources();
276        mPermComparator = new PermissionInfoComparator();
277        mPermGroupComparator = new PermissionGroupInfoComparator();
278        mPermsList = new ArrayList<MyPermissionInfo>();
279        Set<MyPermissionInfo> permSet = new HashSet<MyPermissionInfo>();
280        if(pkg == null) {
281            return;
282        }
283
284        // Convert to a PackageInfo
285        PackageInfo info = PackageParser.generatePackageInfo(pkg, null,
286                PackageManager.GET_PERMISSIONS, 0, 0, null);
287        PackageInfo installedPkgInfo = null;
288        // Get requested permissions
289        if (info.requestedPermissions != null) {
290            try {
291                installedPkgInfo = mPm.getPackageInfo(info.packageName,
292                        PackageManager.GET_PERMISSIONS);
293            } catch (NameNotFoundException e) {
294            }
295            extractPerms(info, permSet, installedPkgInfo);
296        }
297        // Get permissions related to  shared user if any
298        if (pkg.mSharedUserId != null) {
299            int sharedUid;
300            try {
301                sharedUid = mPm.getUidForSharedUser(pkg.mSharedUserId);
302                getAllUsedPermissions(sharedUid, permSet);
303            } catch (NameNotFoundException e) {
304                Log.w(TAG, "Could'nt retrieve shared user id for:"+pkg.packageName);
305            }
306        }
307        // Retrieve list of permissions
308        for (MyPermissionInfo tmpInfo : permSet) {
309            mPermsList.add(tmpInfo);
310        }
311        setPermissions(mPermsList);
312    }
313
314    private void loadResources() {
315        // Pick up from framework resources instead.
316        mNewPermPrefix = mContext.getText(R.string.perms_new_perm_prefix);
317        mNormalIcon = mContext.getResources().getDrawable(R.drawable.ic_text_dot);
318        mDangerousIcon = mContext.getResources().getDrawable(R.drawable.ic_bullet_key_permission);
319    }
320
321    /**
322     * Utility to retrieve a view displaying a single permission.  This provides
323     * the old UI layout for permissions; it is only here for the device admin
324     * settings to continue to use.
325     */
326    public static View getPermissionItemView(Context context,
327            CharSequence grpName, CharSequence description, boolean dangerous) {
328        LayoutInflater inflater = (LayoutInflater)context.getSystemService(
329                Context.LAYOUT_INFLATER_SERVICE);
330        Drawable icon = context.getResources().getDrawable(dangerous
331                ? R.drawable.ic_bullet_key_permission : R.drawable.ic_text_dot);
332        return getPermissionItemViewOld(context, inflater, grpName,
333                description, dangerous, icon);
334    }
335
336    public PackageInfo getInstalledPackageInfo() {
337        return mInstalledPackageInfo;
338    }
339
340    private void getAllUsedPermissions(int sharedUid, Set<MyPermissionInfo> permSet) {
341        String sharedPkgList[] = mPm.getPackagesForUid(sharedUid);
342        if(sharedPkgList == null || (sharedPkgList.length == 0)) {
343            return;
344        }
345        for(String sharedPkg : sharedPkgList) {
346            getPermissionsForPackage(sharedPkg, permSet);
347        }
348    }
349
350    private void getPermissionsForPackage(String packageName,
351            Set<MyPermissionInfo> permSet) {
352        PackageInfo pkgInfo;
353        try {
354            pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
355        } catch (NameNotFoundException e) {
356            Log.w(TAG, "Couldn't retrieve permissions for package:"+packageName);
357            return;
358        }
359        if ((pkgInfo != null) && (pkgInfo.requestedPermissions != null)) {
360            extractPerms(pkgInfo, permSet, pkgInfo);
361        }
362    }
363
364    private void extractPerms(PackageInfo info, Set<MyPermissionInfo> permSet,
365            PackageInfo installedPkgInfo) {
366        String[] strList = info.requestedPermissions;
367        int[] flagsList = info.requestedPermissionsFlags;
368        if ((strList == null) || (strList.length == 0)) {
369            return;
370        }
371        mInstalledPackageInfo = installedPkgInfo;
372        for (int i=0; i<strList.length; i++) {
373            String permName = strList[i];
374            // If we are only looking at an existing app, then we only
375            // care about permissions that have actually been granted to it.
376            if (installedPkgInfo != null && info == installedPkgInfo) {
377                if ((flagsList[i]&PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) {
378                    continue;
379                }
380            }
381            try {
382                PermissionInfo tmpPermInfo = mPm.getPermissionInfo(permName, 0);
383                if (tmpPermInfo == null) {
384                    continue;
385                }
386                int existingIndex = -1;
387                if (installedPkgInfo != null
388                        && installedPkgInfo.requestedPermissions != null) {
389                    for (int j=0; j<installedPkgInfo.requestedPermissions.length; j++) {
390                        if (permName.equals(installedPkgInfo.requestedPermissions[j])) {
391                            existingIndex = j;
392                            break;
393                        }
394                    }
395                }
396                final int existingFlags = existingIndex >= 0 ?
397                        installedPkgInfo.requestedPermissionsFlags[existingIndex] : 0;
398                if (!isDisplayablePermission(tmpPermInfo, flagsList[i], existingFlags)) {
399                    // This is not a permission that is interesting for the user
400                    // to see, so skip it.
401                    continue;
402                }
403                final String origGroupName = tmpPermInfo.group;
404                String groupName = origGroupName;
405                if (groupName == null) {
406                    groupName = tmpPermInfo.packageName;
407                    tmpPermInfo.group = groupName;
408                }
409                MyPermissionGroupInfo group = mPermGroups.get(groupName);
410                if (group == null) {
411                    PermissionGroupInfo grp = null;
412                    if (origGroupName != null) {
413                        grp = mPm.getPermissionGroupInfo(origGroupName, 0);
414                    }
415                    if (grp != null) {
416                        group = new MyPermissionGroupInfo(grp);
417                    } else {
418                        // We could be here either because the permission
419                        // didn't originally specify a group or the group it
420                        // gave couldn't be found.  In either case, we consider
421                        // its group to be the permission's package name.
422                        tmpPermInfo.group = tmpPermInfo.packageName;
423                        group = mPermGroups.get(tmpPermInfo.group);
424                        if (group == null) {
425                            group = new MyPermissionGroupInfo(tmpPermInfo);
426                        }
427                        group = new MyPermissionGroupInfo(tmpPermInfo);
428                    }
429                    mPermGroups.put(tmpPermInfo.group, group);
430                }
431                final boolean newPerm = installedPkgInfo != null
432                        && (existingFlags&PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0;
433                MyPermissionInfo myPerm = new MyPermissionInfo(tmpPermInfo);
434                myPerm.mNewReqFlags = flagsList[i];
435                myPerm.mExistingReqFlags = existingFlags;
436                // This is a new permission if the app is already installed and
437                // doesn't currently hold this permission.
438                myPerm.mNew = newPerm;
439                permSet.add(myPerm);
440            } catch (NameNotFoundException e) {
441                Log.i(TAG, "Ignoring unknown permission:"+permName);
442            }
443        }
444    }
445
446    public int getPermissionCount() {
447        return getPermissionCount(WHICH_ALL);
448    }
449
450    private List<MyPermissionInfo> getPermissionList(MyPermissionGroupInfo grp, int which) {
451        if (which == WHICH_NEW) {
452            return grp.mNewPermissions;
453        } else if (which == WHICH_PERSONAL) {
454            return grp.mPersonalPermissions;
455        } else if (which == WHICH_DEVICE) {
456            return grp.mDevicePermissions;
457        } else {
458            return grp.mAllPermissions;
459        }
460    }
461
462    public int getPermissionCount(int which) {
463        int N = 0;
464        for (int i=0; i<mPermGroupsList.size(); i++) {
465            N += getPermissionList(mPermGroupsList.get(i), which).size();
466        }
467        return N;
468    }
469
470    public View getPermissionsView() {
471        return getPermissionsView(WHICH_ALL);
472    }
473
474    public View getPermissionsView(int which) {
475        mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
476
477        LinearLayout permsView = (LinearLayout) mInflater.inflate(R.layout.app_perms_summary, null);
478        LinearLayout displayList = (LinearLayout) permsView.findViewById(R.id.perms_list);
479        View noPermsView = permsView.findViewById(R.id.no_permissions);
480
481        displayPermissions(mPermGroupsList, displayList, which);
482        if (displayList.getChildCount() <= 0) {
483            noPermsView.setVisibility(View.VISIBLE);
484        }
485
486        return permsView;
487    }
488
489    /**
490     * Utility method that displays permissions from a map containing group name and
491     * list of permission descriptions.
492     */
493    private void displayPermissions(List<MyPermissionGroupInfo> groups,
494            LinearLayout permListView, int which) {
495        permListView.removeAllViews();
496
497        int spacing = (int)(8*mContext.getResources().getDisplayMetrics().density);
498
499        for (int i=0; i<groups.size(); i++) {
500            MyPermissionGroupInfo grp = groups.get(i);
501            final List<MyPermissionInfo> perms = getPermissionList(grp, which);
502            for (int j=0; j<perms.size(); j++) {
503                MyPermissionInfo perm = perms.get(j);
504                View view = getPermissionItemView(grp, perm, j == 0,
505                        which != WHICH_NEW ? mNewPermPrefix : null);
506                LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
507                        ViewGroup.LayoutParams.MATCH_PARENT,
508                        ViewGroup.LayoutParams.WRAP_CONTENT);
509                if (j == 0) {
510                    lp.topMargin = spacing;
511                }
512                if (j == grp.mAllPermissions.size()-1) {
513                    lp.bottomMargin = spacing;
514                }
515                if (permListView.getChildCount() == 0) {
516                    lp.topMargin *= 2;
517                }
518                permListView.addView(view, lp);
519            }
520        }
521    }
522
523    private PermissionItemView getPermissionItemView(MyPermissionGroupInfo grp,
524            MyPermissionInfo perm, boolean first, CharSequence newPermPrefix) {
525        return getPermissionItemView(mContext, mInflater, grp, perm, first, newPermPrefix);
526    }
527
528    private static PermissionItemView getPermissionItemView(Context context, LayoutInflater inflater,
529            MyPermissionGroupInfo grp, MyPermissionInfo perm, boolean first,
530            CharSequence newPermPrefix) {
531        PermissionItemView permView = (PermissionItemView)inflater.inflate(
532                R.layout.app_permission_item, null);
533        permView.setPermission(grp, perm, first, newPermPrefix);
534        return permView;
535    }
536
537    private static View getPermissionItemViewOld(Context context, LayoutInflater inflater,
538            CharSequence grpName, CharSequence permList, boolean dangerous, Drawable icon) {
539        View permView = inflater.inflate(R.layout.app_permission_item_old, null);
540
541        TextView permGrpView = (TextView) permView.findViewById(R.id.permission_group);
542        TextView permDescView = (TextView) permView.findViewById(R.id.permission_list);
543
544        ImageView imgView = (ImageView)permView.findViewById(R.id.perm_icon);
545        imgView.setImageDrawable(icon);
546        if(grpName != null) {
547            permGrpView.setText(grpName);
548            permDescView.setText(permList);
549        } else {
550            permGrpView.setText(permList);
551            permDescView.setVisibility(View.GONE);
552        }
553        return permView;
554    }
555
556    private boolean isDisplayablePermission(PermissionInfo pInfo, int newReqFlags,
557            int existingReqFlags) {
558        final int base = pInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
559        // Dangerous and normal permissions are always shown to the user.
560        if (base == PermissionInfo.PROTECTION_DANGEROUS ||
561                base == PermissionInfo.PROTECTION_NORMAL) {
562            return true;
563        }
564        // Development permissions are only shown to the user if they are already
565        // granted to the app -- if we are installing an app and they are not
566        // already granted, they will not be granted as part of the install.
567        if ((existingReqFlags&PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0
568                && (pInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
569            return true;
570        }
571        return false;
572    }
573
574    private static class PermissionGroupInfoComparator implements Comparator<MyPermissionGroupInfo> {
575        private final Collator sCollator = Collator.getInstance();
576        PermissionGroupInfoComparator() {
577        }
578        public final int compare(MyPermissionGroupInfo a, MyPermissionGroupInfo b) {
579            if (((a.flags^b.flags)&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) {
580                return ((a.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) ? -1 : 1;
581            }
582            if (a.priority != b.priority) {
583                return a.priority > b.priority ? -1 : 1;
584            }
585            return sCollator.compare(a.mLabel, b.mLabel);
586        }
587    }
588
589    private static class PermissionInfoComparator implements Comparator<MyPermissionInfo> {
590        private final Collator sCollator = Collator.getInstance();
591        PermissionInfoComparator() {
592        }
593        public final int compare(MyPermissionInfo a, MyPermissionInfo b) {
594            return sCollator.compare(a.mLabel, b.mLabel);
595        }
596    }
597
598    private void addPermToList(List<MyPermissionInfo> permList,
599            MyPermissionInfo pInfo) {
600        if (pInfo.mLabel == null) {
601            pInfo.mLabel = pInfo.loadLabel(mPm);
602        }
603        int idx = Collections.binarySearch(permList, pInfo, mPermComparator);
604        if(localLOGV) Log.i(TAG, "idx="+idx+", list.size="+permList.size());
605        if (idx < 0) {
606            idx = -idx-1;
607            permList.add(idx, pInfo);
608        }
609    }
610
611    private void setPermissions(List<MyPermissionInfo> permList) {
612        if (permList != null) {
613            // First pass to group permissions
614            for (MyPermissionInfo pInfo : permList) {
615                if(localLOGV) Log.i(TAG, "Processing permission:"+pInfo.name);
616                if(!isDisplayablePermission(pInfo, pInfo.mNewReqFlags, pInfo.mExistingReqFlags)) {
617                    if(localLOGV) Log.i(TAG, "Permission:"+pInfo.name+" is not displayable");
618                    continue;
619                }
620                MyPermissionGroupInfo group = mPermGroups.get(pInfo.group);
621                if (group != null) {
622                    pInfo.mLabel = pInfo.loadLabel(mPm);
623                    addPermToList(group.mAllPermissions, pInfo);
624                    if (pInfo.mNew) {
625                        addPermToList(group.mNewPermissions, pInfo);
626                    }
627                    if ((group.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) {
628                        addPermToList(group.mPersonalPermissions, pInfo);
629                    } else {
630                        addPermToList(group.mDevicePermissions, pInfo);
631                    }
632                }
633            }
634        }
635
636        for (MyPermissionGroupInfo pgrp : mPermGroups.values()) {
637            if (pgrp.labelRes != 0 || pgrp.nonLocalizedLabel != null) {
638                pgrp.mLabel = pgrp.loadLabel(mPm);
639            } else {
640                ApplicationInfo app;
641                try {
642                    app = mPm.getApplicationInfo(pgrp.packageName, 0);
643                    pgrp.mLabel = app.loadLabel(mPm);
644                } catch (NameNotFoundException e) {
645                    pgrp.mLabel = pgrp.loadLabel(mPm);
646                }
647            }
648            mPermGroupsList.add(pgrp);
649        }
650        Collections.sort(mPermGroupsList, mPermGroupComparator);
651        if (false) {
652            for (MyPermissionGroupInfo grp : mPermGroupsList) {
653                Log.i("foo", "Group " + grp.name + " personal="
654                        + ((grp.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0)
655                        + " priority=" + grp.priority);
656            }
657        }
658    }
659}
660