• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.pm;
18 
19 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
20 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
21 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
22 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
23 
24 import com.android.internal.util.FastXmlSerializer;
25 import com.android.internal.util.JournaledFile;
26 import com.android.internal.util.XmlUtils;
27 import com.android.server.IntentResolver;
28 import com.android.server.pm.PackageManagerService.DumpState;
29 
30 import org.xmlpull.v1.XmlPullParser;
31 import org.xmlpull.v1.XmlPullParserException;
32 import org.xmlpull.v1.XmlSerializer;
33 
34 import android.content.ComponentName;
35 import android.content.Intent;
36 import android.content.pm.ApplicationInfo;
37 import android.content.pm.ComponentInfo;
38 import android.content.pm.PackageManager;
39 import android.content.pm.PackageParser;
40 import android.content.pm.PermissionInfo;
41 import android.content.pm.Signature;
42 import android.content.pm.VerifierDeviceIdentity;
43 import android.os.Binder;
44 import android.os.Environment;
45 import android.os.FileUtils;
46 import android.os.Process;
47 import android.util.Log;
48 import android.util.Slog;
49 import android.util.SparseArray;
50 import android.util.Xml;
51 
52 import java.io.BufferedOutputStream;
53 import java.io.File;
54 import java.io.FileInputStream;
55 import java.io.FileOutputStream;
56 import java.io.IOException;
57 import java.io.PrintWriter;
58 import java.text.SimpleDateFormat;
59 import java.util.ArrayList;
60 import java.util.Arrays;
61 import java.util.Date;
62 import java.util.HashMap;
63 import java.util.HashSet;
64 import java.util.Iterator;
65 
66 /**
67  * Holds information about dynamic settings.
68  */
69 final class Settings {
70     private static final String TAG = "PackageSettings";
71 
72     private static final boolean DEBUG_STOPPED = false;
73 
74     private final File mSettingsFilename;
75     private final File mBackupSettingsFilename;
76     private final File mPackageListFilename;
77     private final File mStoppedPackagesFilename;
78     private final File mBackupStoppedPackagesFilename;
79     final HashMap<String, PackageSetting> mPackages =
80             new HashMap<String, PackageSetting>();
81     // List of replaced system applications
82     final HashMap<String, PackageSetting> mDisabledSysPackages =
83         new HashMap<String, PackageSetting>();
84 
85     // These are the last platform API version we were using for
86     // the apps installed on internal and external storage.  It is
87     // used to grant newer permissions one time during a system upgrade.
88     int mInternalSdkPlatform;
89     int mExternalSdkPlatform;
90 
91     /** Device identity for the purpose of package verification. */
92     private VerifierDeviceIdentity mVerifierDeviceIdentity;
93 
94     // The user's preferred activities associated with particular intent
95     // filters.
96     final IntentResolver<PreferredActivity, PreferredActivity> mPreferredActivities =
97                 new IntentResolver<PreferredActivity, PreferredActivity>() {
98         @Override
99         protected String packageForFilter(PreferredActivity filter) {
100             return filter.mPref.mComponent.getPackageName();
101         }
102         @Override
103         protected void dumpFilter(PrintWriter out, String prefix,
104                 PreferredActivity filter) {
105             filter.mPref.dump(out, prefix, filter);
106         }
107     };
108     final HashMap<String, SharedUserSetting> mSharedUsers =
109             new HashMap<String, SharedUserSetting>();
110     private final ArrayList<Object> mUserIds = new ArrayList<Object>();
111     private final SparseArray<Object> mOtherUserIds =
112             new SparseArray<Object>();
113 
114     // For reading/writing settings file.
115     private final ArrayList<Signature> mPastSignatures =
116             new ArrayList<Signature>();
117 
118     // Mapping from permission names to info about them.
119     final HashMap<String, BasePermission> mPermissions =
120             new HashMap<String, BasePermission>();
121 
122     // Mapping from permission tree names to info about them.
123     final HashMap<String, BasePermission> mPermissionTrees =
124             new HashMap<String, BasePermission>();
125 
126     // Packages that have been uninstalled and still need their external
127     // storage data deleted.
128     final ArrayList<String> mPackagesToBeCleaned = new ArrayList<String>();
129 
130     // Packages that have been renamed since they were first installed.
131     // Keys are the new names of the packages, values are the original
132     // names.  The packages appear everwhere else under their original
133     // names.
134     final HashMap<String, String> mRenamedPackages = new HashMap<String, String>();
135 
136     final StringBuilder mReadMessages = new StringBuilder();
137 
138     /**
139      * Used to track packages that have a shared user ID that hasn't been read
140      * in yet.
141      * <p>
142      * TODO: make this just a local variable that is passed in during package
143      * scanning to make it less confusing.
144      */
145     private final ArrayList<PendingPackage> mPendingPackages = new ArrayList<PendingPackage>();
146 
Settings()147     Settings() {
148         File dataDir = Environment.getDataDirectory();
149         File systemDir = new File(dataDir, "system");
150         systemDir.mkdirs();
151         FileUtils.setPermissions(systemDir.toString(),
152                 FileUtils.S_IRWXU|FileUtils.S_IRWXG
153                 |FileUtils.S_IROTH|FileUtils.S_IXOTH,
154                 -1, -1);
155         mSettingsFilename = new File(systemDir, "packages.xml");
156         mBackupSettingsFilename = new File(systemDir, "packages-backup.xml");
157         mPackageListFilename = new File(systemDir, "packages.list");
158         mStoppedPackagesFilename = new File(systemDir, "packages-stopped.xml");
159         mBackupStoppedPackagesFilename = new File(systemDir, "packages-stopped-backup.xml");
160     }
161 
getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage, String realName, SharedUserSetting sharedUser, File codePath, File resourcePath, String nativeLibraryPathString, int pkgFlags, boolean create, boolean add)162     PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage,
163             String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
164             String nativeLibraryPathString, int pkgFlags, boolean create, boolean add) {
165         final String name = pkg.packageName;
166         PackageSetting p = getPackageLPw(name, origPackage, realName, sharedUser, codePath,
167                 resourcePath, nativeLibraryPathString, pkg.mVersionCode, pkgFlags, create, add);
168         return p;
169     }
170 
peekPackageLPr(String name)171     PackageSetting peekPackageLPr(String name) {
172         return mPackages.get(name);
173     }
174 
setInstallStatus(String pkgName, int status)175     void setInstallStatus(String pkgName, int status) {
176         PackageSetting p = mPackages.get(pkgName);
177         if(p != null) {
178             if(p.getInstallStatus() != status) {
179                 p.setInstallStatus(status);
180             }
181         }
182     }
183 
setInstallerPackageName(String pkgName, String installerPkgName)184     void setInstallerPackageName(String pkgName,
185             String installerPkgName) {
186         PackageSetting p = mPackages.get(pkgName);
187         if(p != null) {
188             p.setInstallerPackageName(installerPkgName);
189         }
190     }
191 
getSharedUserLPw(String name, int pkgFlags, boolean create)192     SharedUserSetting getSharedUserLPw(String name,
193             int pkgFlags, boolean create) {
194         SharedUserSetting s = mSharedUsers.get(name);
195         if (s == null) {
196             if (!create) {
197                 return null;
198             }
199             s = new SharedUserSetting(name, pkgFlags);
200             if (PackageManagerService.MULTIPLE_APPLICATION_UIDS) {
201                 s.userId = newUserIdLPw(s);
202             } else {
203                 s.userId = PackageManagerService.FIRST_APPLICATION_UID;
204             }
205             Log.i(PackageManagerService.TAG, "New shared user " + name + ": id=" + s.userId);
206             // < 0 means we couldn't assign a userid; fall out and return
207             // s, which is currently null
208             if (s.userId >= 0) {
209                 mSharedUsers.put(name, s);
210             }
211         }
212 
213         return s;
214     }
215 
disableSystemPackageLPw(String name)216     boolean disableSystemPackageLPw(String name) {
217         final PackageSetting p = mPackages.get(name);
218         if(p == null) {
219             Log.w(PackageManagerService.TAG, "Package:"+name+" is not an installed package");
220             return false;
221         }
222         final PackageSetting dp = mDisabledSysPackages.get(name);
223         // always make sure the system package code and resource paths dont change
224         if (dp == null) {
225             if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
226                 p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
227             }
228             mDisabledSysPackages.put(name, p);
229 
230             // a little trick...  when we install the new package, we don't
231             // want to modify the existing PackageSetting for the built-in
232             // version.  so at this point we need a new PackageSetting that
233             // is okay to muck with.
234             PackageSetting newp = new PackageSetting(p);
235             replacePackageLPw(name, newp);
236             return true;
237         }
238         return false;
239     }
240 
enableSystemPackageLPw(String name)241     PackageSetting enableSystemPackageLPw(String name) {
242         PackageSetting p = mDisabledSysPackages.get(name);
243         if(p == null) {
244             Log.w(PackageManagerService.TAG, "Package:"+name+" is not disabled");
245             return null;
246         }
247         // Reset flag in ApplicationInfo object
248         if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
249             p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
250         }
251         PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
252                 p.nativeLibraryPathString, p.userId, p.versionCode, p.pkgFlags);
253         mDisabledSysPackages.remove(name);
254         return ret;
255     }
256 
addPackageLPw(String name, String realName, File codePath, File resourcePath, String nativeLibraryPathString, int uid, int vc, int pkgFlags)257     PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
258             String nativeLibraryPathString, int uid, int vc, int pkgFlags) {
259         PackageSetting p = mPackages.get(name);
260         if (p != null) {
261             if (p.userId == uid) {
262                 return p;
263             }
264             PackageManagerService.reportSettingsProblem(Log.ERROR,
265                     "Adding duplicate package, keeping first: " + name);
266             return null;
267         }
268         p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString,
269                 vc, pkgFlags);
270         p.userId = uid;
271         if (addUserIdLPw(uid, p, name)) {
272             mPackages.put(name, p);
273             return p;
274         }
275         return null;
276     }
277 
addSharedUserLPw(String name, int uid, int pkgFlags)278     SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags) {
279         SharedUserSetting s = mSharedUsers.get(name);
280         if (s != null) {
281             if (s.userId == uid) {
282                 return s;
283             }
284             PackageManagerService.reportSettingsProblem(Log.ERROR,
285                     "Adding duplicate shared user, keeping first: " + name);
286             return null;
287         }
288         s = new SharedUserSetting(name, pkgFlags);
289         s.userId = uid;
290         if (addUserIdLPw(uid, s, name)) {
291             mSharedUsers.put(name, s);
292             return s;
293         }
294         return null;
295     }
296 
297     // Transfer ownership of permissions from one package to another.
transferPermissionsLPw(String origPkg, String newPkg)298     void transferPermissionsLPw(String origPkg, String newPkg) {
299         // Transfer ownership of permissions to the new package.
300         for (int i=0; i<2; i++) {
301             HashMap<String, BasePermission> permissions =
302                     i == 0 ? mPermissionTrees : mPermissions;
303             for (BasePermission bp : permissions.values()) {
304                 if (origPkg.equals(bp.sourcePackage)) {
305                     if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG,
306                             "Moving permission " + bp.name
307                             + " from pkg " + bp.sourcePackage
308                             + " to " + newPkg);
309                     bp.sourcePackage = newPkg;
310                     bp.packageSetting = null;
311                     bp.perm = null;
312                     if (bp.pendingInfo != null) {
313                         bp.pendingInfo.packageName = newPkg;
314                     }
315                     bp.uid = 0;
316                     bp.gids = null;
317                 }
318             }
319         }
320     }
321 
getPackageLPw(String name, PackageSetting origPackage, String realName, SharedUserSetting sharedUser, File codePath, File resourcePath, String nativeLibraryPathString, int vc, int pkgFlags, boolean create, boolean add)322     private PackageSetting getPackageLPw(String name, PackageSetting origPackage,
323             String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
324             String nativeLibraryPathString, int vc, int pkgFlags, boolean create, boolean add) {
325         PackageSetting p = mPackages.get(name);
326         if (p != null) {
327             if (!p.codePath.equals(codePath)) {
328                 // Check to see if its a disabled system app
329                 if ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
330                     // This is an updated system app with versions in both system
331                     // and data partition. Just let the most recent version
332                     // take precedence.
333                     Slog.w(PackageManagerService.TAG, "Trying to update system app code path from " +
334                             p.codePathString + " to " + codePath.toString());
335                 } else {
336                     // Just a change in the code path is not an issue, but
337                     // let's log a message about it.
338                     Slog.i(PackageManagerService.TAG, "Package " + name + " codePath changed from " + p.codePath
339                             + " to " + codePath + "; Retaining data and using new");
340                     /*
341                      * Since we've changed paths, we need to prefer the new
342                      * native library path over the one stored in the
343                      * package settings since we might have moved from
344                      * internal to external storage or vice versa.
345                      */
346                     p.nativeLibraryPathString = nativeLibraryPathString;
347                 }
348             }
349             if (p.sharedUser != sharedUser) {
350                 PackageManagerService.reportSettingsProblem(Log.WARN,
351                         "Package " + name + " shared user changed from "
352                         + (p.sharedUser != null ? p.sharedUser.name : "<nothing>")
353                         + " to "
354                         + (sharedUser != null ? sharedUser.name : "<nothing>")
355                         + "; replacing with new");
356                 p = null;
357             } else {
358                 if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0) {
359                     // If what we are scanning is a system package, then
360                     // make it so, regardless of whether it was previously
361                     // installed only in the data partition.
362                     p.pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
363                 }
364             }
365         }
366         if (p == null) {
367             // Create a new PackageSettings entry. this can end up here because
368             // of code path mismatch or user id mismatch of an updated system partition
369             if (!create) {
370                 return null;
371             }
372             if (origPackage != null) {
373                 // We are consuming the data from an existing package.
374                 p = new PackageSetting(origPackage.name, name, codePath, resourcePath,
375                         nativeLibraryPathString, vc, pkgFlags);
376                 if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package " + name
377                         + " is adopting original package " + origPackage.name);
378                 // Note that we will retain the new package's signature so
379                 // that we can keep its data.
380                 PackageSignatures s = p.signatures;
381                 p.copyFrom(origPackage);
382                 p.signatures = s;
383                 p.sharedUser = origPackage.sharedUser;
384                 p.userId = origPackage.userId;
385                 p.origPackage = origPackage;
386                 mRenamedPackages.put(name, origPackage.name);
387                 name = origPackage.name;
388                 // Update new package state.
389                 p.setTimeStamp(codePath.lastModified());
390             } else {
391                 p = new PackageSetting(name, realName, codePath, resourcePath,
392                         nativeLibraryPathString, vc, pkgFlags);
393                 p.setTimeStamp(codePath.lastModified());
394                 p.sharedUser = sharedUser;
395                 // If this is not a system app, it starts out stopped.
396                 if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
397                     if (DEBUG_STOPPED) {
398                         RuntimeException e = new RuntimeException("here");
399                         e.fillInStackTrace();
400                         Slog.i(PackageManagerService.TAG, "Stopping package " + name, e);
401                     }
402                     p.stopped = true;
403                     p.notLaunched = true;
404                 }
405                 if (sharedUser != null) {
406                     p.userId = sharedUser.userId;
407                 } else if (PackageManagerService.MULTIPLE_APPLICATION_UIDS) {
408                     // Clone the setting here for disabled system packages
409                     PackageSetting dis = mDisabledSysPackages.get(name);
410                     if (dis != null) {
411                         // For disabled packages a new setting is created
412                         // from the existing user id. This still has to be
413                         // added to list of user id's
414                         // Copy signatures from previous setting
415                         if (dis.signatures.mSignatures != null) {
416                             p.signatures.mSignatures = dis.signatures.mSignatures.clone();
417                         }
418                         p.userId = dis.userId;
419                         // Clone permissions
420                         p.grantedPermissions = new HashSet<String>(dis.grantedPermissions);
421                         // Clone component info
422                         p.disabledComponents = new HashSet<String>(dis.disabledComponents);
423                         p.enabledComponents = new HashSet<String>(dis.enabledComponents);
424                         // Add new setting to list of user ids
425                         addUserIdLPw(p.userId, p, name);
426                     } else {
427                         // Assign new user id
428                         p.userId = newUserIdLPw(p);
429                     }
430                 } else {
431                     p.userId = PackageManagerService.FIRST_APPLICATION_UID;
432                 }
433             }
434             if (p.userId < 0) {
435                 PackageManagerService.reportSettingsProblem(Log.WARN,
436                         "Package " + name + " could not be assigned a valid uid");
437                 return null;
438             }
439             if (add) {
440                 // Finish adding new package by adding it and updating shared
441                 // user preferences
442                 addPackageSettingLPw(p, name, sharedUser);
443             }
444         }
445         return p;
446     }
447 
insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg)448     void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) {
449         p.pkg = pkg;
450         pkg.mSetEnabled = p.enabled;
451         pkg.mSetStopped = p.stopped;
452         final String codePath = pkg.applicationInfo.sourceDir;
453         final String resourcePath = pkg.applicationInfo.publicSourceDir;
454         // Update code path if needed
455         if (!codePath.equalsIgnoreCase(p.codePathString)) {
456             Slog.w(PackageManagerService.TAG, "Code path for pkg : " + p.pkg.packageName +
457                     " changing from " + p.codePathString + " to " + codePath);
458             p.codePath = new File(codePath);
459             p.codePathString = codePath;
460         }
461         //Update resource path if needed
462         if (!resourcePath.equalsIgnoreCase(p.resourcePathString)) {
463             Slog.w(PackageManagerService.TAG, "Resource path for pkg : " + p.pkg.packageName +
464                     " changing from " + p.resourcePathString + " to " + resourcePath);
465             p.resourcePath = new File(resourcePath);
466             p.resourcePathString = resourcePath;
467         }
468         // Update the native library path if needed
469         final String nativeLibraryPath = pkg.applicationInfo.nativeLibraryDir;
470         if (nativeLibraryPath != null
471                 && !nativeLibraryPath.equalsIgnoreCase(p.nativeLibraryPathString)) {
472             p.nativeLibraryPathString = nativeLibraryPath;
473         }
474         // Update version code if needed
475          if (pkg.mVersionCode != p.versionCode) {
476             p.versionCode = pkg.mVersionCode;
477         }
478          // Update signatures if needed.
479          if (p.signatures.mSignatures == null) {
480              p.signatures.assignSignatures(pkg.mSignatures);
481          }
482          // If this app defines a shared user id initialize
483          // the shared user signatures as well.
484          if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) {
485              p.sharedUser.signatures.assignSignatures(pkg.mSignatures);
486          }
487         addPackageSettingLPw(p, pkg.packageName, p.sharedUser);
488     }
489 
490     // Utility method that adds a PackageSetting to mPackages and
491     // completes updating the shared user attributes
addPackageSettingLPw(PackageSetting p, String name, SharedUserSetting sharedUser)492     private void addPackageSettingLPw(PackageSetting p, String name,
493             SharedUserSetting sharedUser) {
494         mPackages.put(name, p);
495         if (sharedUser != null) {
496             if (p.sharedUser != null && p.sharedUser != sharedUser) {
497                 PackageManagerService.reportSettingsProblem(Log.ERROR,
498                         "Package " + p.name + " was user "
499                         + p.sharedUser + " but is now " + sharedUser
500                         + "; I am not changing its files so it will probably fail!");
501                 p.sharedUser.packages.remove(p);
502             } else if (p.userId != sharedUser.userId) {
503                 PackageManagerService.reportSettingsProblem(Log.ERROR,
504                     "Package " + p.name + " was user id " + p.userId
505                     + " but is now user " + sharedUser
506                     + " with id " + sharedUser.userId
507                     + "; I am not changing its files so it will probably fail!");
508             }
509 
510             sharedUser.packages.add(p);
511             p.sharedUser = sharedUser;
512             p.userId = sharedUser.userId;
513         }
514     }
515 
516     /*
517      * Update the shared user setting when a package using
518      * specifying the shared user id is removed. The gids
519      * associated with each permission of the deleted package
520      * are removed from the shared user's gid list only if its
521      * not in use by other permissions of packages in the
522      * shared user setting.
523      */
updateSharedUserPermsLPw(PackageSetting deletedPs, int[] globalGids)524     void updateSharedUserPermsLPw(PackageSetting deletedPs, int[] globalGids) {
525         if ((deletedPs == null) || (deletedPs.pkg == null)) {
526             Slog.i(PackageManagerService.TAG,
527                     "Trying to update info for null package. Just ignoring");
528             return;
529         }
530         // No sharedUserId
531         if (deletedPs.sharedUser == null) {
532             return;
533         }
534         SharedUserSetting sus = deletedPs.sharedUser;
535         // Update permissions
536         for (String eachPerm : deletedPs.pkg.requestedPermissions) {
537             boolean used = false;
538             if (!sus.grantedPermissions.contains(eachPerm)) {
539                 continue;
540             }
541             for (PackageSetting pkg:sus.packages) {
542                 if (pkg.pkg != null &&
543                         !pkg.pkg.packageName.equals(deletedPs.pkg.packageName) &&
544                         pkg.pkg.requestedPermissions.contains(eachPerm)) {
545                     used = true;
546                     break;
547                 }
548             }
549             if (!used) {
550                 // can safely delete this permission from list
551                 sus.grantedPermissions.remove(eachPerm);
552             }
553         }
554         // Update gids
555         int newGids[] = globalGids;
556         for (String eachPerm : sus.grantedPermissions) {
557             BasePermission bp = mPermissions.get(eachPerm);
558             if (bp != null) {
559                 newGids = PackageManagerService.appendInts(newGids, bp.gids);
560             }
561         }
562         sus.gids = newGids;
563     }
564 
removePackageLPw(String name)565     int removePackageLPw(String name) {
566         final PackageSetting p = mPackages.get(name);
567         if (p != null) {
568             mPackages.remove(name);
569             if (p.sharedUser != null) {
570                 p.sharedUser.packages.remove(p);
571                 if (p.sharedUser.packages.size() == 0) {
572                     mSharedUsers.remove(p.sharedUser.name);
573                     removeUserIdLPw(p.sharedUser.userId);
574                     return p.sharedUser.userId;
575                 }
576             } else {
577                 removeUserIdLPw(p.userId);
578                 return p.userId;
579             }
580         }
581         return -1;
582     }
583 
replacePackageLPw(String name, PackageSetting newp)584     private void replacePackageLPw(String name, PackageSetting newp) {
585         final PackageSetting p = mPackages.get(name);
586         if (p != null) {
587             if (p.sharedUser != null) {
588                 p.sharedUser.packages.remove(p);
589                 p.sharedUser.packages.add(newp);
590             } else {
591                 replaceUserIdLPw(p.userId, newp);
592             }
593         }
594         mPackages.put(name, newp);
595     }
596 
addUserIdLPw(int uid, Object obj, Object name)597     private boolean addUserIdLPw(int uid, Object obj, Object name) {
598         if (uid >= PackageManagerService.FIRST_APPLICATION_UID + PackageManagerService.MAX_APPLICATION_UIDS) {
599             return false;
600         }
601 
602         if (uid >= PackageManagerService.FIRST_APPLICATION_UID) {
603             int N = mUserIds.size();
604             final int index = uid - PackageManagerService.FIRST_APPLICATION_UID;
605             while (index >= N) {
606                 mUserIds.add(null);
607                 N++;
608             }
609             if (mUserIds.get(index) != null) {
610                 PackageManagerService.reportSettingsProblem(Log.ERROR,
611                         "Adding duplicate user id: " + uid
612                         + " name=" + name);
613                 return false;
614             }
615             mUserIds.set(index, obj);
616         } else {
617             if (mOtherUserIds.get(uid) != null) {
618                 PackageManagerService.reportSettingsProblem(Log.ERROR,
619                         "Adding duplicate shared id: " + uid
620                         + " name=" + name);
621                 return false;
622             }
623             mOtherUserIds.put(uid, obj);
624         }
625         return true;
626     }
627 
getUserIdLPr(int uid)628     public Object getUserIdLPr(int uid) {
629         if (uid >= PackageManagerService.FIRST_APPLICATION_UID) {
630             final int N = mUserIds.size();
631             final int index = uid - PackageManagerService.FIRST_APPLICATION_UID;
632             return index < N ? mUserIds.get(index) : null;
633         } else {
634             return mOtherUserIds.get(uid);
635         }
636     }
637 
removeUserIdLPw(int uid)638     private void removeUserIdLPw(int uid) {
639         if (uid >= PackageManagerService.FIRST_APPLICATION_UID) {
640             final int N = mUserIds.size();
641             final int index = uid - PackageManagerService.FIRST_APPLICATION_UID;
642             if (index < N) mUserIds.set(index, null);
643         } else {
644             mOtherUserIds.remove(uid);
645         }
646     }
647 
replaceUserIdLPw(int uid, Object obj)648     private void replaceUserIdLPw(int uid, Object obj) {
649         if (uid >= PackageManagerService.FIRST_APPLICATION_UID) {
650             final int N = mUserIds.size();
651             final int index = uid - PackageManagerService.FIRST_APPLICATION_UID;
652             if (index < N) mUserIds.set(index, obj);
653         } else {
654             mOtherUserIds.put(uid, obj);
655         }
656     }
657 
writeStoppedLPr()658     void writeStoppedLPr() {
659         // Keep the old stopped packages around until we know the new ones have
660         // been successfully written.
661         if (mStoppedPackagesFilename.exists()) {
662             // Presence of backup settings file indicates that we failed
663             // to persist packages earlier. So preserve the older
664             // backup for future reference since the current packages
665             // might have been corrupted.
666             if (!mBackupStoppedPackagesFilename.exists()) {
667                 if (!mStoppedPackagesFilename.renameTo(mBackupStoppedPackagesFilename)) {
668                     Log.wtf(PackageManagerService.TAG, "Unable to backup package manager stopped packages, "
669                             + "current changes will be lost at reboot");
670                     return;
671                 }
672             } else {
673                 mStoppedPackagesFilename.delete();
674                 Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");
675             }
676         }
677 
678         try {
679             final FileOutputStream fstr = new FileOutputStream(mStoppedPackagesFilename);
680             final BufferedOutputStream str = new BufferedOutputStream(fstr);
681 
682             //XmlSerializer serializer = XmlUtils.serializerInstance();
683             final XmlSerializer serializer = new FastXmlSerializer();
684             serializer.setOutput(str, "utf-8");
685             serializer.startDocument(null, true);
686             serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
687 
688             serializer.startTag(null, "stopped-packages");
689 
690             for (final PackageSetting pkg : mPackages.values()) {
691                 if (pkg.stopped) {
692                     serializer.startTag(null, "pkg");
693                     serializer.attribute(null, "name", pkg.name);
694                     if (pkg.notLaunched) {
695                         serializer.attribute(null, "nl", "1");
696                     }
697                     serializer.endTag(null, "pkg");
698                 }
699             }
700 
701             serializer.endTag(null, "stopped-packages");
702 
703             serializer.endDocument();
704 
705             str.flush();
706             FileUtils.sync(fstr);
707             str.close();
708 
709             // New settings successfully written, old ones are no longer
710             // needed.
711             mBackupStoppedPackagesFilename.delete();
712             FileUtils.setPermissions(mStoppedPackagesFilename.toString(),
713                     FileUtils.S_IRUSR|FileUtils.S_IWUSR
714                     |FileUtils.S_IRGRP|FileUtils.S_IWGRP
715                     |FileUtils.S_IROTH,
716                     -1, -1);
717 
718             // Done, all is good!
719             return;
720         } catch(java.io.IOException e) {
721             Log.wtf(PackageManagerService.TAG, "Unable to write package manager stopped packages, "
722                     + " current changes will be lost at reboot", e);
723         }
724 
725         // Clean up partially written files
726         if (mStoppedPackagesFilename.exists()) {
727             if (!mStoppedPackagesFilename.delete()) {
728                 Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: " + mStoppedPackagesFilename);
729             }
730         }
731     }
732 
733     // Note: assumed "stopped" field is already cleared in all packages.
readStoppedLPw()734     void readStoppedLPw() {
735         FileInputStream str = null;
736         if (mBackupStoppedPackagesFilename.exists()) {
737             try {
738                 str = new FileInputStream(mBackupStoppedPackagesFilename);
739                 mReadMessages.append("Reading from backup stopped packages file\n");
740                 PackageManagerService.reportSettingsProblem(Log.INFO, "Need to read from backup stopped packages file");
741                 if (mSettingsFilename.exists()) {
742                     // If both the backup and normal file exist, we
743                     // ignore the normal one since it might have been
744                     // corrupted.
745                     Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
746                             + mStoppedPackagesFilename);
747                     mStoppedPackagesFilename.delete();
748                 }
749             } catch (java.io.IOException e) {
750                 // We'll try for the normal settings file.
751             }
752         }
753 
754         try {
755             if (str == null) {
756                 if (!mStoppedPackagesFilename.exists()) {
757                     mReadMessages.append("No stopped packages file found\n");
758                     PackageManagerService.reportSettingsProblem(Log.INFO, "No stopped packages file file; "
759                             + "assuming all started");
760                     // At first boot, make sure no packages are stopped.
761                     // We usually want to have third party apps initialize
762                     // in the stopped state, but not at first boot.
763                     for (PackageSetting pkg : mPackages.values()) {
764                         pkg.stopped = false;
765                         pkg.notLaunched = false;
766                     }
767                     return;
768                 }
769                 str = new FileInputStream(mStoppedPackagesFilename);
770             }
771             final XmlPullParser parser = Xml.newPullParser();
772             parser.setInput(str, null);
773 
774             int type;
775             while ((type=parser.next()) != XmlPullParser.START_TAG
776                        && type != XmlPullParser.END_DOCUMENT) {
777                 ;
778             }
779 
780             if (type != XmlPullParser.START_TAG) {
781                 mReadMessages.append("No start tag found in stopped packages file\n");
782                 PackageManagerService.reportSettingsProblem(Log.WARN,
783                         "No start tag found in package manager stopped packages");
784                 return;
785             }
786 
787             int outerDepth = parser.getDepth();
788             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
789                    && (type != XmlPullParser.END_TAG
790                            || parser.getDepth() > outerDepth)) {
791                 if (type == XmlPullParser.END_TAG
792                         || type == XmlPullParser.TEXT) {
793                     continue;
794                 }
795 
796                 String tagName = parser.getName();
797                 if (tagName.equals("pkg")) {
798                     String name = parser.getAttributeValue(null, "name");
799                     PackageSetting ps = mPackages.get(name);
800                     if (ps != null) {
801                         ps.stopped = true;
802                         if ("1".equals(parser.getAttributeValue(null, "nl"))) {
803                             ps.notLaunched = true;
804                         }
805                     } else {
806                         Slog.w(PackageManagerService.TAG, "No package known for stopped package: " + name);
807                     }
808                     XmlUtils.skipCurrentTag(parser);
809                 } else {
810                     Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
811                           + parser.getName());
812                     XmlUtils.skipCurrentTag(parser);
813                 }
814             }
815 
816             str.close();
817 
818         } catch(XmlPullParserException e) {
819             mReadMessages.append("Error reading: " + e.toString());
820             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading stopped packages: " + e);
821             Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
822 
823         } catch(java.io.IOException e) {
824             mReadMessages.append("Error reading: " + e.toString());
825             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
826             Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
827 
828         }
829     }
830 
writeLPr()831     void writeLPr() {
832         //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
833 
834         // Keep the old settings around until we know the new ones have
835         // been successfully written.
836         if (mSettingsFilename.exists()) {
837             // Presence of backup settings file indicates that we failed
838             // to persist settings earlier. So preserve the older
839             // backup for future reference since the current settings
840             // might have been corrupted.
841             if (!mBackupSettingsFilename.exists()) {
842                 if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {
843                     Log.wtf(PackageManagerService.TAG, "Unable to backup package manager settings, "
844                             + " current changes will be lost at reboot");
845                     return;
846                 }
847             } else {
848                 mSettingsFilename.delete();
849                 Slog.w(PackageManagerService.TAG, "Preserving older settings backup");
850             }
851         }
852 
853         mPastSignatures.clear();
854 
855         try {
856             FileOutputStream fstr = new FileOutputStream(mSettingsFilename);
857             BufferedOutputStream str = new BufferedOutputStream(fstr);
858 
859             //XmlSerializer serializer = XmlUtils.serializerInstance();
860             XmlSerializer serializer = new FastXmlSerializer();
861             serializer.setOutput(str, "utf-8");
862             serializer.startDocument(null, true);
863             serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
864 
865             serializer.startTag(null, "packages");
866 
867             serializer.startTag(null, "last-platform-version");
868             serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform));
869             serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform));
870             serializer.endTag(null, "last-platform-version");
871 
872             if (mVerifierDeviceIdentity != null) {
873                 serializer.startTag(null, "verifier");
874                 serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());
875                 serializer.endTag(null, "verifier");
876             }
877 
878             serializer.startTag(null, "permission-trees");
879             for (BasePermission bp : mPermissionTrees.values()) {
880                 writePermissionLPr(serializer, bp);
881             }
882             serializer.endTag(null, "permission-trees");
883 
884             serializer.startTag(null, "permissions");
885             for (BasePermission bp : mPermissions.values()) {
886                 writePermissionLPr(serializer, bp);
887             }
888             serializer.endTag(null, "permissions");
889 
890             for (final PackageSetting pkg : mPackages.values()) {
891                 writePackageLPr(serializer, pkg);
892             }
893 
894             for (final PackageSetting pkg : mDisabledSysPackages.values()) {
895                 writeDisabledSysPackageLPr(serializer, pkg);
896             }
897 
898             serializer.startTag(null, "preferred-activities");
899             for (final PreferredActivity pa : mPreferredActivities.filterSet()) {
900                 serializer.startTag(null, "item");
901                 pa.writeToXml(serializer);
902                 serializer.endTag(null, "item");
903             }
904             serializer.endTag(null, "preferred-activities");
905 
906             for (final SharedUserSetting usr : mSharedUsers.values()) {
907                 serializer.startTag(null, "shared-user");
908                 serializer.attribute(null, "name", usr.name);
909                 serializer.attribute(null, "userId",
910                         Integer.toString(usr.userId));
911                 usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
912                 serializer.startTag(null, "perms");
913                 for (String name : usr.grantedPermissions) {
914                     serializer.startTag(null, "item");
915                     serializer.attribute(null, "name", name);
916                     serializer.endTag(null, "item");
917                 }
918                 serializer.endTag(null, "perms");
919                 serializer.endTag(null, "shared-user");
920             }
921 
922             if (mPackagesToBeCleaned.size() > 0) {
923                 for (int i=0; i<mPackagesToBeCleaned.size(); i++) {
924                     serializer.startTag(null, "cleaning-package");
925                     serializer.attribute(null, "name", mPackagesToBeCleaned.get(i));
926                     serializer.endTag(null, "cleaning-package");
927                 }
928             }
929 
930             if (mRenamedPackages.size() > 0) {
931                 for (HashMap.Entry<String, String> e : mRenamedPackages.entrySet()) {
932                     serializer.startTag(null, "renamed-package");
933                     serializer.attribute(null, "new", e.getKey());
934                     serializer.attribute(null, "old", e.getValue());
935                     serializer.endTag(null, "renamed-package");
936                 }
937             }
938 
939             serializer.endTag(null, "packages");
940 
941             serializer.endDocument();
942 
943             str.flush();
944             FileUtils.sync(fstr);
945             str.close();
946 
947             // New settings successfully written, old ones are no longer
948             // needed.
949             mBackupSettingsFilename.delete();
950             FileUtils.setPermissions(mSettingsFilename.toString(),
951                     FileUtils.S_IRUSR|FileUtils.S_IWUSR
952                     |FileUtils.S_IRGRP|FileUtils.S_IWGRP
953                     |FileUtils.S_IROTH,
954                     -1, -1);
955 
956             // Write package list file now, use a JournaledFile.
957             //
958             File tempFile = new File(mPackageListFilename.toString() + ".tmp");
959             JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
960 
961             fstr = new FileOutputStream(journal.chooseForWrite());
962             str = new BufferedOutputStream(fstr);
963             try {
964                 StringBuilder sb = new StringBuilder();
965                 for (final PackageSetting pkg : mPackages.values()) {
966                     ApplicationInfo ai = pkg.pkg.applicationInfo;
967                     String dataPath = ai.dataDir;
968                     boolean isDebug  = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
969 
970                     // Avoid any application that has a space in its path
971                     // or that is handled by the system.
972                     if (dataPath.indexOf(" ") >= 0 || ai.uid <= Process.FIRST_APPLICATION_UID)
973                         continue;
974 
975                     // we store on each line the following information for now:
976                     //
977                     // pkgName    - package name
978                     // userId     - application-specific user id
979                     // debugFlag  - 0 or 1 if the package is debuggable.
980                     // dataPath   - path to package's data path
981                     //
982                     // NOTE: We prefer not to expose all ApplicationInfo flags for now.
983                     //
984                     // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
985                     // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
986                     //   system/core/run-as/run-as.c
987                     //
988                     sb.setLength(0);
989                     sb.append(ai.packageName);
990                     sb.append(" ");
991                     sb.append((int)ai.uid);
992                     sb.append(isDebug ? " 1 " : " 0 ");
993                     sb.append(dataPath);
994                     sb.append("\n");
995                     str.write(sb.toString().getBytes());
996                 }
997                 str.flush();
998                 FileUtils.sync(fstr);
999                 str.close();
1000                 journal.commit();
1001             }
1002             catch (Exception  e) {
1003                 journal.rollback();
1004             }
1005 
1006             FileUtils.setPermissions(mPackageListFilename.toString(),
1007                     FileUtils.S_IRUSR|FileUtils.S_IWUSR
1008                     |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1009                     |FileUtils.S_IROTH,
1010                     -1, -1);
1011 
1012             writeStoppedLPr();
1013 
1014             return;
1015 
1016         } catch(XmlPullParserException e) {
1017             Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
1018                     + "current changes will be lost at reboot", e);
1019         } catch(java.io.IOException e) {
1020             Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
1021                     + "current changes will be lost at reboot", e);
1022         }
1023         // Clean up partially written files
1024         if (mSettingsFilename.exists()) {
1025             if (!mSettingsFilename.delete()) {
1026                 Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: " + mSettingsFilename);
1027             }
1028         }
1029         //Debug.stopMethodTracing();
1030     }
1031 
writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)1032     void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
1033             throws java.io.IOException {
1034         serializer.startTag(null, "updated-package");
1035         serializer.attribute(null, "name", pkg.name);
1036         if (pkg.realName != null) {
1037             serializer.attribute(null, "realName", pkg.realName);
1038         }
1039         serializer.attribute(null, "codePath", pkg.codePathString);
1040         serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
1041         serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
1042         serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
1043         serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
1044         if (!pkg.resourcePathString.equals(pkg.codePathString)) {
1045             serializer.attribute(null, "resourcePath", pkg.resourcePathString);
1046         }
1047         if (pkg.nativeLibraryPathString != null) {
1048             serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
1049         }
1050         if (pkg.sharedUser == null) {
1051             serializer.attribute(null, "userId", Integer.toString(pkg.userId));
1052         } else {
1053             serializer.attribute(null, "sharedUserId", Integer.toString(pkg.userId));
1054         }
1055         serializer.startTag(null, "perms");
1056         if (pkg.sharedUser == null) {
1057             // If this is a shared user, the permissions will
1058             // be written there. We still need to write an
1059             // empty permissions list so permissionsFixed will
1060             // be set.
1061             for (final String name : pkg.grantedPermissions) {
1062                 BasePermission bp = mPermissions.get(name);
1063                 if (bp != null) {
1064                     // We only need to write signature or system permissions but
1065                     // this wont
1066                     // match the semantics of grantedPermissions. So write all
1067                     // permissions.
1068                     serializer.startTag(null, "item");
1069                     serializer.attribute(null, "name", name);
1070                     serializer.endTag(null, "item");
1071                 }
1072             }
1073         }
1074         serializer.endTag(null, "perms");
1075         serializer.endTag(null, "updated-package");
1076     }
1077 
writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)1078     void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)
1079             throws java.io.IOException {
1080         serializer.startTag(null, "package");
1081         serializer.attribute(null, "name", pkg.name);
1082         if (pkg.realName != null) {
1083             serializer.attribute(null, "realName", pkg.realName);
1084         }
1085         serializer.attribute(null, "codePath", pkg.codePathString);
1086         if (!pkg.resourcePathString.equals(pkg.codePathString)) {
1087             serializer.attribute(null, "resourcePath", pkg.resourcePathString);
1088         }
1089         if (pkg.nativeLibraryPathString != null) {
1090             serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
1091         }
1092         serializer.attribute(null, "flags", Integer.toString(pkg.pkgFlags));
1093         serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
1094         serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
1095         serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
1096         serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
1097         if (pkg.sharedUser == null) {
1098             serializer.attribute(null, "userId", Integer.toString(pkg.userId));
1099         } else {
1100             serializer.attribute(null, "sharedUserId", Integer.toString(pkg.userId));
1101         }
1102         if (pkg.uidError) {
1103             serializer.attribute(null, "uidError", "true");
1104         }
1105         if (pkg.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
1106             serializer.attribute(null, "enabled", Integer.toString(pkg.enabled));
1107         }
1108         if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
1109             serializer.attribute(null, "installStatus", "false");
1110         }
1111         if (pkg.installerPackageName != null) {
1112             serializer.attribute(null, "installer", pkg.installerPackageName);
1113         }
1114         pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
1115         if ((pkg.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1116             serializer.startTag(null, "perms");
1117             if (pkg.sharedUser == null) {
1118                 // If this is a shared user, the permissions will
1119                 // be written there. We still need to write an
1120                 // empty permissions list so permissionsFixed will
1121                 // be set.
1122                 for (final String name : pkg.grantedPermissions) {
1123                     serializer.startTag(null, "item");
1124                     serializer.attribute(null, "name", name);
1125                     serializer.endTag(null, "item");
1126                 }
1127             }
1128             serializer.endTag(null, "perms");
1129         }
1130         if (pkg.disabledComponents.size() > 0) {
1131             serializer.startTag(null, "disabled-components");
1132             for (final String name : pkg.disabledComponents) {
1133                 serializer.startTag(null, "item");
1134                 serializer.attribute(null, "name", name);
1135                 serializer.endTag(null, "item");
1136             }
1137             serializer.endTag(null, "disabled-components");
1138         }
1139         if (pkg.enabledComponents.size() > 0) {
1140             serializer.startTag(null, "enabled-components");
1141             for (final String name : pkg.enabledComponents) {
1142                 serializer.startTag(null, "item");
1143                 serializer.attribute(null, "name", name);
1144                 serializer.endTag(null, "item");
1145             }
1146             serializer.endTag(null, "enabled-components");
1147         }
1148 
1149         serializer.endTag(null, "package");
1150     }
1151 
writePermissionLPr(XmlSerializer serializer, BasePermission bp)1152     void writePermissionLPr(XmlSerializer serializer, BasePermission bp)
1153             throws XmlPullParserException, java.io.IOException {
1154         if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) {
1155             serializer.startTag(null, "item");
1156             serializer.attribute(null, "name", bp.name);
1157             serializer.attribute(null, "package", bp.sourcePackage);
1158             if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
1159                 serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel));
1160             }
1161             if (PackageManagerService.DEBUG_SETTINGS)
1162                 Log.v(PackageManagerService.TAG, "Writing perm: name=" + bp.name + " type="
1163                         + bp.type);
1164             if (bp.type == BasePermission.TYPE_DYNAMIC) {
1165                 final PermissionInfo pi = bp.perm != null ? bp.perm.info : bp.pendingInfo;
1166                 if (pi != null) {
1167                     serializer.attribute(null, "type", "dynamic");
1168                     if (pi.icon != 0) {
1169                         serializer.attribute(null, "icon", Integer.toString(pi.icon));
1170                     }
1171                     if (pi.nonLocalizedLabel != null) {
1172                         serializer.attribute(null, "label", pi.nonLocalizedLabel.toString());
1173                     }
1174                 }
1175             }
1176             serializer.endTag(null, "item");
1177         }
1178     }
1179 
getListOfIncompleteInstallPackagesLPr()1180     ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() {
1181         final HashSet<String> kList = new HashSet<String>(mPackages.keySet());
1182         final Iterator<String> its = kList.iterator();
1183         final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
1184         while (its.hasNext()) {
1185             final String key = its.next();
1186             final PackageSetting ps = mPackages.get(key);
1187             if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
1188                 ret.add(ps);
1189             }
1190         }
1191         return ret;
1192     }
1193 
readLPw()1194     boolean readLPw() {
1195         FileInputStream str = null;
1196         if (mBackupSettingsFilename.exists()) {
1197             try {
1198                 str = new FileInputStream(mBackupSettingsFilename);
1199                 mReadMessages.append("Reading from backup settings file\n");
1200                 PackageManagerService.reportSettingsProblem(Log.INFO,
1201                         "Need to read from backup settings file");
1202                 if (mSettingsFilename.exists()) {
1203                     // If both the backup and settings file exist, we
1204                     // ignore the settings since it might have been
1205                     // corrupted.
1206                     Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
1207                             + mSettingsFilename);
1208                     mSettingsFilename.delete();
1209                 }
1210             } catch (java.io.IOException e) {
1211                 // We'll try for the normal settings file.
1212             }
1213         }
1214 
1215         mPendingPackages.clear();
1216         mPastSignatures.clear();
1217 
1218         try {
1219             if (str == null) {
1220                 if (!mSettingsFilename.exists()) {
1221                     mReadMessages.append("No settings file found\n");
1222                     PackageManagerService.reportSettingsProblem(Log.INFO,
1223                             "No settings file; creating initial state");
1224                     return false;
1225                 }
1226                 str = new FileInputStream(mSettingsFilename);
1227             }
1228             XmlPullParser parser = Xml.newPullParser();
1229             parser.setInput(str, null);
1230 
1231             int type;
1232             while ((type = parser.next()) != XmlPullParser.START_TAG
1233                     && type != XmlPullParser.END_DOCUMENT) {
1234                 ;
1235             }
1236 
1237             if (type != XmlPullParser.START_TAG) {
1238                 mReadMessages.append("No start tag found in settings file\n");
1239                 PackageManagerService.reportSettingsProblem(Log.WARN,
1240                         "No start tag found in package manager settings");
1241                 Log.wtf(PackageManagerService.TAG,
1242                         "No start tag found in package manager settings");
1243                 return false;
1244             }
1245 
1246             int outerDepth = parser.getDepth();
1247             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1248                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1249                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1250                     continue;
1251                 }
1252 
1253                 String tagName = parser.getName();
1254                 if (tagName.equals("package")) {
1255                     readPackageLPw(parser);
1256                 } else if (tagName.equals("permissions")) {
1257                     readPermissionsLPw(mPermissions, parser);
1258                 } else if (tagName.equals("permission-trees")) {
1259                     readPermissionsLPw(mPermissionTrees, parser);
1260                 } else if (tagName.equals("shared-user")) {
1261                     readSharedUserLPw(parser);
1262                 } else if (tagName.equals("preferred-packages")) {
1263                     // no longer used.
1264                 } else if (tagName.equals("preferred-activities")) {
1265                     readPreferredActivitiesLPw(parser);
1266                 } else if (tagName.equals("updated-package")) {
1267                     readDisabledSysPackageLPw(parser);
1268                 } else if (tagName.equals("cleaning-package")) {
1269                     String name = parser.getAttributeValue(null, "name");
1270                     if (name != null) {
1271                         mPackagesToBeCleaned.add(name);
1272                     }
1273                 } else if (tagName.equals("renamed-package")) {
1274                     String nname = parser.getAttributeValue(null, "new");
1275                     String oname = parser.getAttributeValue(null, "old");
1276                     if (nname != null && oname != null) {
1277                         mRenamedPackages.put(nname, oname);
1278                     }
1279                 } else if (tagName.equals("last-platform-version")) {
1280                     mInternalSdkPlatform = mExternalSdkPlatform = 0;
1281                     try {
1282                         String internal = parser.getAttributeValue(null, "internal");
1283                         if (internal != null) {
1284                             mInternalSdkPlatform = Integer.parseInt(internal);
1285                         }
1286                         String external = parser.getAttributeValue(null, "external");
1287                         if (external != null) {
1288                             mExternalSdkPlatform = Integer.parseInt(external);
1289                         }
1290                     } catch (NumberFormatException e) {
1291                     }
1292                 } else if (tagName.equals("verifier")) {
1293                     final String deviceIdentity = parser.getAttributeValue(null, "device");
1294                     try {
1295                         mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
1296                     } catch (IllegalArgumentException e) {
1297                         Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
1298                                 + e.getMessage());
1299                     }
1300                 } else {
1301                     Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
1302                             + parser.getName());
1303                     XmlUtils.skipCurrentTag(parser);
1304                 }
1305             }
1306 
1307             str.close();
1308 
1309         } catch (XmlPullParserException e) {
1310             mReadMessages.append("Error reading: " + e.toString());
1311             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1312             Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
1313 
1314         } catch (java.io.IOException e) {
1315             mReadMessages.append("Error reading: " + e.toString());
1316             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1317             Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
1318 
1319         }
1320 
1321         final int N = mPendingPackages.size();
1322         for (int i = 0; i < N; i++) {
1323             final PendingPackage pp = mPendingPackages.get(i);
1324             Object idObj = getUserIdLPr(pp.sharedId);
1325             if (idObj != null && idObj instanceof SharedUserSetting) {
1326                 PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
1327                         (SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
1328                         pp.nativeLibraryPathString, pp.versionCode, pp.pkgFlags, true, true);
1329                 if (p == null) {
1330                     PackageManagerService.reportSettingsProblem(Log.WARN,
1331                             "Unable to create application package for " + pp.name);
1332                     continue;
1333                 }
1334                 p.copyFrom(pp);
1335             } else if (idObj != null) {
1336                 String msg = "Bad package setting: package " + pp.name + " has shared uid "
1337                         + pp.sharedId + " that is not a shared uid\n";
1338                 mReadMessages.append(msg);
1339                 PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
1340             } else {
1341                 String msg = "Bad package setting: package " + pp.name + " has shared uid "
1342                         + pp.sharedId + " that is not defined\n";
1343                 mReadMessages.append(msg);
1344                 PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
1345             }
1346         }
1347         mPendingPackages.clear();
1348 
1349         /*
1350          * Make sure all the updated system packages have their shared users
1351          * associated with them.
1352          */
1353         final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
1354         while (disabledIt.hasNext()) {
1355             final PackageSetting disabledPs = disabledIt.next();
1356             final Object id = getUserIdLPr(disabledPs.userId);
1357             if (id != null && id instanceof SharedUserSetting) {
1358                 disabledPs.sharedUser = (SharedUserSetting) id;
1359             }
1360         }
1361 
1362         readStoppedLPw();
1363 
1364         mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
1365                 + mSharedUsers.size() + " shared uids\n");
1366 
1367         return true;
1368     }
1369 
readInt(XmlPullParser parser, String ns, String name, int defValue)1370     private int readInt(XmlPullParser parser, String ns, String name, int defValue) {
1371         String v = parser.getAttributeValue(ns, name);
1372         try {
1373             if (v == null) {
1374                 return defValue;
1375             }
1376             return Integer.parseInt(v);
1377         } catch (NumberFormatException e) {
1378             PackageManagerService.reportSettingsProblem(Log.WARN,
1379                     "Error in package manager settings: attribute " + name
1380                             + " has bad integer value " + v + " at "
1381                             + parser.getPositionDescription());
1382         }
1383         return defValue;
1384     }
1385 
readPermissionsLPw(HashMap<String, BasePermission> out, XmlPullParser parser)1386     private void readPermissionsLPw(HashMap<String, BasePermission> out, XmlPullParser parser)
1387             throws IOException, XmlPullParserException {
1388         int outerDepth = parser.getDepth();
1389         int type;
1390         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1391                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1392             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1393                 continue;
1394             }
1395 
1396             final String tagName = parser.getName();
1397             if (tagName.equals("item")) {
1398                 final String name = parser.getAttributeValue(null, "name");
1399                 final String sourcePackage = parser.getAttributeValue(null, "package");
1400                 final String ptype = parser.getAttributeValue(null, "type");
1401                 if (name != null && sourcePackage != null) {
1402                     final boolean dynamic = "dynamic".equals(ptype);
1403                     final BasePermission bp = new BasePermission(name, sourcePackage,
1404                             dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
1405                     bp.protectionLevel = readInt(parser, null, "protection",
1406                             PermissionInfo.PROTECTION_NORMAL);
1407                     if (dynamic) {
1408                         PermissionInfo pi = new PermissionInfo();
1409                         pi.packageName = sourcePackage.intern();
1410                         pi.name = name.intern();
1411                         pi.icon = readInt(parser, null, "icon", 0);
1412                         pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
1413                         pi.protectionLevel = bp.protectionLevel;
1414                         bp.pendingInfo = pi;
1415                     }
1416                     out.put(bp.name, bp);
1417                 } else {
1418                     PackageManagerService.reportSettingsProblem(Log.WARN,
1419                             "Error in package manager settings: permissions has" + " no name at "
1420                                     + parser.getPositionDescription());
1421                 }
1422             } else {
1423                 PackageManagerService.reportSettingsProblem(Log.WARN,
1424                         "Unknown element reading permissions: " + parser.getName() + " at "
1425                                 + parser.getPositionDescription());
1426             }
1427             XmlUtils.skipCurrentTag(parser);
1428         }
1429     }
1430 
readDisabledSysPackageLPw(XmlPullParser parser)1431     private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
1432             IOException {
1433         String name = parser.getAttributeValue(null, "name");
1434         String realName = parser.getAttributeValue(null, "realName");
1435         String codePathStr = parser.getAttributeValue(null, "codePath");
1436         String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
1437         String nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
1438         if (resourcePathStr == null) {
1439             resourcePathStr = codePathStr;
1440         }
1441         String version = parser.getAttributeValue(null, "version");
1442         int versionCode = 0;
1443         if (version != null) {
1444             try {
1445                 versionCode = Integer.parseInt(version);
1446             } catch (NumberFormatException e) {
1447             }
1448         }
1449 
1450         int pkgFlags = 0;
1451         pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
1452         PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr),
1453                 new File(resourcePathStr), nativeLibraryPathStr, versionCode, pkgFlags);
1454         String timeStampStr = parser.getAttributeValue(null, "ft");
1455         if (timeStampStr != null) {
1456             try {
1457                 long timeStamp = Long.parseLong(timeStampStr, 16);
1458                 ps.setTimeStamp(timeStamp);
1459             } catch (NumberFormatException e) {
1460             }
1461         } else {
1462             timeStampStr = parser.getAttributeValue(null, "ts");
1463             if (timeStampStr != null) {
1464                 try {
1465                     long timeStamp = Long.parseLong(timeStampStr);
1466                     ps.setTimeStamp(timeStamp);
1467                 } catch (NumberFormatException e) {
1468                 }
1469             }
1470         }
1471         timeStampStr = parser.getAttributeValue(null, "it");
1472         if (timeStampStr != null) {
1473             try {
1474                 ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
1475             } catch (NumberFormatException e) {
1476             }
1477         }
1478         timeStampStr = parser.getAttributeValue(null, "ut");
1479         if (timeStampStr != null) {
1480             try {
1481                 ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
1482             } catch (NumberFormatException e) {
1483             }
1484         }
1485         String idStr = parser.getAttributeValue(null, "userId");
1486         ps.userId = idStr != null ? Integer.parseInt(idStr) : 0;
1487         if (ps.userId <= 0) {
1488             String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
1489             ps.userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
1490         }
1491         int outerDepth = parser.getDepth();
1492         int type;
1493         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1494                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1495             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1496                 continue;
1497             }
1498 
1499             String tagName = parser.getName();
1500             if (tagName.equals("perms")) {
1501                 readGrantedPermissionsLPw(parser, ps.grantedPermissions);
1502             } else {
1503                 PackageManagerService.reportSettingsProblem(Log.WARN,
1504                         "Unknown element under <updated-package>: " + parser.getName());
1505                 XmlUtils.skipCurrentTag(parser);
1506             }
1507         }
1508         mDisabledSysPackages.put(name, ps);
1509     }
1510 
readPackageLPw(XmlPullParser parser)1511     private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
1512         String name = null;
1513         String realName = null;
1514         String idStr = null;
1515         String sharedIdStr = null;
1516         String codePathStr = null;
1517         String resourcePathStr = null;
1518         String nativeLibraryPathStr = null;
1519         String systemStr = null;
1520         String installerPackageName = null;
1521         String uidError = null;
1522         int pkgFlags = 0;
1523         long timeStamp = 0;
1524         long firstInstallTime = 0;
1525         long lastUpdateTime = 0;
1526         PackageSettingBase packageSetting = null;
1527         String version = null;
1528         int versionCode = 0;
1529         try {
1530             name = parser.getAttributeValue(null, "name");
1531             realName = parser.getAttributeValue(null, "realName");
1532             idStr = parser.getAttributeValue(null, "userId");
1533             uidError = parser.getAttributeValue(null, "uidError");
1534             sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
1535             codePathStr = parser.getAttributeValue(null, "codePath");
1536             resourcePathStr = parser.getAttributeValue(null, "resourcePath");
1537             nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
1538             version = parser.getAttributeValue(null, "version");
1539             if (version != null) {
1540                 try {
1541                     versionCode = Integer.parseInt(version);
1542                 } catch (NumberFormatException e) {
1543                 }
1544             }
1545             installerPackageName = parser.getAttributeValue(null, "installer");
1546 
1547             systemStr = parser.getAttributeValue(null, "flags");
1548             if (systemStr != null) {
1549                 try {
1550                     pkgFlags = Integer.parseInt(systemStr);
1551                 } catch (NumberFormatException e) {
1552                 }
1553             } else {
1554                 // For backward compatibility
1555                 systemStr = parser.getAttributeValue(null, "system");
1556                 if (systemStr != null) {
1557                     pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
1558                             : 0;
1559                 } else {
1560                     // Old settings that don't specify system... just treat
1561                     // them as system, good enough.
1562                     pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
1563                 }
1564             }
1565             String timeStampStr = parser.getAttributeValue(null, "ft");
1566             if (timeStampStr != null) {
1567                 try {
1568                     timeStamp = Long.parseLong(timeStampStr, 16);
1569                 } catch (NumberFormatException e) {
1570                 }
1571             } else {
1572                 timeStampStr = parser.getAttributeValue(null, "ts");
1573                 if (timeStampStr != null) {
1574                     try {
1575                         timeStamp = Long.parseLong(timeStampStr);
1576                     } catch (NumberFormatException e) {
1577                     }
1578                 }
1579             }
1580             timeStampStr = parser.getAttributeValue(null, "it");
1581             if (timeStampStr != null) {
1582                 try {
1583                     firstInstallTime = Long.parseLong(timeStampStr, 16);
1584                 } catch (NumberFormatException e) {
1585                 }
1586             }
1587             timeStampStr = parser.getAttributeValue(null, "ut");
1588             if (timeStampStr != null) {
1589                 try {
1590                     lastUpdateTime = Long.parseLong(timeStampStr, 16);
1591                 } catch (NumberFormatException e) {
1592                 }
1593             }
1594             if (PackageManagerService.DEBUG_SETTINGS)
1595                 Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
1596                         + " sharedUserId=" + sharedIdStr);
1597             int userId = idStr != null ? Integer.parseInt(idStr) : 0;
1598             if (resourcePathStr == null) {
1599                 resourcePathStr = codePathStr;
1600             }
1601             if (realName != null) {
1602                 realName = realName.intern();
1603             }
1604             if (name == null) {
1605                 PackageManagerService.reportSettingsProblem(Log.WARN,
1606                         "Error in package manager settings: <package> has no name at "
1607                                 + parser.getPositionDescription());
1608             } else if (codePathStr == null) {
1609                 PackageManagerService.reportSettingsProblem(Log.WARN,
1610                         "Error in package manager settings: <package> has no codePath at "
1611                                 + parser.getPositionDescription());
1612             } else if (userId > 0) {
1613                 packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
1614                         new File(resourcePathStr), nativeLibraryPathStr, userId, versionCode,
1615                         pkgFlags);
1616                 if (PackageManagerService.DEBUG_SETTINGS)
1617                     Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
1618                             + userId + " pkg=" + packageSetting);
1619                 if (packageSetting == null) {
1620                     PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
1621                             + userId + " while parsing settings at "
1622                             + parser.getPositionDescription());
1623                 } else {
1624                     packageSetting.setTimeStamp(timeStamp);
1625                     packageSetting.firstInstallTime = firstInstallTime;
1626                     packageSetting.lastUpdateTime = lastUpdateTime;
1627                 }
1628             } else if (sharedIdStr != null) {
1629                 userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
1630                 if (userId > 0) {
1631                     packageSetting = new PendingPackage(name.intern(), realName, new File(
1632                             codePathStr), new File(resourcePathStr), nativeLibraryPathStr, userId,
1633                             versionCode, pkgFlags);
1634                     packageSetting.setTimeStamp(timeStamp);
1635                     packageSetting.firstInstallTime = firstInstallTime;
1636                     packageSetting.lastUpdateTime = lastUpdateTime;
1637                     mPendingPackages.add((PendingPackage) packageSetting);
1638                     if (PackageManagerService.DEBUG_SETTINGS)
1639                         Log.i(PackageManagerService.TAG, "Reading package " + name
1640                                 + ": sharedUserId=" + userId + " pkg=" + packageSetting);
1641                 } else {
1642                     PackageManagerService.reportSettingsProblem(Log.WARN,
1643                             "Error in package manager settings: package " + name
1644                                     + " has bad sharedId " + sharedIdStr + " at "
1645                                     + parser.getPositionDescription());
1646                 }
1647             } else {
1648                 PackageManagerService.reportSettingsProblem(Log.WARN,
1649                         "Error in package manager settings: package " + name + " has bad userId "
1650                                 + idStr + " at " + parser.getPositionDescription());
1651             }
1652         } catch (NumberFormatException e) {
1653             PackageManagerService.reportSettingsProblem(Log.WARN,
1654                     "Error in package manager settings: package " + name + " has bad userId "
1655                             + idStr + " at " + parser.getPositionDescription());
1656         }
1657         if (packageSetting != null) {
1658             packageSetting.uidError = "true".equals(uidError);
1659             packageSetting.installerPackageName = installerPackageName;
1660             packageSetting.nativeLibraryPathString = nativeLibraryPathStr;
1661             final String enabledStr = parser.getAttributeValue(null, "enabled");
1662             if (enabledStr != null) {
1663                 try {
1664                     packageSetting.enabled = Integer.parseInt(enabledStr);
1665                 } catch (NumberFormatException e) {
1666                     if (enabledStr.equalsIgnoreCase("true")) {
1667                         packageSetting.enabled = COMPONENT_ENABLED_STATE_ENABLED;
1668                     } else if (enabledStr.equalsIgnoreCase("false")) {
1669                         packageSetting.enabled = COMPONENT_ENABLED_STATE_DISABLED;
1670                     } else if (enabledStr.equalsIgnoreCase("default")) {
1671                         packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT;
1672                     } else {
1673                         PackageManagerService.reportSettingsProblem(Log.WARN,
1674                                 "Error in package manager settings: package " + name
1675                                         + " has bad enabled value: " + idStr + " at "
1676                                         + parser.getPositionDescription());
1677                     }
1678                 }
1679             } else {
1680                 packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT;
1681             }
1682             final String installStatusStr = parser.getAttributeValue(null, "installStatus");
1683             if (installStatusStr != null) {
1684                 if (installStatusStr.equalsIgnoreCase("false")) {
1685                     packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE;
1686                 } else {
1687                     packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
1688                 }
1689             }
1690 
1691             int outerDepth = parser.getDepth();
1692             int type;
1693             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1694                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1695                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1696                     continue;
1697                 }
1698 
1699                 String tagName = parser.getName();
1700                 if (tagName.equals("disabled-components")) {
1701                     readDisabledComponentsLPw(packageSetting, parser);
1702                 } else if (tagName.equals("enabled-components")) {
1703                     readEnabledComponentsLPw(packageSetting, parser);
1704                 } else if (tagName.equals("sigs")) {
1705                     packageSetting.signatures.readXml(parser, mPastSignatures);
1706                 } else if (tagName.equals("perms")) {
1707                     readGrantedPermissionsLPw(parser, packageSetting.grantedPermissions);
1708                     packageSetting.permissionsFixed = true;
1709                 } else {
1710                     PackageManagerService.reportSettingsProblem(Log.WARN,
1711                             "Unknown element under <package>: " + parser.getName());
1712                     XmlUtils.skipCurrentTag(parser);
1713                 }
1714             }
1715         } else {
1716             XmlUtils.skipCurrentTag(parser);
1717         }
1718     }
1719 
readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser)1720     private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser)
1721             throws IOException, XmlPullParserException {
1722         int outerDepth = parser.getDepth();
1723         int type;
1724         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1725                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1726             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1727                 continue;
1728             }
1729 
1730             String tagName = parser.getName();
1731             if (tagName.equals("item")) {
1732                 String name = parser.getAttributeValue(null, "name");
1733                 if (name != null) {
1734                     packageSetting.disabledComponents.add(name.intern());
1735                 } else {
1736                     PackageManagerService.reportSettingsProblem(Log.WARN,
1737                             "Error in package manager settings: <disabled-components> has"
1738                                     + " no name at " + parser.getPositionDescription());
1739                 }
1740             } else {
1741                 PackageManagerService.reportSettingsProblem(Log.WARN,
1742                         "Unknown element under <disabled-components>: " + parser.getName());
1743             }
1744             XmlUtils.skipCurrentTag(parser);
1745         }
1746     }
1747 
readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser)1748     private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser)
1749             throws IOException, XmlPullParserException {
1750         int outerDepth = parser.getDepth();
1751         int type;
1752         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1753                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1754             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1755                 continue;
1756             }
1757 
1758             String tagName = parser.getName();
1759             if (tagName.equals("item")) {
1760                 String name = parser.getAttributeValue(null, "name");
1761                 if (name != null) {
1762                     packageSetting.enabledComponents.add(name.intern());
1763                 } else {
1764                     PackageManagerService.reportSettingsProblem(Log.WARN,
1765                             "Error in package manager settings: <enabled-components> has"
1766                                     + " no name at " + parser.getPositionDescription());
1767                 }
1768             } else {
1769                 PackageManagerService.reportSettingsProblem(Log.WARN,
1770                         "Unknown element under <enabled-components>: " + parser.getName());
1771             }
1772             XmlUtils.skipCurrentTag(parser);
1773         }
1774     }
1775 
readSharedUserLPw(XmlPullParser parser)1776     private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
1777         String name = null;
1778         String idStr = null;
1779         int pkgFlags = 0;
1780         SharedUserSetting su = null;
1781         try {
1782             name = parser.getAttributeValue(null, "name");
1783             idStr = parser.getAttributeValue(null, "userId");
1784             int userId = idStr != null ? Integer.parseInt(idStr) : 0;
1785             if ("true".equals(parser.getAttributeValue(null, "system"))) {
1786                 pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
1787             }
1788             if (name == null) {
1789                 PackageManagerService.reportSettingsProblem(Log.WARN,
1790                         "Error in package manager settings: <shared-user> has no name at "
1791                                 + parser.getPositionDescription());
1792             } else if (userId == 0) {
1793                 PackageManagerService.reportSettingsProblem(Log.WARN,
1794                         "Error in package manager settings: shared-user " + name
1795                                 + " has bad userId " + idStr + " at "
1796                                 + parser.getPositionDescription());
1797             } else {
1798                 if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags)) == null) {
1799                     PackageManagerService
1800                             .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
1801                                     + parser.getPositionDescription());
1802                 }
1803             }
1804         } catch (NumberFormatException e) {
1805             PackageManagerService.reportSettingsProblem(Log.WARN,
1806                     "Error in package manager settings: package " + name + " has bad userId "
1807                             + idStr + " at " + parser.getPositionDescription());
1808         }
1809         ;
1810 
1811         if (su != null) {
1812             int outerDepth = parser.getDepth();
1813             int type;
1814             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1815                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1816                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1817                     continue;
1818                 }
1819 
1820                 String tagName = parser.getName();
1821                 if (tagName.equals("sigs")) {
1822                     su.signatures.readXml(parser, mPastSignatures);
1823                 } else if (tagName.equals("perms")) {
1824                     readGrantedPermissionsLPw(parser, su.grantedPermissions);
1825                 } else {
1826                     PackageManagerService.reportSettingsProblem(Log.WARN,
1827                             "Unknown element under <shared-user>: " + parser.getName());
1828                     XmlUtils.skipCurrentTag(parser);
1829                 }
1830             }
1831 
1832         } else {
1833             XmlUtils.skipCurrentTag(parser);
1834         }
1835     }
1836 
readGrantedPermissionsLPw(XmlPullParser parser, HashSet<String> outPerms)1837     private void readGrantedPermissionsLPw(XmlPullParser parser, HashSet<String> outPerms)
1838             throws IOException, XmlPullParserException {
1839         int outerDepth = parser.getDepth();
1840         int type;
1841         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1842                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1843             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1844                 continue;
1845             }
1846 
1847             String tagName = parser.getName();
1848             if (tagName.equals("item")) {
1849                 String name = parser.getAttributeValue(null, "name");
1850                 if (name != null) {
1851                     outPerms.add(name.intern());
1852                 } else {
1853                     PackageManagerService.reportSettingsProblem(Log.WARN,
1854                             "Error in package manager settings: <perms> has" + " no name at "
1855                                     + parser.getPositionDescription());
1856                 }
1857             } else {
1858                 PackageManagerService.reportSettingsProblem(Log.WARN,
1859                         "Unknown element under <perms>: " + parser.getName());
1860             }
1861             XmlUtils.skipCurrentTag(parser);
1862         }
1863     }
1864 
readPreferredActivitiesLPw(XmlPullParser parser)1865     private void readPreferredActivitiesLPw(XmlPullParser parser) throws XmlPullParserException,
1866             IOException {
1867         int outerDepth = parser.getDepth();
1868         int type;
1869         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1870                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1871             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1872                 continue;
1873             }
1874 
1875             String tagName = parser.getName();
1876             if (tagName.equals("item")) {
1877                 PreferredActivity pa = new PreferredActivity(parser);
1878                 if (pa.mPref.getParseError() == null) {
1879                     mPreferredActivities.addFilter(pa);
1880                 } else {
1881                     PackageManagerService.reportSettingsProblem(Log.WARN,
1882                             "Error in package manager settings: <preferred-activity> "
1883                                     + pa.mPref.getParseError() + " at "
1884                                     + parser.getPositionDescription());
1885                 }
1886             } else {
1887                 PackageManagerService.reportSettingsProblem(Log.WARN,
1888                         "Unknown element under <preferred-activities>: " + parser.getName());
1889                 XmlUtils.skipCurrentTag(parser);
1890             }
1891         }
1892     }
1893 
1894     // Returns -1 if we could not find an available UserId to assign
newUserIdLPw(Object obj)1895     private int newUserIdLPw(Object obj) {
1896         // Let's be stupidly inefficient for now...
1897         final int N = mUserIds.size();
1898         for (int i = 0; i < N; i++) {
1899             if (mUserIds.get(i) == null) {
1900                 mUserIds.set(i, obj);
1901                 return PackageManagerService.FIRST_APPLICATION_UID + i;
1902             }
1903         }
1904 
1905         // None left?
1906         if (N >= PackageManagerService.MAX_APPLICATION_UIDS) {
1907             return -1;
1908         }
1909 
1910         mUserIds.add(obj);
1911         return PackageManagerService.FIRST_APPLICATION_UID + N;
1912     }
1913 
getVerifierDeviceIdentityLPw()1914     public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
1915         if (mVerifierDeviceIdentity == null) {
1916             mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
1917 
1918             writeLPr();
1919         }
1920 
1921         return mVerifierDeviceIdentity;
1922     }
1923 
getDisabledSystemPkgLPr(String name)1924     public PackageSetting getDisabledSystemPkgLPr(String name) {
1925         PackageSetting ps = mDisabledSysPackages.get(name);
1926         return ps;
1927     }
1928 
isEnabledLPr(ComponentInfo componentInfo, int flags)1929     boolean isEnabledLPr(ComponentInfo componentInfo, int flags) {
1930         if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
1931             return true;
1932         }
1933         final PackageSetting packageSettings = mPackages.get(componentInfo.packageName);
1934         if (PackageManagerService.DEBUG_SETTINGS) {
1935             Log.v(PackageManagerService.TAG, "isEnabledLock - packageName = " + componentInfo.packageName
1936                        + " componentName = " + componentInfo.name);
1937             Log.v(PackageManagerService.TAG, "enabledComponents: "
1938                        + Arrays.toString(packageSettings.enabledComponents.toArray()));
1939             Log.v(PackageManagerService.TAG, "disabledComponents: "
1940                        + Arrays.toString(packageSettings.disabledComponents.toArray()));
1941         }
1942         if (packageSettings == null) {
1943             return false;
1944         }
1945         if (packageSettings.enabled == COMPONENT_ENABLED_STATE_DISABLED
1946                 || packageSettings.enabled == COMPONENT_ENABLED_STATE_DISABLED_USER
1947                 || (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled
1948                         && packageSettings.enabled == COMPONENT_ENABLED_STATE_DEFAULT)) {
1949             return false;
1950         }
1951         if (packageSettings.enabledComponents.contains(componentInfo.name)) {
1952             return true;
1953         }
1954         if (packageSettings.disabledComponents.contains(componentInfo.name)) {
1955             return false;
1956         }
1957         return componentInfo.enabled;
1958     }
1959 
getInstallerPackageNameLPr(String packageName)1960     String getInstallerPackageNameLPr(String packageName) {
1961         final PackageSetting pkg = mPackages.get(packageName);
1962         if (pkg == null) {
1963             throw new IllegalArgumentException("Unknown package: " + packageName);
1964         }
1965         return pkg.installerPackageName;
1966     }
1967 
getApplicationEnabledSettingLPr(String packageName)1968     int getApplicationEnabledSettingLPr(String packageName) {
1969         final PackageSetting pkg = mPackages.get(packageName);
1970         if (pkg == null) {
1971             throw new IllegalArgumentException("Unknown package: " + packageName);
1972         }
1973         return pkg.enabled;
1974     }
1975 
getComponentEnabledSettingLPr(ComponentName componentName)1976     int getComponentEnabledSettingLPr(ComponentName componentName) {
1977         final String packageName = componentName.getPackageName();
1978         final PackageSetting pkg = mPackages.get(packageName);
1979         if (pkg == null) {
1980             throw new IllegalArgumentException("Unknown component: " + componentName);
1981         }
1982         final String classNameStr = componentName.getClassName();
1983         return pkg.getCurrentEnabledStateLPr(classNameStr);
1984     }
1985 
setPackageStoppedStateLPw(String packageName, boolean stopped, boolean allowedByPermission, int uid)1986     boolean setPackageStoppedStateLPw(String packageName, boolean stopped,
1987             boolean allowedByPermission, int uid) {
1988         final PackageSetting pkgSetting = mPackages.get(packageName);
1989         if (pkgSetting == null) {
1990             throw new IllegalArgumentException("Unknown package: " + packageName);
1991         }
1992         if (!allowedByPermission && (uid != pkgSetting.userId)) {
1993             throw new SecurityException(
1994                     "Permission Denial: attempt to change stopped state from pid="
1995                     + Binder.getCallingPid()
1996                     + ", uid=" + uid + ", package uid=" + pkgSetting.userId);
1997         }
1998         if (DEBUG_STOPPED) {
1999             if (stopped) {
2000                 RuntimeException e = new RuntimeException("here");
2001                 e.fillInStackTrace();
2002                 Slog.i(TAG, "Stopping package " + packageName, e);
2003             }
2004         }
2005         if (pkgSetting.stopped != stopped) {
2006             pkgSetting.stopped = stopped;
2007             pkgSetting.pkg.mSetStopped = stopped;
2008             if (pkgSetting.notLaunched) {
2009                 if (pkgSetting.installerPackageName != null) {
2010                     PackageManagerService.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
2011                             pkgSetting.name, null,
2012                             pkgSetting.installerPackageName, null);
2013                 }
2014                 pkgSetting.notLaunched = false;
2015             }
2016             return true;
2017         }
2018         return false;
2019     }
2020 
dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState)2021     void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState) {
2022         final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
2023         final Date date = new Date();
2024         boolean printedSomething = false;
2025         for (final PackageSetting ps : mPackages.values()) {
2026             if (packageName != null && !packageName.equals(ps.realName)
2027                     && !packageName.equals(ps.name)) {
2028                 continue;
2029             }
2030 
2031             if (packageName != null) {
2032                 dumpState.setSharedUser(ps.sharedUser);
2033             }
2034 
2035             if (!printedSomething) {
2036                 if (dumpState.onTitlePrinted())
2037                     pw.println(" ");
2038                 pw.println("Packages:");
2039                 printedSomething = true;
2040             }
2041             pw.print("  Package [");
2042                 pw.print(ps.realName != null ? ps.realName : ps.name);
2043                 pw.print("] (");
2044                 pw.print(Integer.toHexString(System.identityHashCode(ps)));
2045                 pw.println("):");
2046 
2047             if (ps.realName != null) {
2048                 pw.print("    compat name=");
2049                 pw.println(ps.name);
2050             }
2051 
2052             pw.print("    userId="); pw.print(ps.userId);
2053             pw.print(" gids="); pw.println(PackageManagerService.arrayToString(ps.gids));
2054             pw.print("    sharedUser="); pw.println(ps.sharedUser);
2055             pw.print("    pkg="); pw.println(ps.pkg);
2056             pw.print("    codePath="); pw.println(ps.codePathString);
2057             pw.print("    resourcePath="); pw.println(ps.resourcePathString);
2058             pw.print("    nativeLibraryPath="); pw.println(ps.nativeLibraryPathString);
2059             pw.print("    versionCode="); pw.println(ps.versionCode);
2060             if (ps.pkg != null) {
2061                 pw.print("    versionName="); pw.println(ps.pkg.mVersionName);
2062                 pw.print("    dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
2063                 pw.print("    targetSdk="); pw.println(ps.pkg.applicationInfo.targetSdkVersion);
2064                 if (ps.pkg.mOperationPending) {
2065                     pw.println("    mOperationPending=true");
2066                 }
2067                 pw.print("    supportsScreens=[");
2068                 boolean first = true;
2069                 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
2070                     if (!first)
2071                         pw.print(", ");
2072                     first = false;
2073                     pw.print("small");
2074                 }
2075                 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
2076                     if (!first)
2077                         pw.print(", ");
2078                     first = false;
2079                     pw.print("medium");
2080                 }
2081                 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
2082                     if (!first)
2083                         pw.print(", ");
2084                     first = false;
2085                     pw.print("large");
2086                 }
2087                 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
2088                     if (!first)
2089                         pw.print(", ");
2090                     first = false;
2091                     pw.print("xlarge");
2092                 }
2093                 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
2094                     if (!first)
2095                         pw.print(", ");
2096                     first = false;
2097                     pw.print("resizeable");
2098                 }
2099                 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
2100                     if (!first)
2101                         pw.print(", ");
2102                     first = false;
2103                     pw.print("anyDensity");
2104                 }
2105             }
2106             pw.println("]");
2107             pw.print("    timeStamp=");
2108                 date.setTime(ps.timeStamp);
2109                 pw.println(sdf.format(date));
2110             pw.print("    firstInstallTime=");
2111                 date.setTime(ps.firstInstallTime);
2112                 pw.println(sdf.format(date));
2113             pw.print("    lastUpdateTime=");
2114                 date.setTime(ps.lastUpdateTime);
2115                 pw.println(sdf.format(date));
2116             if (ps.installerPackageName != null) {
2117                 pw.print("    installerPackageName="); pw.println(ps.installerPackageName);
2118             }
2119             pw.print("    signatures="); pw.println(ps.signatures);
2120             pw.print("    permissionsFixed="); pw.print(ps.permissionsFixed);
2121             pw.print(" haveGids="); pw.println(ps.haveGids);
2122             pw.print("    pkgFlags=0x"); pw.print(Integer.toHexString(ps.pkgFlags));
2123             pw.print(" installStatus="); pw.print(ps.installStatus);
2124             pw.print(" stopped="); pw.print(ps.stopped);
2125             pw.print(" enabled="); pw.println(ps.enabled);
2126             if (ps.disabledComponents.size() > 0) {
2127                 pw.println("    disabledComponents:");
2128                 for (String s : ps.disabledComponents) {
2129                     pw.print("      "); pw.println(s);
2130                 }
2131             }
2132             if (ps.enabledComponents.size() > 0) {
2133                 pw.println("    enabledComponents:");
2134                 for (String s : ps.enabledComponents) {
2135                     pw.print("      "); pw.println(s);
2136                 }
2137             }
2138             if (ps.grantedPermissions.size() > 0) {
2139                 pw.println("    grantedPermissions:");
2140                 for (String s : ps.grantedPermissions) {
2141                     pw.print("      "); pw.println(s);
2142                 }
2143             }
2144         }
2145 
2146         printedSomething = false;
2147         if (mRenamedPackages.size() > 0) {
2148             for (final HashMap.Entry<String, String> e : mRenamedPackages.entrySet()) {
2149                 if (packageName != null && !packageName.equals(e.getKey())
2150                         && !packageName.equals(e.getValue())) {
2151                     continue;
2152                 }
2153                 if (!printedSomething) {
2154                     if (dumpState.onTitlePrinted())
2155                         pw.println(" ");
2156                     pw.println("Renamed packages:");
2157                     printedSomething = true;
2158                 }
2159                 pw.print("  ");
2160                 pw.print(e.getKey());
2161                 pw.print(" -> ");
2162                 pw.println(e.getValue());
2163             }
2164         }
2165 
2166         printedSomething = false;
2167         if (mDisabledSysPackages.size() > 0) {
2168             for (final PackageSetting ps : mDisabledSysPackages.values()) {
2169                 if (packageName != null && !packageName.equals(ps.realName)
2170                         && !packageName.equals(ps.name)) {
2171                     continue;
2172                 }
2173                 if (!printedSomething) {
2174                     if (dumpState.onTitlePrinted())
2175                         pw.println(" ");
2176                     pw.println("Hidden system packages:");
2177                     printedSomething = true;
2178                 }
2179                 pw.print("  Package [");
2180                 pw.print(ps.realName != null ? ps.realName : ps.name);
2181                 pw.print("] (");
2182                 pw.print(Integer.toHexString(System.identityHashCode(ps)));
2183                 pw.println("):");
2184                 if (ps.realName != null) {
2185                     pw.print("    compat name=");
2186                     pw.println(ps.name);
2187                 }
2188                 pw.print("    userId=");
2189                 pw.println(ps.userId);
2190                 pw.print("    sharedUser=");
2191                 pw.println(ps.sharedUser);
2192                 pw.print("    codePath=");
2193                 pw.println(ps.codePathString);
2194                 pw.print("    resourcePath=");
2195                 pw.println(ps.resourcePathString);
2196             }
2197         }
2198     }
2199 
dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState)2200     void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) {
2201         boolean printedSomething = false;
2202         for (BasePermission p : mPermissions.values()) {
2203             if (packageName != null && !packageName.equals(p.sourcePackage)) {
2204                 continue;
2205             }
2206             if (!printedSomething) {
2207                 if (dumpState.onTitlePrinted())
2208                     pw.println(" ");
2209                 pw.println("Permissions:");
2210                 printedSomething = true;
2211             }
2212             pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
2213                     pw.print(Integer.toHexString(System.identityHashCode(p)));
2214                     pw.println("):");
2215             pw.print("    sourcePackage="); pw.println(p.sourcePackage);
2216             pw.print("    uid="); pw.print(p.uid);
2217                     pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids));
2218                     pw.print(" type="); pw.print(p.type);
2219                     pw.print(" prot="); pw.println(p.protectionLevel);
2220             if (p.packageSetting != null) {
2221                 pw.print("    packageSetting="); pw.println(p.packageSetting);
2222             }
2223             if (p.perm != null) {
2224                 pw.print("    perm="); pw.println(p.perm);
2225             }
2226         }
2227     }
2228 
dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState)2229     void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState) {
2230         boolean printedSomething = false;
2231         for (SharedUserSetting su : mSharedUsers.values()) {
2232             if (packageName != null && su != dumpState.getSharedUser()) {
2233                 continue;
2234             }
2235             if (!printedSomething) {
2236                 if (dumpState.onTitlePrinted())
2237                     pw.println(" ");
2238                 pw.println("Shared users:");
2239                 printedSomething = true;
2240             }
2241             pw.print("  SharedUser [");
2242             pw.print(su.name);
2243             pw.print("] (");
2244             pw.print(Integer.toHexString(System.identityHashCode(su)));
2245                     pw.println("):");
2246             pw.print("    userId=");
2247             pw.print(su.userId);
2248             pw.print(" gids=");
2249             pw.println(PackageManagerService.arrayToString(su.gids));
2250             pw.println("    grantedPermissions:");
2251             for (String s : su.grantedPermissions) {
2252                 pw.print("      ");
2253                 pw.println(s);
2254             }
2255         }
2256     }
2257 
dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState)2258     void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
2259         pw.println("Settings parse messages:");
2260         pw.print(mReadMessages.toString());
2261     }
2262 }