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