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