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