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, true /* allowInstall */);
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, boolean allowInstall) {
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 && allowInstall) {
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 && allowInstall) {
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        final int N = mPendingPackages.size();
1705        for (int i = 0; i < N; i++) {
1706            final PendingPackage pp = mPendingPackages.get(i);
1707            Object idObj = getUserIdLPr(pp.sharedId);
1708            if (idObj != null && idObj instanceof SharedUserSetting) {
1709                PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
1710                        (SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
1711                        pp.nativeLibraryPathString, pp.versionCode, pp.pkgFlags,
1712                        null, true /* add */, false /* allowInstall */);
1713                if (p == null) {
1714                    PackageManagerService.reportSettingsProblem(Log.WARN,
1715                            "Unable to create application package for " + pp.name);
1716                    continue;
1717                }
1718                p.copyFrom(pp);
1719            } else if (idObj != null) {
1720                String msg = "Bad package setting: package " + pp.name + " has shared uid "
1721                        + pp.sharedId + " that is not a shared uid\n";
1722                mReadMessages.append(msg);
1723                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
1724            } else {
1725                String msg = "Bad package setting: package " + pp.name + " has shared uid "
1726                        + pp.sharedId + " that is not defined\n";
1727                mReadMessages.append(msg);
1728                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
1729            }
1730        }
1731        mPendingPackages.clear();
1732
1733        if (mBackupStoppedPackagesFilename.exists()
1734                || mStoppedPackagesFilename.exists()) {
1735            // Read old file
1736            readStoppedLPw();
1737            mBackupStoppedPackagesFilename.delete();
1738            mStoppedPackagesFilename.delete();
1739            // Migrate to new file format
1740            writePackageRestrictionsLPr(0);
1741        } else {
1742            if (users == null) {
1743                readPackageRestrictionsLPr(0);
1744            } else {
1745                for (UserInfo user : users) {
1746                    readPackageRestrictionsLPr(user.id);
1747                }
1748            }
1749        }
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