Settings.java revision 4ed745d359ada6986ac15d8718452e5c55f40170
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_UNTIL_USED;
22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
24import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
25import static android.os.Process.SYSTEM_UID;
26import static android.os.Process.PACKAGE_INFO_GID;
27
28import android.content.IntentFilter;
29import android.content.pm.ActivityInfo;
30import android.content.pm.ResolveInfo;
31import android.net.Uri;
32import android.os.Binder;
33import android.os.Build;
34import android.os.Environment;
35import android.os.FileUtils;
36import android.os.PatternMatcher;
37import android.os.Process;
38import android.os.UserHandle;
39import android.os.UserManager;
40import android.util.LogPrinter;
41
42import com.android.internal.util.FastXmlSerializer;
43import com.android.internal.util.JournaledFile;
44import com.android.internal.util.XmlUtils;
45import com.android.server.pm.PackageManagerService.DumpState;
46
47import java.util.Collection;
48
49import org.xmlpull.v1.XmlPullParser;
50import org.xmlpull.v1.XmlPullParserException;
51import org.xmlpull.v1.XmlSerializer;
52
53import android.content.ComponentName;
54import android.content.Context;
55import android.content.Intent;
56import android.content.pm.ApplicationInfo;
57import android.content.pm.ComponentInfo;
58import android.content.pm.PackageCleanItem;
59import android.content.pm.PackageManager;
60import android.content.pm.PackageParser;
61import android.content.pm.PermissionInfo;
62import android.content.pm.Signature;
63import android.content.pm.UserInfo;
64import android.content.pm.PackageUserState;
65import android.content.pm.VerifierDeviceIdentity;
66import android.util.Log;
67import android.util.Slog;
68import android.util.SparseArray;
69import android.util.Xml;
70
71import java.io.BufferedOutputStream;
72import java.io.File;
73import java.io.FileInputStream;
74import java.io.FileOutputStream;
75import java.io.IOException;
76import java.io.PrintWriter;
77import java.text.SimpleDateFormat;
78import java.util.ArrayList;
79import java.util.Arrays;
80import java.util.Date;
81import java.util.HashMap;
82import java.util.HashSet;
83import java.util.Iterator;
84import java.util.List;
85import java.util.Map;
86import java.util.Objects;
87import java.util.Set;
88import java.util.Map.Entry;
89
90import libcore.io.IoUtils;
91
92/**
93 * Holds information about dynamic settings.
94 */
95final class Settings {
96    private static final String TAG = "PackageSettings";
97
98    /**
99     * Current version of the package database. Set it to the latest version in
100     * the {@link DatabaseVersion} class below to ensure the database upgrade
101     * doesn't happen repeatedly.
102     * <p>
103     * Note that care should be taken to make sure all database upgrades are
104     * idempotent.
105     */
106    private static final int CURRENT_DATABASE_VERSION = DatabaseVersion.SIGNATURE_END_ENTITY;
107
108    /**
109     * This class contains constants that can be referred to from upgrade code.
110     * Insert constant values here that describe the upgrade reason. The version
111     * code must be monotonically increasing.
112     */
113    public static class DatabaseVersion {
114        /**
115         * The initial version of the database.
116         */
117        public static final int FIRST_VERSION = 1;
118
119        /**
120         * Migrating the Signature array from the entire certificate chain to
121         * just the signing certificate.
122         */
123        public static final int SIGNATURE_END_ENTITY = 2;
124    }
125
126    private static final boolean DEBUG_STOPPED = false;
127    private static final boolean DEBUG_MU = false;
128
129    private static final String TAG_READ_EXTERNAL_STORAGE = "read-external-storage";
130    private static final String ATTR_ENFORCEMENT = "enforcement";
131
132    private static final String TAG_ITEM = "item";
133    private static final String TAG_DISABLED_COMPONENTS = "disabled-components";
134    private static final String TAG_ENABLED_COMPONENTS = "enabled-components";
135    private static final String TAG_PACKAGE_RESTRICTIONS = "package-restrictions";
136    private static final String TAG_PACKAGE = "pkg";
137    private static final String TAG_PERSISTENT_PREFERRED_ACTIVITIES =
138            "persistent-preferred-activities";
139    static final String TAG_CROSS_PROFILE_INTENT_FILTERS =
140            "crossProfile-intent-filters";
141    private static final String TAG_CROSS_PROFILE_PACKAGE_INFO = "cross-profile-package-info";
142    private static final String CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID = "target-user-id";
143    private static final String CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME = "package-name";
144    private static final String CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME = "value";
145    //Old name. Kept for compatibility
146    static final String TAG_FORWARDING_INTENT_FILTERS =
147            "forwarding-intent-filters";
148
149    private static final String ATTR_NAME = "name";
150    private static final String ATTR_USER = "user";
151    private static final String ATTR_CODE = "code";
152    private static final String ATTR_NOT_LAUNCHED = "nl";
153    private static final String ATTR_ENABLED = "enabled";
154    private static final String ATTR_ENABLED_CALLER = "enabledCaller";
155    private static final String ATTR_STOPPED = "stopped";
156    private static final String ATTR_BLOCKED = "blocked";
157    private static final String ATTR_INSTALLED = "inst";
158    private static final String ATTR_BLOCK_UNINSTALL = "blockUninstall";
159
160    private final File mSettingsFilename;
161    private final File mBackupSettingsFilename;
162    private final File mPackageListFilename;
163    private final File mStoppedPackagesFilename;
164    private final File mBackupStoppedPackagesFilename;
165
166    final HashMap<String, PackageSetting> mPackages =
167            new HashMap<String, PackageSetting>();
168    // List of replaced system applications
169    private final HashMap<String, PackageSetting> mDisabledSysPackages =
170        new HashMap<String, PackageSetting>();
171
172    private static int mFirstAvailableUid = 0;
173
174    // These are the last platform API version we were using for
175    // the apps installed on internal and external storage.  It is
176    // used to grant newer permissions one time during a system upgrade.
177    int mInternalSdkPlatform;
178    int mExternalSdkPlatform;
179
180    /**
181     * The current database version for apps on internal storage. This is
182     * used to upgrade the format of the packages.xml database not necessarily
183     * tied to an SDK version.
184     */
185    int mInternalDatabaseVersion;
186    int mExternalDatabaseVersion;
187
188    /**
189     * Last known value of {@link Build#FINGERPRINT}. Used to determine when an
190     * system update has occurred, meaning we need to clear code caches.
191     */
192    String mFingerprint;
193
194    Boolean mReadExternalStorageEnforced;
195
196    /** Device identity for the purpose of package verification. */
197    private VerifierDeviceIdentity mVerifierDeviceIdentity;
198
199    // The user's preferred activities associated with particular intent
200    // filters.
201    final SparseArray<PreferredIntentResolver> mPreferredActivities =
202            new SparseArray<PreferredIntentResolver>();
203
204    // The persistent preferred activities of the user's profile/device owner
205    // associated with particular intent filters.
206    final SparseArray<PersistentPreferredIntentResolver> mPersistentPreferredActivities =
207            new SparseArray<PersistentPreferredIntentResolver>();
208
209    // For every user, it is used to find to which other users the intent can be forwarded.
210    final SparseArray<CrossProfileIntentResolver> mCrossProfileIntentResolvers =
211            new SparseArray<CrossProfileIntentResolver>();
212
213    final HashMap<String, SharedUserSetting> mSharedUsers =
214            new HashMap<String, SharedUserSetting>();
215    private final ArrayList<Object> mUserIds = new ArrayList<Object>();
216    private final SparseArray<Object> mOtherUserIds =
217            new SparseArray<Object>();
218
219    // For reading/writing settings file.
220    private final ArrayList<Signature> mPastSignatures =
221            new ArrayList<Signature>();
222
223    // Mapping from permission names to info about them.
224    final HashMap<String, BasePermission> mPermissions =
225            new HashMap<String, BasePermission>();
226
227    // Mapping from permission tree names to info about them.
228    final HashMap<String, BasePermission> mPermissionTrees =
229            new HashMap<String, BasePermission>();
230
231    // Packages that have been uninstalled and still need their external
232    // storage data deleted.
233    final ArrayList<PackageCleanItem> mPackagesToBeCleaned = new ArrayList<PackageCleanItem>();
234
235    // Packages that have been renamed since they were first installed.
236    // Keys are the new names of the packages, values are the original
237    // names.  The packages appear everwhere else under their original
238    // names.
239    final HashMap<String, String> mRenamedPackages = new HashMap<String, String>();
240
241    final StringBuilder mReadMessages = new StringBuilder();
242
243    /**
244     * Used to track packages that have a shared user ID that hasn't been read
245     * in yet.
246     * <p>
247     * TODO: make this just a local variable that is passed in during package
248     * scanning to make it less confusing.
249     */
250    private final ArrayList<PendingPackage> mPendingPackages = new ArrayList<PendingPackage>();
251
252    private final Context mContext;
253
254    private final File mSystemDir;
255
256    public final KeySetManagerService mKeySetManagerService = new KeySetManagerService(mPackages);
257
258    // A mapping of (sourceUserId, targetUserId, packageNames) for forwarding the intents of a
259    // package.
260    final SparseArray<SparseArray<ArrayList<String>>>
261            mCrossProfilePackageInfo = new SparseArray<SparseArray<ArrayList<String>>>();
262
263    Settings(Context context) {
264        this(context, Environment.getDataDirectory());
265    }
266
267    Settings(Context context, File dataDir) {
268        mContext = context;
269        mSystemDir = new File(dataDir, "system");
270        mSystemDir.mkdirs();
271        FileUtils.setPermissions(mSystemDir.toString(),
272                FileUtils.S_IRWXU|FileUtils.S_IRWXG
273                |FileUtils.S_IROTH|FileUtils.S_IXOTH,
274                -1, -1);
275        mSettingsFilename = new File(mSystemDir, "packages.xml");
276        mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
277        mPackageListFilename = new File(mSystemDir, "packages.list");
278        FileUtils.setPermissions(mPackageListFilename, 0660, SYSTEM_UID, PACKAGE_INFO_GID);
279
280        // Deprecated: Needed for migration
281        mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
282        mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
283    }
284
285    public void addCrossProfilePackage(
286            String packageName, int sourceUserId, int targetUserId) {
287        synchronized(mCrossProfilePackageInfo) {
288            SparseArray<ArrayList<String>> sourceForwardingInfo =
289                    mCrossProfilePackageInfo.get(sourceUserId);
290            if (sourceForwardingInfo == null) {
291                sourceForwardingInfo = new SparseArray<ArrayList<String>>();
292                mCrossProfilePackageInfo.put(sourceUserId, sourceForwardingInfo);
293            }
294            ArrayList<String> packageNames = sourceForwardingInfo.get(targetUserId);
295            if (packageNames == null) {
296                packageNames = new ArrayList<String>();
297                sourceForwardingInfo.put(targetUserId, packageNames);
298            }
299            if (!packageNames.contains(packageName)) {
300                packageNames.add(packageName);
301            }
302        }
303    }
304
305    public void removeCrossProfilePackage(
306            String packageName, int sourceUserId, int targetUserId) {
307        synchronized(mCrossProfilePackageInfo) {
308            SparseArray<ArrayList<String>> sourceForwardingInfo =
309                    mCrossProfilePackageInfo.get(sourceUserId);
310            if (sourceForwardingInfo == null) {
311                return;
312            }
313            ArrayList<String> packageNames = sourceForwardingInfo.get(targetUserId);
314            if (packageNames != null && packageNames.contains(packageName)) {
315                packageNames.remove(packageName);
316                if (packageNames.isEmpty()) {
317                    sourceForwardingInfo.remove(targetUserId);
318                    if (sourceForwardingInfo.size() == 0) {
319                        mCrossProfilePackageInfo.remove(sourceUserId);
320                    }
321                }
322            }
323        }
324    }
325
326    PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage,
327            String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
328            String legacyNativeLibraryPathString, String primaryCpuAbi, String secondaryCpuAbi, int pkgFlags,
329            UserHandle user, boolean add) {
330        final String name = pkg.packageName;
331        PackageSetting p = getPackageLPw(name, origPackage, realName, sharedUser, codePath,
332                resourcePath, legacyNativeLibraryPathString, primaryCpuAbi, secondaryCpuAbi,
333                pkg.mVersionCode, pkgFlags, user, add, true /* allowInstall */);
334        return p;
335    }
336
337    PackageSetting peekPackageLPr(String name) {
338        return mPackages.get(name);
339    }
340
341    void setInstallStatus(String pkgName, int status) {
342        PackageSetting p = mPackages.get(pkgName);
343        if(p != null) {
344            if(p.getInstallStatus() != status) {
345                p.setInstallStatus(status);
346            }
347        }
348    }
349
350    void setInstallerPackageName(String pkgName,
351            String installerPkgName) {
352        PackageSetting p = mPackages.get(pkgName);
353        if(p != null) {
354            p.setInstallerPackageName(installerPkgName);
355        }
356    }
357
358    SharedUserSetting getSharedUserLPw(String name,
359            int pkgFlags, boolean create) {
360        SharedUserSetting s = mSharedUsers.get(name);
361        if (s == null) {
362            if (!create) {
363                return null;
364            }
365            s = new SharedUserSetting(name, pkgFlags);
366            s.userId = newUserIdLPw(s);
367            Log.i(PackageManagerService.TAG, "New shared user " + name + ": id=" + s.userId);
368            // < 0 means we couldn't assign a userid; fall out and return
369            // s, which is currently null
370            if (s.userId >= 0) {
371                mSharedUsers.put(name, s);
372            }
373        }
374
375        return s;
376    }
377
378    Collection<SharedUserSetting> getAllSharedUsersLPw() {
379        return mSharedUsers.values();
380    }
381
382
383    boolean disableSystemPackageLPw(String name) {
384        final PackageSetting p = mPackages.get(name);
385        if(p == null) {
386            Log.w(PackageManagerService.TAG, "Package:"+name+" is not an installed package");
387            return false;
388        }
389        final PackageSetting dp = mDisabledSysPackages.get(name);
390        // always make sure the system package code and resource paths dont change
391        if (dp == null) {
392            if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
393                p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
394            }
395            mDisabledSysPackages.put(name, p);
396
397            // a little trick...  when we install the new package, we don't
398            // want to modify the existing PackageSetting for the built-in
399            // version.  so at this point we need a new PackageSetting that
400            // is okay to muck with.
401            PackageSetting newp = new PackageSetting(p);
402            replacePackageLPw(name, newp);
403            return true;
404        }
405        return false;
406    }
407
408    PackageSetting enableSystemPackageLPw(String name) {
409        PackageSetting p = mDisabledSysPackages.get(name);
410        if(p == null) {
411            Log.w(PackageManagerService.TAG, "Package:"+name+" is not disabled");
412            return null;
413        }
414        // Reset flag in ApplicationInfo object
415        if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
416            p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
417        }
418        PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
419                p.legacyNativeLibraryPathString, p.primaryCpuAbiString,
420                p.secondaryCpuAbiString, p.appId, p.versionCode, p.pkgFlags);
421        mDisabledSysPackages.remove(name);
422        return ret;
423    }
424
425    boolean isDisabledSystemPackageLPr(String name) {
426        return mDisabledSysPackages.containsKey(name);
427    }
428
429    void removeDisabledSystemPackageLPw(String name) {
430        mDisabledSysPackages.remove(name);
431    }
432
433    PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
434            String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString,
435            int uid, int vc, int pkgFlags) {
436        PackageSetting p = mPackages.get(name);
437        if (p != null) {
438            if (p.appId == uid) {
439                return p;
440            }
441            PackageManagerService.reportSettingsProblem(Log.ERROR,
442                    "Adding duplicate package, keeping first: " + name);
443            return null;
444        }
445        p = new PackageSetting(name, realName, codePath, resourcePath,
446                legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString, vc, pkgFlags);
447        p.appId = uid;
448        if (addUserIdLPw(uid, p, name)) {
449            mPackages.put(name, p);
450            return p;
451        }
452        return null;
453    }
454
455    SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags) {
456        SharedUserSetting s = mSharedUsers.get(name);
457        if (s != null) {
458            if (s.userId == uid) {
459                return s;
460            }
461            PackageManagerService.reportSettingsProblem(Log.ERROR,
462                    "Adding duplicate shared user, keeping first: " + name);
463            return null;
464        }
465        s = new SharedUserSetting(name, pkgFlags);
466        s.userId = uid;
467        if (addUserIdLPw(uid, s, name)) {
468            mSharedUsers.put(name, s);
469            return s;
470        }
471        return null;
472    }
473
474    void pruneSharedUsersLPw() {
475        ArrayList<String> removeStage = new ArrayList<String>();
476        for (Map.Entry<String,SharedUserSetting> entry : mSharedUsers.entrySet()) {
477            final SharedUserSetting sus = entry.getValue();
478            if (sus == null || sus.packages.size() == 0) {
479                removeStage.add(entry.getKey());
480            }
481        }
482        for (int i = 0; i < removeStage.size(); i++) {
483            mSharedUsers.remove(removeStage.get(i));
484        }
485    }
486
487    // Transfer ownership of permissions from one package to another.
488    void transferPermissionsLPw(String origPkg, String newPkg) {
489        // Transfer ownership of permissions to the new package.
490        for (int i=0; i<2; i++) {
491            HashMap<String, BasePermission> permissions =
492                    i == 0 ? mPermissionTrees : mPermissions;
493            for (BasePermission bp : permissions.values()) {
494                if (origPkg.equals(bp.sourcePackage)) {
495                    if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG,
496                            "Moving permission " + bp.name
497                            + " from pkg " + bp.sourcePackage
498                            + " to " + newPkg);
499                    bp.sourcePackage = newPkg;
500                    bp.packageSetting = null;
501                    bp.perm = null;
502                    if (bp.pendingInfo != null) {
503                        bp.pendingInfo.packageName = newPkg;
504                    }
505                    bp.uid = 0;
506                    bp.gids = null;
507                }
508            }
509        }
510    }
511
512    private PackageSetting getPackageLPw(String name, PackageSetting origPackage,
513            String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
514            String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString,
515            int vc, int pkgFlags, UserHandle installUser, boolean add, boolean allowInstall) {
516        PackageSetting p = mPackages.get(name);
517        if (p != null) {
518            p.primaryCpuAbiString = primaryCpuAbiString;
519            p.secondaryCpuAbiString = secondaryCpuAbiString;
520            if (!p.codePath.equals(codePath)) {
521                // Check to see if its a disabled system app
522                if ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
523                    // This is an updated system app with versions in both system
524                    // and data partition. Just let the most recent version
525                    // take precedence.
526                    Slog.w(PackageManagerService.TAG, "Trying to update system app code path from "
527                            + p.codePathString + " to " + codePath.toString());
528                } else {
529                    // Just a change in the code path is not an issue, but
530                    // let's log a message about it.
531                    Slog.i(PackageManagerService.TAG, "Package " + name + " codePath changed from "
532                            + p.codePath + " to " + codePath + "; Retaining data and using new");
533                    /*
534                     * Since we've changed paths, we need to prefer the new
535                     * native library path over the one stored in the
536                     * package settings since we might have moved from
537                     * internal to external storage or vice versa.
538                     */
539                    p.legacyNativeLibraryPathString = legacyNativeLibraryPathString;
540                }
541            }
542            if (p.sharedUser != sharedUser) {
543                PackageManagerService.reportSettingsProblem(Log.WARN,
544                        "Package " + name + " shared user changed from "
545                        + (p.sharedUser != null ? p.sharedUser.name : "<nothing>")
546                        + " to "
547                        + (sharedUser != null ? sharedUser.name : "<nothing>")
548                        + "; replacing with new");
549                p = null;
550            } else {
551                // If what we are scanning is a system (and possibly privileged) package,
552                // then make it so, regardless of whether it was previously installed only
553                // in the data partition.
554                final int sysPrivFlags = pkgFlags
555                        & (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PRIVILEGED);
556                p.pkgFlags |= sysPrivFlags;
557            }
558        }
559        if (p == null) {
560            if (origPackage != null) {
561                // We are consuming the data from an existing package.
562                p = new PackageSetting(origPackage.name, name, codePath, resourcePath,
563                        legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString, vc, pkgFlags);
564                if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
565                        + name + " is adopting original package " + origPackage.name);
566                // Note that we will retain the new package's signature so
567                // that we can keep its data.
568                PackageSignatures s = p.signatures;
569                p.copyFrom(origPackage);
570                p.signatures = s;
571                p.sharedUser = origPackage.sharedUser;
572                p.appId = origPackage.appId;
573                p.origPackage = origPackage;
574                mRenamedPackages.put(name, origPackage.name);
575                name = origPackage.name;
576                // Update new package state.
577                p.setTimeStamp(codePath.lastModified());
578            } else {
579                p = new PackageSetting(name, realName, codePath, resourcePath,
580                        legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString, vc, pkgFlags);
581                p.setTimeStamp(codePath.lastModified());
582                p.sharedUser = sharedUser;
583                // If this is not a system app, it starts out stopped.
584                if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
585                    if (DEBUG_STOPPED) {
586                        RuntimeException e = new RuntimeException("here");
587                        e.fillInStackTrace();
588                        Slog.i(PackageManagerService.TAG, "Stopping package " + name, e);
589                    }
590                    List<UserInfo> users = getAllUsers();
591                    if (users != null && allowInstall) {
592                        for (UserInfo user : users) {
593                            // By default we consider this app to be installed
594                            // for the user if no user has been specified (which
595                            // means to leave it at its original value, and the
596                            // original default value is true), or we are being
597                            // asked to install for all users, or this is the
598                            // user we are installing for.
599                            // In this context all users (USER_ALL) implies an adb install,
600                            // so we additionally check whether that is allowed for this user.
601                            final boolean installed = installUser == null
602                                    || (installUser.getIdentifier() == UserHandle.USER_ALL
603                                            && (!isUnknownSourcesDisallowed(user.id)))
604                                    || installUser.getIdentifier() == user.id;
605                            p.setUserState(user.id, COMPONENT_ENABLED_STATE_DEFAULT,
606                                    installed,
607                                    true, // stopped,
608                                    true, // notLaunched
609                                    false, // blocked
610                                    null, null, null,
611                                    false // blockUninstall
612                                    );
613                            writePackageRestrictionsLPr(user.id);
614                        }
615                    }
616                }
617                if (sharedUser != null) {
618                    p.appId = sharedUser.userId;
619                } else {
620                    // Clone the setting here for disabled system packages
621                    PackageSetting dis = mDisabledSysPackages.get(name);
622                    if (dis != null) {
623                        // For disabled packages a new setting is created
624                        // from the existing user id. This still has to be
625                        // added to list of user id's
626                        // Copy signatures from previous setting
627                        if (dis.signatures.mSignatures != null) {
628                            p.signatures.mSignatures = dis.signatures.mSignatures.clone();
629                        }
630                        p.appId = dis.appId;
631                        // Clone permissions
632                        p.grantedPermissions = new HashSet<String>(dis.grantedPermissions);
633                        // Clone component info
634                        List<UserInfo> users = getAllUsers();
635                        if (users != null) {
636                            for (UserInfo user : users) {
637                                int userId = user.id;
638                                p.setDisabledComponentsCopy(
639                                        dis.getDisabledComponents(userId), userId);
640                                p.setEnabledComponentsCopy(
641                                        dis.getEnabledComponents(userId), userId);
642                            }
643                        }
644                        // Add new setting to list of user ids
645                        addUserIdLPw(p.appId, p, name);
646                    } else {
647                        // Assign new user id
648                        p.appId = newUserIdLPw(p);
649                    }
650                }
651            }
652            if (p.appId < 0) {
653                PackageManagerService.reportSettingsProblem(Log.WARN,
654                        "Package " + name + " could not be assigned a valid uid");
655                return null;
656            }
657            if (add) {
658                // Finish adding new package by adding it and updating shared
659                // user preferences
660                addPackageSettingLPw(p, name, sharedUser);
661            }
662        } else {
663            if (installUser != null && allowInstall) {
664                // The caller has explicitly specified the user they want this
665                // package installed for, and the package already exists.
666                // Make sure it conforms to the new request.
667                List<UserInfo> users = getAllUsers();
668                if (users != null) {
669                    for (UserInfo user : users) {
670                        // Installing for USER_ALL implies an adb install, so we
671                        // additionally check whether that is allowed for this user.
672                        if ((installUser.getIdentifier() == UserHandle.USER_ALL
673                                        && (!isUnknownSourcesDisallowed(user.id)))
674                                || installUser.getIdentifier() == user.id) {
675                            boolean installed = p.getInstalled(user.id);
676                            if (!installed) {
677                                p.setInstalled(true, user.id);
678                                writePackageRestrictionsLPr(user.id);
679                            }
680                        }
681                    }
682                }
683            }
684        }
685        return p;
686    }
687
688    boolean isUnknownSourcesDisallowed(int userId) {
689        UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
690        return um.getUserRestrictions(new UserHandle(userId)).getBoolean(
691                UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, false);
692    }
693
694    void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) {
695        p.pkg = pkg;
696        // pkg.mSetEnabled = p.getEnabled(userId);
697        // pkg.mSetStopped = p.getStopped(userId);
698        final String codePath = pkg.applicationInfo.getCodePath();
699        final String resourcePath = pkg.applicationInfo.getResourcePath();
700        final String legacyNativeLibraryPath = pkg.applicationInfo.nativeLibraryRootDir;
701        // Update code path if needed
702        if (!Objects.equals(codePath, p.codePathString)) {
703            Slog.w(PackageManagerService.TAG, "Code path for pkg : " + p.pkg.packageName +
704                    " changing from " + p.codePathString + " to " + codePath);
705            p.codePath = new File(codePath);
706            p.codePathString = codePath;
707        }
708        //Update resource path if needed
709        if (!Objects.equals(resourcePath, p.resourcePathString)) {
710            Slog.w(PackageManagerService.TAG, "Resource path for pkg : " + p.pkg.packageName +
711                    " changing from " + p.resourcePathString + " to " + resourcePath);
712            p.resourcePath = new File(resourcePath);
713            p.resourcePathString = resourcePath;
714        }
715        // Update the native library paths if needed
716        if (!Objects.equals(legacyNativeLibraryPath, p.legacyNativeLibraryPathString)) {
717            p.legacyNativeLibraryPathString = legacyNativeLibraryPath;
718        }
719
720        // Update the required Cpu Abi
721        p.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
722        p.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
723        // Update version code if needed
724        if (pkg.mVersionCode != p.versionCode) {
725            p.versionCode = pkg.mVersionCode;
726        }
727        // Update signatures if needed.
728        if (p.signatures.mSignatures == null) {
729            p.signatures.assignSignatures(pkg.mSignatures);
730        }
731        // Update flags if needed.
732        if (pkg.applicationInfo.flags != p.pkgFlags) {
733            p.pkgFlags = pkg.applicationInfo.flags;
734        }
735        // If this app defines a shared user id initialize
736        // the shared user signatures as well.
737        if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) {
738            p.sharedUser.signatures.assignSignatures(pkg.mSignatures);
739        }
740        addPackageSettingLPw(p, pkg.packageName, p.sharedUser);
741    }
742
743    // Utility method that adds a PackageSetting to mPackages and
744    // completes updating the shared user attributes
745    private void addPackageSettingLPw(PackageSetting p, String name,
746            SharedUserSetting sharedUser) {
747        mPackages.put(name, p);
748        if (sharedUser != null) {
749            if (p.sharedUser != null && p.sharedUser != sharedUser) {
750                PackageManagerService.reportSettingsProblem(Log.ERROR,
751                        "Package " + p.name + " was user "
752                        + p.sharedUser + " but is now " + sharedUser
753                        + "; I am not changing its files so it will probably fail!");
754                p.sharedUser.removePackage(p);
755            } else if (p.appId != sharedUser.userId) {
756                PackageManagerService.reportSettingsProblem(Log.ERROR,
757                    "Package " + p.name + " was user id " + p.appId
758                    + " but is now user " + sharedUser
759                    + " with id " + sharedUser.userId
760                    + "; I am not changing its files so it will probably fail!");
761            }
762
763            sharedUser.addPackage(p);
764            p.sharedUser = sharedUser;
765            p.appId = sharedUser.userId;
766        }
767    }
768
769    /*
770     * Update the shared user setting when a package using
771     * specifying the shared user id is removed. The gids
772     * associated with each permission of the deleted package
773     * are removed from the shared user's gid list only if its
774     * not in use by other permissions of packages in the
775     * shared user setting.
776     */
777    void updateSharedUserPermsLPw(PackageSetting deletedPs, int[] globalGids) {
778        if ((deletedPs == null) || (deletedPs.pkg == null)) {
779            Slog.i(PackageManagerService.TAG,
780                    "Trying to update info for null package. Just ignoring");
781            return;
782        }
783        // No sharedUserId
784        if (deletedPs.sharedUser == null) {
785            return;
786        }
787        SharedUserSetting sus = deletedPs.sharedUser;
788        // Update permissions
789        for (String eachPerm : deletedPs.pkg.requestedPermissions) {
790            boolean used = false;
791            if (!sus.grantedPermissions.contains(eachPerm)) {
792                continue;
793            }
794            for (PackageSetting pkg:sus.packages) {
795                if (pkg.pkg != null &&
796                        !pkg.pkg.packageName.equals(deletedPs.pkg.packageName) &&
797                        pkg.pkg.requestedPermissions.contains(eachPerm)) {
798                    used = true;
799                    break;
800                }
801            }
802            if (!used) {
803                // can safely delete this permission from list
804                sus.grantedPermissions.remove(eachPerm);
805            }
806        }
807        // Update gids
808        int newGids[] = globalGids;
809        for (String eachPerm : sus.grantedPermissions) {
810            BasePermission bp = mPermissions.get(eachPerm);
811            if (bp != null) {
812                newGids = PackageManagerService.appendInts(newGids, bp.gids);
813            }
814        }
815        sus.gids = newGids;
816    }
817
818    int removePackageLPw(String name) {
819        final PackageSetting p = mPackages.get(name);
820        if (p != null) {
821            mPackages.remove(name);
822            if (p.sharedUser != null) {
823                p.sharedUser.removePackage(p);
824                if (p.sharedUser.packages.size() == 0) {
825                    mSharedUsers.remove(p.sharedUser.name);
826                    removeUserIdLPw(p.sharedUser.userId);
827                    return p.sharedUser.userId;
828                }
829            } else {
830                removeUserIdLPw(p.appId);
831                return p.appId;
832            }
833        }
834        return -1;
835    }
836
837    private void replacePackageLPw(String name, PackageSetting newp) {
838        final PackageSetting p = mPackages.get(name);
839        if (p != null) {
840            if (p.sharedUser != null) {
841                p.sharedUser.removePackage(p);
842                p.sharedUser.addPackage(newp);
843            } else {
844                replaceUserIdLPw(p.appId, newp);
845            }
846        }
847        mPackages.put(name, newp);
848    }
849
850    private boolean addUserIdLPw(int uid, Object obj, Object name) {
851        if (uid > Process.LAST_APPLICATION_UID) {
852            return false;
853        }
854
855        if (uid >= Process.FIRST_APPLICATION_UID) {
856            int N = mUserIds.size();
857            final int index = uid - Process.FIRST_APPLICATION_UID;
858            while (index >= N) {
859                mUserIds.add(null);
860                N++;
861            }
862            if (mUserIds.get(index) != null) {
863                PackageManagerService.reportSettingsProblem(Log.ERROR,
864                        "Adding duplicate user id: " + uid
865                        + " name=" + name);
866                return false;
867            }
868            mUserIds.set(index, obj);
869        } else {
870            if (mOtherUserIds.get(uid) != null) {
871                PackageManagerService.reportSettingsProblem(Log.ERROR,
872                        "Adding duplicate shared id: " + uid
873                        + " name=" + name);
874                return false;
875            }
876            mOtherUserIds.put(uid, obj);
877        }
878        return true;
879    }
880
881    public Object getUserIdLPr(int uid) {
882        if (uid >= Process.FIRST_APPLICATION_UID) {
883            final int N = mUserIds.size();
884            final int index = uid - Process.FIRST_APPLICATION_UID;
885            return index < N ? mUserIds.get(index) : null;
886        } else {
887            return mOtherUserIds.get(uid);
888        }
889    }
890
891    private void removeUserIdLPw(int uid) {
892        if (uid >= Process.FIRST_APPLICATION_UID) {
893            final int N = mUserIds.size();
894            final int index = uid - Process.FIRST_APPLICATION_UID;
895            if (index < N) mUserIds.set(index, null);
896        } else {
897            mOtherUserIds.remove(uid);
898        }
899        setFirstAvailableUid(uid+1);
900    }
901
902    private void replaceUserIdLPw(int uid, Object obj) {
903        if (uid >= Process.FIRST_APPLICATION_UID) {
904            final int N = mUserIds.size();
905            final int index = uid - Process.FIRST_APPLICATION_UID;
906            if (index < N) mUserIds.set(index, obj);
907        } else {
908            mOtherUserIds.put(uid, obj);
909        }
910    }
911
912    PreferredIntentResolver editPreferredActivitiesLPw(int userId) {
913        PreferredIntentResolver pir = mPreferredActivities.get(userId);
914        if (pir == null) {
915            pir = new PreferredIntentResolver();
916            mPreferredActivities.put(userId, pir);
917        }
918        return pir;
919    }
920
921    PersistentPreferredIntentResolver editPersistentPreferredActivitiesLPw(int userId) {
922        PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.get(userId);
923        if (ppir == null) {
924            ppir = new PersistentPreferredIntentResolver();
925            mPersistentPreferredActivities.put(userId, ppir);
926        }
927        return ppir;
928    }
929
930    CrossProfileIntentResolver editCrossProfileIntentResolverLPw(int userId) {
931        CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(userId);
932        if (cpir == null) {
933            cpir = new CrossProfileIntentResolver();
934            mCrossProfileIntentResolvers.put(userId, cpir);
935        }
936        return cpir;
937    }
938
939    private File getUserPackagesStateFile(int userId) {
940        return new File(Environment.getUserSystemDirectory(userId), "package-restrictions.xml");
941    }
942
943    private File getUserPackagesStateBackupFile(int userId) {
944        return new File(Environment.getUserSystemDirectory(userId),
945                "package-restrictions-backup.xml");
946    }
947
948    void writeAllUsersPackageRestrictionsLPr() {
949        List<UserInfo> users = getAllUsers();
950        if (users == null) return;
951
952        for (UserInfo user : users) {
953            writePackageRestrictionsLPr(user.id);
954        }
955    }
956
957    void readAllUsersPackageRestrictionsLPr() {
958        List<UserInfo> users = getAllUsers();
959        if (users == null) {
960            readPackageRestrictionsLPr(0);
961            return;
962        }
963
964        for (UserInfo user : users) {
965            readPackageRestrictionsLPr(user.id);
966        }
967    }
968
969    /**
970     * Returns whether the current database has is older than {@code version}
971     * for apps on internal storage.
972     */
973    public boolean isInternalDatabaseVersionOlderThan(int version) {
974        return mInternalDatabaseVersion < version;
975    }
976
977    /**
978     * Returns whether the current database has is older than {@code version}
979     * for apps on external storage.
980     */
981    public boolean isExternalDatabaseVersionOlderThan(int version) {
982        return mExternalDatabaseVersion < version;
983    }
984
985    /**
986     * Updates the database version for apps on internal storage. Called after
987     * call the updates to the database format are done for apps on internal
988     * storage after the initial start-up scan.
989     */
990    public void updateInternalDatabaseVersion() {
991        mInternalDatabaseVersion = CURRENT_DATABASE_VERSION;
992    }
993
994    /**
995     * Updates the database version for apps on internal storage. Called after
996     * call the updates to the database format are done for apps on internal
997     * storage after the initial start-up scan.
998     */
999    public void updateExternalDatabaseVersion() {
1000        mExternalDatabaseVersion = CURRENT_DATABASE_VERSION;
1001    }
1002
1003    private void readPreferredActivitiesLPw(XmlPullParser parser, int userId)
1004            throws XmlPullParserException, IOException {
1005        int outerDepth = parser.getDepth();
1006        int type;
1007        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1008                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1009            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1010                continue;
1011            }
1012
1013            String tagName = parser.getName();
1014            if (tagName.equals(TAG_ITEM)) {
1015                PreferredActivity pa = new PreferredActivity(parser);
1016                if (pa.mPref.getParseError() == null) {
1017                    editPreferredActivitiesLPw(userId).addFilter(pa);
1018                } else {
1019                    PackageManagerService.reportSettingsProblem(Log.WARN,
1020                            "Error in package manager settings: <preferred-activity> "
1021                                    + pa.mPref.getParseError() + " at "
1022                                    + parser.getPositionDescription());
1023                }
1024            } else {
1025                PackageManagerService.reportSettingsProblem(Log.WARN,
1026                        "Unknown element under <preferred-activities>: " + parser.getName());
1027                XmlUtils.skipCurrentTag(parser);
1028            }
1029        }
1030    }
1031
1032    private void readPersistentPreferredActivitiesLPw(XmlPullParser parser, int userId)
1033            throws XmlPullParserException, IOException {
1034        int outerDepth = parser.getDepth();
1035        int type;
1036        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1037                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1038            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1039                continue;
1040            }
1041            String tagName = parser.getName();
1042            if (tagName.equals(TAG_ITEM)) {
1043                PersistentPreferredActivity ppa = new PersistentPreferredActivity(parser);
1044                editPersistentPreferredActivitiesLPw(userId).addFilter(ppa);
1045            } else {
1046                PackageManagerService.reportSettingsProblem(Log.WARN,
1047                        "Unknown element under <" + TAG_PERSISTENT_PREFERRED_ACTIVITIES + ">: "
1048                        + parser.getName());
1049                XmlUtils.skipCurrentTag(parser);
1050            }
1051        }
1052    }
1053
1054    private void readCrossProfileIntentFiltersLPw(XmlPullParser parser, int userId)
1055            throws XmlPullParserException, IOException {
1056        int outerDepth = parser.getDepth();
1057        int type;
1058        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1059                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1060            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1061                continue;
1062            }
1063            String tagName = parser.getName();
1064            if (tagName.equals(TAG_ITEM)) {
1065                CrossProfileIntentFilter cpif = new CrossProfileIntentFilter(parser);
1066                editCrossProfileIntentResolverLPw(userId).addFilter(cpif);
1067            } else {
1068                String msg = "Unknown element under " +  TAG_CROSS_PROFILE_INTENT_FILTERS + ": " +
1069                        parser.getName();
1070                PackageManagerService.reportSettingsProblem(Log.WARN, msg);
1071                XmlUtils.skipCurrentTag(parser);
1072            }
1073        }
1074    }
1075
1076    private void readCrossProfilePackageInfoLPw(XmlPullParser parser, int userId)
1077            throws XmlPullParserException, IOException {
1078        int outerDepth = parser.getDepth();
1079        int type;
1080        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1081                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1082            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1083                continue;
1084            }
1085            String tagName = parser.getName();
1086            if (tagName.equals(TAG_ITEM)) {
1087                String targetUserIdString = parser.getAttributeValue(null,
1088                        CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID);
1089                if (targetUserIdString == null) {
1090                    String msg = "Missing element under " + TAG +": "
1091                            + CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID + " at " +
1092                            parser.getPositionDescription();
1093                    PackageManagerService.reportSettingsProblem(Log.WARN, msg);
1094                    continue;
1095                }
1096                int targetUserId = Integer.parseInt(targetUserIdString);
1097                readCrossProfilePackageInfoForTargetLPw(parser, userId, targetUserId);
1098            } else {
1099                String msg = "Unknown element under " +  TAG_CROSS_PROFILE_PACKAGE_INFO + ": " +
1100                        parser.getName();
1101                PackageManagerService.reportSettingsProblem(Log.WARN, msg);
1102                XmlUtils.skipCurrentTag(parser);
1103            }
1104        }
1105    }
1106
1107    private void readCrossProfilePackageInfoForTargetLPw(
1108            XmlPullParser parser, int sourceUserId, int targetUserId)
1109            throws XmlPullParserException, IOException {
1110        int outerDepth = parser.getDepth();
1111        int type;
1112        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1113                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1114            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1115                continue;
1116            }
1117            String tagName = parser.getName();
1118            if (tagName.equals(CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME)) {
1119                String packageName = parser.getAttributeValue(
1120                        null, CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME);
1121                if (packageName == null) {
1122                    String msg = "Missing element under " + TAG +": "
1123                            + CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME + " at " +
1124                            parser.getPositionDescription();
1125                    PackageManagerService.reportSettingsProblem(Log.WARN, msg);
1126                    continue;
1127                }
1128                addCrossProfilePackage(packageName, sourceUserId, targetUserId);
1129            } else {
1130                String msg = "Unknown element under " +  TAG_ITEM + ": " +
1131                        parser.getName();
1132                PackageManagerService.reportSettingsProblem(Log.WARN, msg);
1133                XmlUtils.skipCurrentTag(parser);
1134            }
1135        }
1136    }
1137
1138    void readPackageRestrictionsLPr(int userId) {
1139        if (DEBUG_MU) {
1140            Log.i(TAG, "Reading package restrictions for user=" + userId);
1141        }
1142        FileInputStream str = null;
1143        File userPackagesStateFile = getUserPackagesStateFile(userId);
1144        File backupFile = getUserPackagesStateBackupFile(userId);
1145        if (backupFile.exists()) {
1146            try {
1147                str = new FileInputStream(backupFile);
1148                mReadMessages.append("Reading from backup stopped packages file\n");
1149                PackageManagerService.reportSettingsProblem(Log.INFO,
1150                        "Need to read from backup stopped packages file");
1151                if (userPackagesStateFile.exists()) {
1152                    // If both the backup and normal file exist, we
1153                    // ignore the normal one since it might have been
1154                    // corrupted.
1155                    Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
1156                            + userPackagesStateFile);
1157                    userPackagesStateFile.delete();
1158                }
1159            } catch (java.io.IOException e) {
1160                // We'll try for the normal settings file.
1161            }
1162        }
1163
1164        try {
1165            if (str == null) {
1166                if (!userPackagesStateFile.exists()) {
1167                    mReadMessages.append("No stopped packages file found\n");
1168                    PackageManagerService.reportSettingsProblem(Log.INFO,
1169                            "No stopped packages file; "
1170                            + "assuming all started");
1171                    // At first boot, make sure no packages are stopped.
1172                    // We usually want to have third party apps initialize
1173                    // in the stopped state, but not at first boot.  Also
1174                    // consider all applications to be installed.
1175                    for (PackageSetting pkg : mPackages.values()) {
1176                        pkg.setUserState(userId, COMPONENT_ENABLED_STATE_DEFAULT,
1177                                true,   // installed
1178                                false,  // stopped
1179                                false,  // notLaunched
1180                                false,  // blocked
1181                                null, null, null,
1182                                false // blockUninstall
1183                                );
1184                    }
1185                    return;
1186                }
1187                str = new FileInputStream(userPackagesStateFile);
1188            }
1189            final XmlPullParser parser = Xml.newPullParser();
1190            parser.setInput(str, null);
1191
1192            int type;
1193            while ((type=parser.next()) != XmlPullParser.START_TAG
1194                       && type != XmlPullParser.END_DOCUMENT) {
1195                ;
1196            }
1197
1198            if (type != XmlPullParser.START_TAG) {
1199                mReadMessages.append("No start tag found in package restrictions file\n");
1200                PackageManagerService.reportSettingsProblem(Log.WARN,
1201                        "No start tag found in package manager stopped packages");
1202                return;
1203            }
1204
1205            int outerDepth = parser.getDepth();
1206            PackageSetting ps = null;
1207            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1208                   && (type != XmlPullParser.END_TAG
1209                           || parser.getDepth() > outerDepth)) {
1210                if (type == XmlPullParser.END_TAG
1211                        || type == XmlPullParser.TEXT) {
1212                    continue;
1213                }
1214
1215                String tagName = parser.getName();
1216                if (tagName.equals(TAG_PACKAGE)) {
1217                    String name = parser.getAttributeValue(null, ATTR_NAME);
1218                    ps = mPackages.get(name);
1219                    if (ps == null) {
1220                        Slog.w(PackageManagerService.TAG, "No package known for stopped package: "
1221                                + name);
1222                        XmlUtils.skipCurrentTag(parser);
1223                        continue;
1224                    }
1225                    final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
1226                    final int enabled = enabledStr == null
1227                            ? COMPONENT_ENABLED_STATE_DEFAULT : Integer.parseInt(enabledStr);
1228                    final String enabledCaller = parser.getAttributeValue(null,
1229                            ATTR_ENABLED_CALLER);
1230                    final String installedStr = parser.getAttributeValue(null, ATTR_INSTALLED);
1231                    final boolean installed = installedStr == null
1232                            ? true : Boolean.parseBoolean(installedStr);
1233                    final String stoppedStr = parser.getAttributeValue(null, ATTR_STOPPED);
1234                    final boolean stopped = stoppedStr == null
1235                            ? false : Boolean.parseBoolean(stoppedStr);
1236                    final String blockedStr = parser.getAttributeValue(null, ATTR_BLOCKED);
1237                    final boolean blocked = blockedStr == null
1238                            ? false : Boolean.parseBoolean(blockedStr);
1239                    final String notLaunchedStr = parser.getAttributeValue(null, ATTR_NOT_LAUNCHED);
1240                    final boolean notLaunched = stoppedStr == null
1241                            ? false : Boolean.parseBoolean(notLaunchedStr);
1242                    final String blockUninstallStr = parser.getAttributeValue(null,
1243                            ATTR_BLOCK_UNINSTALL);
1244                    final boolean blockUninstall = blockUninstallStr == null
1245                            ? false : Boolean.parseBoolean(blockUninstallStr);
1246
1247                    HashSet<String> enabledComponents = null;
1248                    HashSet<String> disabledComponents = null;
1249
1250                    int packageDepth = parser.getDepth();
1251                    while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1252                            && (type != XmlPullParser.END_TAG
1253                            || parser.getDepth() > packageDepth)) {
1254                        if (type == XmlPullParser.END_TAG
1255                                || type == XmlPullParser.TEXT) {
1256                            continue;
1257                        }
1258                        tagName = parser.getName();
1259                        if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
1260                            enabledComponents = readComponentsLPr(parser);
1261                        } else if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
1262                            disabledComponents = readComponentsLPr(parser);
1263                        }
1264                    }
1265
1266                    ps.setUserState(userId, enabled, installed, stopped, notLaunched, blocked,
1267                            enabledCaller, enabledComponents, disabledComponents, blockUninstall);
1268                } else if (tagName.equals("preferred-activities")) {
1269                    readPreferredActivitiesLPw(parser, userId);
1270                } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
1271                    readPersistentPreferredActivitiesLPw(parser, userId);
1272                } else if (tagName.equals(TAG_FORWARDING_INTENT_FILTERS)
1273                        || tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
1274                    readCrossProfileIntentFiltersLPw(parser, userId);
1275                } else if (tagName.equals(TAG_CROSS_PROFILE_PACKAGE_INFO)){
1276                    readCrossProfilePackageInfoLPw(parser, userId);
1277                } else {
1278                    Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
1279                          + parser.getName());
1280                    XmlUtils.skipCurrentTag(parser);
1281                }
1282            }
1283
1284            str.close();
1285
1286        } catch (XmlPullParserException e) {
1287            mReadMessages.append("Error reading: " + e.toString());
1288            PackageManagerService.reportSettingsProblem(Log.ERROR,
1289                    "Error reading stopped packages: " + e);
1290            Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
1291
1292        } catch (java.io.IOException e) {
1293            mReadMessages.append("Error reading: " + e.toString());
1294            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1295            Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
1296        }
1297    }
1298
1299    private HashSet<String> readComponentsLPr(XmlPullParser parser)
1300            throws IOException, XmlPullParserException {
1301        HashSet<String> components = null;
1302        int type;
1303        int outerDepth = parser.getDepth();
1304        String tagName;
1305        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1306                && (type != XmlPullParser.END_TAG
1307                || parser.getDepth() > outerDepth)) {
1308            if (type == XmlPullParser.END_TAG
1309                    || type == XmlPullParser.TEXT) {
1310                continue;
1311            }
1312            tagName = parser.getName();
1313            if (tagName.equals(TAG_ITEM)) {
1314                String componentName = parser.getAttributeValue(null, ATTR_NAME);
1315                if (componentName != null) {
1316                    if (components == null) {
1317                        components = new HashSet<String>();
1318                    }
1319                    components.add(componentName);
1320                }
1321            }
1322        }
1323        return components;
1324    }
1325
1326    void writePreferredActivitiesLPr(XmlSerializer serializer, int userId, boolean full)
1327            throws IllegalArgumentException, IllegalStateException, IOException {
1328        serializer.startTag(null, "preferred-activities");
1329        PreferredIntentResolver pir = mPreferredActivities.get(userId);
1330        if (pir != null) {
1331            for (final PreferredActivity pa : pir.filterSet()) {
1332                serializer.startTag(null, TAG_ITEM);
1333                pa.writeToXml(serializer, full);
1334                serializer.endTag(null, TAG_ITEM);
1335            }
1336        }
1337        serializer.endTag(null, "preferred-activities");
1338    }
1339
1340    void writePersistentPreferredActivitiesLPr(XmlSerializer serializer, int userId)
1341            throws IllegalArgumentException, IllegalStateException, IOException {
1342        serializer.startTag(null, TAG_PERSISTENT_PREFERRED_ACTIVITIES);
1343        PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.get(userId);
1344        if (ppir != null) {
1345            for (final PersistentPreferredActivity ppa : ppir.filterSet()) {
1346                serializer.startTag(null, TAG_ITEM);
1347                ppa.writeToXml(serializer);
1348                serializer.endTag(null, TAG_ITEM);
1349            }
1350        }
1351        serializer.endTag(null, TAG_PERSISTENT_PREFERRED_ACTIVITIES);
1352    }
1353
1354    void writeCrossProfileIntentFiltersLPr(XmlSerializer serializer, int userId)
1355            throws IllegalArgumentException, IllegalStateException, IOException {
1356        serializer.startTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS);
1357        CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(userId);
1358        if (cpir != null) {
1359            for (final CrossProfileIntentFilter cpif : cpir.filterSet()) {
1360                serializer.startTag(null, TAG_ITEM);
1361                cpif.writeToXml(serializer);
1362                serializer.endTag(null, TAG_ITEM);
1363            }
1364        }
1365        serializer.endTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS);
1366    }
1367
1368    void writeCrossProfilePackageInfoLPr(XmlSerializer serializer, int userId)
1369            throws IllegalArgumentException, IllegalStateException, IOException {
1370        SparseArray<ArrayList<String>> sourceForwardingInfo = mCrossProfilePackageInfo.get(userId);
1371        if (sourceForwardingInfo == null) {
1372            return;
1373        }
1374        serializer.startTag(null, TAG_CROSS_PROFILE_PACKAGE_INFO);
1375        int NI = sourceForwardingInfo.size();
1376        for (int i = 0; i < NI; i++) {
1377            int targetUserId = sourceForwardingInfo.keyAt(i);
1378            ArrayList<String> packageNames = sourceForwardingInfo.valueAt(i);
1379            serializer.startTag(null, TAG_ITEM);
1380            serializer.attribute(null, CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID,
1381                    Integer.toString(targetUserId));
1382            int NJ = packageNames.size();
1383            for (int j = 0; j < NJ; j++) {
1384                serializer.startTag(null, CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME);
1385                serializer.attribute(null, CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME,
1386                        packageNames.get(j));
1387                serializer.endTag(null, CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME);
1388            }
1389            serializer.endTag(null, TAG_ITEM);
1390        }
1391        serializer.endTag(null, TAG_CROSS_PROFILE_PACKAGE_INFO);
1392    }
1393
1394    void writePackageRestrictionsLPr(int userId) {
1395        if (DEBUG_MU) {
1396            Log.i(TAG, "Writing package restrictions for user=" + userId);
1397        }
1398        // Keep the old stopped packages around until we know the new ones have
1399        // been successfully written.
1400        File userPackagesStateFile = getUserPackagesStateFile(userId);
1401        File backupFile = getUserPackagesStateBackupFile(userId);
1402        new File(userPackagesStateFile.getParent()).mkdirs();
1403        if (userPackagesStateFile.exists()) {
1404            // Presence of backup settings file indicates that we failed
1405            // to persist packages earlier. So preserve the older
1406            // backup for future reference since the current packages
1407            // might have been corrupted.
1408            if (!backupFile.exists()) {
1409                if (!userPackagesStateFile.renameTo(backupFile)) {
1410                    Log.wtf(PackageManagerService.TAG, "Unable to backup user packages state file, "
1411                            + "current changes will be lost at reboot");
1412                    return;
1413                }
1414            } else {
1415                userPackagesStateFile.delete();
1416                Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");
1417            }
1418        }
1419
1420        try {
1421            final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile);
1422            final BufferedOutputStream str = new BufferedOutputStream(fstr);
1423
1424            final XmlSerializer serializer = new FastXmlSerializer();
1425            serializer.setOutput(str, "utf-8");
1426            serializer.startDocument(null, true);
1427            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1428
1429            serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);
1430
1431            for (final PackageSetting pkg : mPackages.values()) {
1432                PackageUserState ustate = pkg.readUserState(userId);
1433                if (ustate.stopped || ustate.notLaunched || !ustate.installed
1434                        || ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT
1435                        || ustate.blocked
1436                        || (ustate.enabledComponents != null
1437                                && ustate.enabledComponents.size() > 0)
1438                        || (ustate.disabledComponents != null
1439                                && ustate.disabledComponents.size() > 0)
1440                        || ustate.blockUninstall) {
1441                    serializer.startTag(null, TAG_PACKAGE);
1442                    serializer.attribute(null, ATTR_NAME, pkg.name);
1443                    if (DEBUG_MU) Log.i(TAG, "  pkg=" + pkg.name + ", state=" + ustate.enabled);
1444
1445                    if (!ustate.installed) {
1446                        serializer.attribute(null, ATTR_INSTALLED, "false");
1447                    }
1448                    if (ustate.stopped) {
1449                        serializer.attribute(null, ATTR_STOPPED, "true");
1450                    }
1451                    if (ustate.notLaunched) {
1452                        serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");
1453                    }
1454                    if (ustate.blocked) {
1455                        serializer.attribute(null, ATTR_BLOCKED, "true");
1456                    }
1457                    if (ustate.blockUninstall) {
1458                        serializer.attribute(null, ATTR_BLOCK_UNINSTALL, "true");
1459                    }
1460                    if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
1461                        serializer.attribute(null, ATTR_ENABLED,
1462                                Integer.toString(ustate.enabled));
1463                        if (ustate.lastDisableAppCaller != null) {
1464                            serializer.attribute(null, ATTR_ENABLED_CALLER,
1465                                    ustate.lastDisableAppCaller);
1466                        }
1467                    }
1468                    if (ustate.enabledComponents != null
1469                            && ustate.enabledComponents.size() > 0) {
1470                        serializer.startTag(null, TAG_ENABLED_COMPONENTS);
1471                        for (final String name : ustate.enabledComponents) {
1472                            serializer.startTag(null, TAG_ITEM);
1473                            serializer.attribute(null, ATTR_NAME, name);
1474                            serializer.endTag(null, TAG_ITEM);
1475                        }
1476                        serializer.endTag(null, TAG_ENABLED_COMPONENTS);
1477                    }
1478                    if (ustate.disabledComponents != null
1479                            && ustate.disabledComponents.size() > 0) {
1480                        serializer.startTag(null, TAG_DISABLED_COMPONENTS);
1481                        for (final String name : ustate.disabledComponents) {
1482                            serializer.startTag(null, TAG_ITEM);
1483                            serializer.attribute(null, ATTR_NAME, name);
1484                            serializer.endTag(null, TAG_ITEM);
1485                        }
1486                        serializer.endTag(null, TAG_DISABLED_COMPONENTS);
1487                    }
1488                    serializer.endTag(null, TAG_PACKAGE);
1489                }
1490            }
1491
1492            writePreferredActivitiesLPr(serializer, userId, true);
1493
1494            writePersistentPreferredActivitiesLPr(serializer, userId);
1495
1496            writeCrossProfileIntentFiltersLPr(serializer, userId);
1497
1498            writeCrossProfilePackageInfoLPr(serializer, userId);
1499
1500            serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
1501
1502            serializer.endDocument();
1503
1504            str.flush();
1505            FileUtils.sync(fstr);
1506            str.close();
1507
1508            // New settings successfully written, old ones are no longer
1509            // needed.
1510            backupFile.delete();
1511            FileUtils.setPermissions(userPackagesStateFile.toString(),
1512                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
1513                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
1514                    -1, -1);
1515
1516            // Done, all is good!
1517            return;
1518        } catch(java.io.IOException e) {
1519            Log.wtf(PackageManagerService.TAG,
1520                    "Unable to write package manager user packages state, "
1521                    + " current changes will be lost at reboot", e);
1522        }
1523
1524        // Clean up partially written files
1525        if (userPackagesStateFile.exists()) {
1526            if (!userPackagesStateFile.delete()) {
1527                Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: "
1528                        + mStoppedPackagesFilename);
1529            }
1530        }
1531    }
1532
1533    // Note: assumed "stopped" field is already cleared in all packages.
1534    // Legacy reader, used to read in the old file format after an upgrade. Not used after that.
1535    void readStoppedLPw() {
1536        FileInputStream str = null;
1537        if (mBackupStoppedPackagesFilename.exists()) {
1538            try {
1539                str = new FileInputStream(mBackupStoppedPackagesFilename);
1540                mReadMessages.append("Reading from backup stopped packages file\n");
1541                PackageManagerService.reportSettingsProblem(Log.INFO,
1542                        "Need to read from backup stopped packages file");
1543                if (mSettingsFilename.exists()) {
1544                    // If both the backup and normal file exist, we
1545                    // ignore the normal one since it might have been
1546                    // corrupted.
1547                    Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
1548                            + mStoppedPackagesFilename);
1549                    mStoppedPackagesFilename.delete();
1550                }
1551            } catch (java.io.IOException e) {
1552                // We'll try for the normal settings file.
1553            }
1554        }
1555
1556        try {
1557            if (str == null) {
1558                if (!mStoppedPackagesFilename.exists()) {
1559                    mReadMessages.append("No stopped packages file found\n");
1560                    PackageManagerService.reportSettingsProblem(Log.INFO,
1561                            "No stopped packages file file; assuming all started");
1562                    // At first boot, make sure no packages are stopped.
1563                    // We usually want to have third party apps initialize
1564                    // in the stopped state, but not at first boot.
1565                    for (PackageSetting pkg : mPackages.values()) {
1566                        pkg.setStopped(false, 0);
1567                        pkg.setNotLaunched(false, 0);
1568                    }
1569                    return;
1570                }
1571                str = new FileInputStream(mStoppedPackagesFilename);
1572            }
1573            final XmlPullParser parser = Xml.newPullParser();
1574            parser.setInput(str, null);
1575
1576            int type;
1577            while ((type=parser.next()) != XmlPullParser.START_TAG
1578                       && type != XmlPullParser.END_DOCUMENT) {
1579                ;
1580            }
1581
1582            if (type != XmlPullParser.START_TAG) {
1583                mReadMessages.append("No start tag found in stopped packages file\n");
1584                PackageManagerService.reportSettingsProblem(Log.WARN,
1585                        "No start tag found in package manager stopped packages");
1586                return;
1587            }
1588
1589            int outerDepth = parser.getDepth();
1590            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1591                   && (type != XmlPullParser.END_TAG
1592                           || parser.getDepth() > outerDepth)) {
1593                if (type == XmlPullParser.END_TAG
1594                        || type == XmlPullParser.TEXT) {
1595                    continue;
1596                }
1597
1598                String tagName = parser.getName();
1599                if (tagName.equals(TAG_PACKAGE)) {
1600                    String name = parser.getAttributeValue(null, ATTR_NAME);
1601                    PackageSetting ps = mPackages.get(name);
1602                    if (ps != null) {
1603                        ps.setStopped(true, 0);
1604                        if ("1".equals(parser.getAttributeValue(null, ATTR_NOT_LAUNCHED))) {
1605                            ps.setNotLaunched(true, 0);
1606                        }
1607                    } else {
1608                        Slog.w(PackageManagerService.TAG,
1609                                "No package known for stopped package: " + name);
1610                    }
1611                    XmlUtils.skipCurrentTag(parser);
1612                } else {
1613                    Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
1614                          + parser.getName());
1615                    XmlUtils.skipCurrentTag(parser);
1616                }
1617            }
1618
1619            str.close();
1620
1621        } catch (XmlPullParserException e) {
1622            mReadMessages.append("Error reading: " + e.toString());
1623            PackageManagerService.reportSettingsProblem(Log.ERROR,
1624                    "Error reading stopped packages: " + e);
1625            Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
1626
1627        } catch (java.io.IOException e) {
1628            mReadMessages.append("Error reading: " + e.toString());
1629            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1630            Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
1631
1632        }
1633    }
1634
1635    void writeLPr() {
1636        //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
1637
1638        // Keep the old settings around until we know the new ones have
1639        // been successfully written.
1640        if (mSettingsFilename.exists()) {
1641            // Presence of backup settings file indicates that we failed
1642            // to persist settings earlier. So preserve the older
1643            // backup for future reference since the current settings
1644            // might have been corrupted.
1645            if (!mBackupSettingsFilename.exists()) {
1646                if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {
1647                    Log.wtf(PackageManagerService.TAG, "Unable to backup package manager settings, "
1648                            + " current changes will be lost at reboot");
1649                    return;
1650                }
1651            } else {
1652                mSettingsFilename.delete();
1653                Slog.w(PackageManagerService.TAG, "Preserving older settings backup");
1654            }
1655        }
1656
1657        mPastSignatures.clear();
1658
1659        try {
1660            FileOutputStream fstr = new FileOutputStream(mSettingsFilename);
1661            BufferedOutputStream str = new BufferedOutputStream(fstr);
1662
1663            //XmlSerializer serializer = XmlUtils.serializerInstance();
1664            XmlSerializer serializer = new FastXmlSerializer();
1665            serializer.setOutput(str, "utf-8");
1666            serializer.startDocument(null, true);
1667            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1668
1669            serializer.startTag(null, "packages");
1670
1671            serializer.startTag(null, "last-platform-version");
1672            serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform));
1673            serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform));
1674            serializer.attribute(null, "fingerprint", mFingerprint);
1675            serializer.endTag(null, "last-platform-version");
1676
1677            serializer.startTag(null, "database-version");
1678            serializer.attribute(null, "internal", Integer.toString(mInternalDatabaseVersion));
1679            serializer.attribute(null, "external", Integer.toString(mExternalDatabaseVersion));
1680            serializer.endTag(null, "database-version");
1681
1682            if (mVerifierDeviceIdentity != null) {
1683                serializer.startTag(null, "verifier");
1684                serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());
1685                serializer.endTag(null, "verifier");
1686            }
1687
1688            if (mReadExternalStorageEnforced != null) {
1689                serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE);
1690                serializer.attribute(
1691                        null, ATTR_ENFORCEMENT, mReadExternalStorageEnforced ? "1" : "0");
1692                serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE);
1693            }
1694
1695            serializer.startTag(null, "permission-trees");
1696            for (BasePermission bp : mPermissionTrees.values()) {
1697                writePermissionLPr(serializer, bp);
1698            }
1699            serializer.endTag(null, "permission-trees");
1700
1701            serializer.startTag(null, "permissions");
1702            for (BasePermission bp : mPermissions.values()) {
1703                writePermissionLPr(serializer, bp);
1704            }
1705            serializer.endTag(null, "permissions");
1706
1707            for (final PackageSetting pkg : mPackages.values()) {
1708                writePackageLPr(serializer, pkg);
1709            }
1710
1711            for (final PackageSetting pkg : mDisabledSysPackages.values()) {
1712                writeDisabledSysPackageLPr(serializer, pkg);
1713            }
1714
1715            for (final SharedUserSetting usr : mSharedUsers.values()) {
1716                serializer.startTag(null, "shared-user");
1717                serializer.attribute(null, ATTR_NAME, usr.name);
1718                serializer.attribute(null, "userId",
1719                        Integer.toString(usr.userId));
1720                usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
1721                serializer.startTag(null, "perms");
1722                for (String name : usr.grantedPermissions) {
1723                    serializer.startTag(null, TAG_ITEM);
1724                    serializer.attribute(null, ATTR_NAME, name);
1725                    serializer.endTag(null, TAG_ITEM);
1726                }
1727                serializer.endTag(null, "perms");
1728                serializer.endTag(null, "shared-user");
1729            }
1730
1731            if (mPackagesToBeCleaned.size() > 0) {
1732                for (PackageCleanItem item : mPackagesToBeCleaned) {
1733                    final String userStr = Integer.toString(item.userId);
1734                    serializer.startTag(null, "cleaning-package");
1735                    serializer.attribute(null, ATTR_NAME, item.packageName);
1736                    serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false");
1737                    serializer.attribute(null, ATTR_USER, userStr);
1738                    serializer.endTag(null, "cleaning-package");
1739                }
1740            }
1741
1742            if (mRenamedPackages.size() > 0) {
1743                for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
1744                    serializer.startTag(null, "renamed-package");
1745                    serializer.attribute(null, "new", e.getKey());
1746                    serializer.attribute(null, "old", e.getValue());
1747                    serializer.endTag(null, "renamed-package");
1748                }
1749            }
1750
1751            mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
1752
1753            serializer.endTag(null, "packages");
1754
1755            serializer.endDocument();
1756
1757            str.flush();
1758            FileUtils.sync(fstr);
1759            str.close();
1760
1761            // New settings successfully written, old ones are no longer
1762            // needed.
1763            mBackupSettingsFilename.delete();
1764            FileUtils.setPermissions(mSettingsFilename.toString(),
1765                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
1766                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
1767                    -1, -1);
1768
1769            // Write package list file now, use a JournaledFile.
1770            File tempFile = new File(mPackageListFilename.getAbsolutePath() + ".tmp");
1771            JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
1772
1773            final File writeTarget = journal.chooseForWrite();
1774            fstr = new FileOutputStream(writeTarget);
1775            str = new BufferedOutputStream(fstr);
1776            try {
1777                FileUtils.setPermissions(fstr.getFD(), 0660, SYSTEM_UID, PACKAGE_INFO_GID);
1778
1779                StringBuilder sb = new StringBuilder();
1780                for (final PackageSetting pkg : mPackages.values()) {
1781                    if (pkg.pkg == null || pkg.pkg.applicationInfo == null) {
1782                        Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
1783                        continue;
1784                    }
1785
1786                    final ApplicationInfo ai = pkg.pkg.applicationInfo;
1787                    final String dataPath = ai.dataDir;
1788                    final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
1789                    final int[] gids = pkg.getGids();
1790
1791                    // Avoid any application that has a space in its path.
1792                    if (dataPath.indexOf(" ") >= 0)
1793                        continue;
1794
1795                    // we store on each line the following information for now:
1796                    //
1797                    // pkgName    - package name
1798                    // userId     - application-specific user id
1799                    // debugFlag  - 0 or 1 if the package is debuggable.
1800                    // dataPath   - path to package's data path
1801                    // seinfo     - seinfo label for the app (assigned at install time)
1802                    // gids       - supplementary gids this app launches with
1803                    //
1804                    // NOTE: We prefer not to expose all ApplicationInfo flags for now.
1805                    //
1806                    // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
1807                    // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
1808                    //   system/core/run-as/run-as.c
1809                    //   system/core/sdcard/sdcard.c
1810                    //   external/libselinux/src/android.c:package_info_init()
1811                    //
1812                    sb.setLength(0);
1813                    sb.append(ai.packageName);
1814                    sb.append(" ");
1815                    sb.append((int)ai.uid);
1816                    sb.append(isDebug ? " 1 " : " 0 ");
1817                    sb.append(dataPath);
1818                    sb.append(" ");
1819                    sb.append(ai.seinfo);
1820                    sb.append(" ");
1821                    if (gids != null && gids.length > 0) {
1822                        sb.append(gids[0]);
1823                        for (int i = 1; i < gids.length; i++) {
1824                            sb.append(",");
1825                            sb.append(gids[i]);
1826                        }
1827                    } else {
1828                        sb.append("none");
1829                    }
1830                    sb.append("\n");
1831                    str.write(sb.toString().getBytes());
1832                }
1833                str.flush();
1834                FileUtils.sync(fstr);
1835                str.close();
1836                journal.commit();
1837            } catch (Exception e) {
1838                Log.wtf(TAG, "Failed to write packages.list", e);
1839                IoUtils.closeQuietly(str);
1840                journal.rollback();
1841            }
1842
1843            writeAllUsersPackageRestrictionsLPr();
1844            return;
1845
1846        } catch(XmlPullParserException e) {
1847            Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
1848                    + "current changes will be lost at reboot", e);
1849        } catch(java.io.IOException e) {
1850            Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
1851                    + "current changes will be lost at reboot", e);
1852        }
1853        // Clean up partially written files
1854        if (mSettingsFilename.exists()) {
1855            if (!mSettingsFilename.delete()) {
1856                Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: "
1857                        + mSettingsFilename);
1858            }
1859        }
1860        //Debug.stopMethodTracing();
1861    }
1862
1863    void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
1864            throws java.io.IOException {
1865        serializer.startTag(null, "updated-package");
1866        serializer.attribute(null, ATTR_NAME, pkg.name);
1867        if (pkg.realName != null) {
1868            serializer.attribute(null, "realName", pkg.realName);
1869        }
1870        serializer.attribute(null, "codePath", pkg.codePathString);
1871        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
1872        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
1873        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
1874        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
1875        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
1876            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
1877        }
1878        if (pkg.legacyNativeLibraryPathString != null) {
1879            serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
1880        }
1881        if (pkg.primaryCpuAbiString != null) {
1882           serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString);
1883        }
1884        if (pkg.secondaryCpuAbiString != null) {
1885            serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString);
1886        }
1887
1888        if (pkg.sharedUser == null) {
1889            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
1890        } else {
1891            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
1892        }
1893        serializer.startTag(null, "perms");
1894        if (pkg.sharedUser == null) {
1895            // If this is a shared user, the permissions will
1896            // be written there. We still need to write an
1897            // empty permissions list so permissionsFixed will
1898            // be set.
1899            for (final String name : pkg.grantedPermissions) {
1900                BasePermission bp = mPermissions.get(name);
1901                if (bp != null) {
1902                    // We only need to write signature or system permissions but
1903                    // this wont
1904                    // match the semantics of grantedPermissions. So write all
1905                    // permissions.
1906                    serializer.startTag(null, TAG_ITEM);
1907                    serializer.attribute(null, ATTR_NAME, name);
1908                    serializer.endTag(null, TAG_ITEM);
1909                }
1910            }
1911        }
1912        serializer.endTag(null, "perms");
1913        serializer.endTag(null, "updated-package");
1914    }
1915
1916    void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)
1917            throws java.io.IOException {
1918        serializer.startTag(null, "package");
1919        serializer.attribute(null, ATTR_NAME, pkg.name);
1920        if (pkg.realName != null) {
1921            serializer.attribute(null, "realName", pkg.realName);
1922        }
1923        serializer.attribute(null, "codePath", pkg.codePathString);
1924        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
1925            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
1926        }
1927
1928        if (pkg.legacyNativeLibraryPathString != null) {
1929            serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
1930        }
1931        if (pkg.primaryCpuAbiString != null) {
1932            serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString);
1933        }
1934        if (pkg.secondaryCpuAbiString != null) {
1935            serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString);
1936        }
1937
1938        serializer.attribute(null, "flags", Integer.toString(pkg.pkgFlags));
1939        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
1940        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
1941        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
1942        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
1943        if (pkg.sharedUser == null) {
1944            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
1945        } else {
1946            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
1947        }
1948        if (pkg.uidError) {
1949            serializer.attribute(null, "uidError", "true");
1950        }
1951        if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
1952            serializer.attribute(null, "installStatus", "false");
1953        }
1954        if (pkg.installerPackageName != null) {
1955            serializer.attribute(null, "installer", pkg.installerPackageName);
1956        }
1957        pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
1958        if ((pkg.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1959            serializer.startTag(null, "perms");
1960            if (pkg.sharedUser == null) {
1961                // If this is a shared user, the permissions will
1962                // be written there. We still need to write an
1963                // empty permissions list so permissionsFixed will
1964                // be set.
1965                for (final String name : pkg.grantedPermissions) {
1966                    serializer.startTag(null, TAG_ITEM);
1967                    serializer.attribute(null, ATTR_NAME, name);
1968                    serializer.endTag(null, TAG_ITEM);
1969                }
1970            }
1971            serializer.endTag(null, "perms");
1972        }
1973
1974        writeSigningKeySetsLPr(serializer, pkg.keySetData);
1975        writeUpgradeKeySetsLPr(serializer, pkg.keySetData);
1976        writeKeySetAliasesLPr(serializer, pkg.keySetData);
1977
1978        serializer.endTag(null, "package");
1979    }
1980
1981    void writeSigningKeySetsLPr(XmlSerializer serializer,
1982            PackageKeySetData data) throws IOException {
1983        if (data.getSigningKeySets() != null) {
1984            // Keep track of the original signing-keyset.
1985            // Must be recorded first, since it will be read first and wipe the
1986            // current signing-keysets for the package when set.
1987            long properSigningKeySet = data.getProperSigningKeySet();
1988            serializer.startTag(null, "proper-signing-keyset");
1989            serializer.attribute(null, "identifier", Long.toString(properSigningKeySet));
1990            serializer.endTag(null, "proper-signing-keyset");
1991            for (long id : data.getSigningKeySets()) {
1992                serializer.startTag(null, "signing-keyset");
1993                serializer.attribute(null, "identifier", Long.toString(id));
1994                serializer.endTag(null, "signing-keyset");
1995            }
1996        }
1997    }
1998
1999    void writeUpgradeKeySetsLPr(XmlSerializer serializer,
2000            PackageKeySetData data) throws IOException {
2001        if (data.isUsingUpgradeKeySets()) {
2002            for (long id : data.getUpgradeKeySets()) {
2003                serializer.startTag(null, "upgrade-keyset");
2004                serializer.attribute(null, "identifier", Long.toString(id));
2005                serializer.endTag(null, "upgrade-keyset");
2006            }
2007        }
2008    }
2009
2010    void writeKeySetAliasesLPr(XmlSerializer serializer,
2011            PackageKeySetData data) throws IOException {
2012        for (Map.Entry<String, Long> e: data.getAliases().entrySet()) {
2013            serializer.startTag(null, "defined-keyset");
2014            serializer.attribute(null, "alias", e.getKey());
2015            serializer.attribute(null, "identifier", Long.toString(e.getValue()));
2016            serializer.endTag(null, "defined-keyset");
2017        }
2018    }
2019
2020    void writePermissionLPr(XmlSerializer serializer, BasePermission bp)
2021            throws XmlPullParserException, java.io.IOException {
2022        if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) {
2023            serializer.startTag(null, TAG_ITEM);
2024            serializer.attribute(null, ATTR_NAME, bp.name);
2025            serializer.attribute(null, "package", bp.sourcePackage);
2026            if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
2027                serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel));
2028            }
2029            if (PackageManagerService.DEBUG_SETTINGS)
2030                Log.v(PackageManagerService.TAG, "Writing perm: name=" + bp.name + " type="
2031                        + bp.type);
2032            if (bp.type == BasePermission.TYPE_DYNAMIC) {
2033                final PermissionInfo pi = bp.perm != null ? bp.perm.info : bp.pendingInfo;
2034                if (pi != null) {
2035                    serializer.attribute(null, "type", "dynamic");
2036                    if (pi.icon != 0) {
2037                        serializer.attribute(null, "icon", Integer.toString(pi.icon));
2038                    }
2039                    if (pi.nonLocalizedLabel != null) {
2040                        serializer.attribute(null, "label", pi.nonLocalizedLabel.toString());
2041                    }
2042                }
2043            }
2044            serializer.endTag(null, TAG_ITEM);
2045        }
2046    }
2047
2048    ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() {
2049        final HashSet<String> kList = new HashSet<String>(mPackages.keySet());
2050        final Iterator<String> its = kList.iterator();
2051        final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
2052        while (its.hasNext()) {
2053            final String key = its.next();
2054            final PackageSetting ps = mPackages.get(key);
2055            if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
2056                ret.add(ps);
2057            }
2058        }
2059        return ret;
2060    }
2061
2062    void addPackageToCleanLPw(PackageCleanItem pkg) {
2063        if (!mPackagesToBeCleaned.contains(pkg)) {
2064            mPackagesToBeCleaned.add(pkg);
2065        }
2066    }
2067
2068    boolean readLPw(PackageManagerService service, List<UserInfo> users, int sdkVersion,
2069            boolean onlyCore) {
2070        FileInputStream str = null;
2071        if (mBackupSettingsFilename.exists()) {
2072            try {
2073                str = new FileInputStream(mBackupSettingsFilename);
2074                mReadMessages.append("Reading from backup settings file\n");
2075                PackageManagerService.reportSettingsProblem(Log.INFO,
2076                        "Need to read from backup settings file");
2077                if (mSettingsFilename.exists()) {
2078                    // If both the backup and settings file exist, we
2079                    // ignore the settings since it might have been
2080                    // corrupted.
2081                    Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
2082                            + mSettingsFilename);
2083                    mSettingsFilename.delete();
2084                }
2085            } catch (java.io.IOException e) {
2086                // We'll try for the normal settings file.
2087            }
2088        }
2089
2090        mPendingPackages.clear();
2091        mPastSignatures.clear();
2092
2093        try {
2094            if (str == null) {
2095                if (!mSettingsFilename.exists()) {
2096                    mReadMessages.append("No settings file found\n");
2097                    PackageManagerService.reportSettingsProblem(Log.INFO,
2098                            "No settings file; creating initial state");
2099                    mInternalSdkPlatform = mExternalSdkPlatform = sdkVersion;
2100                    mFingerprint = Build.FINGERPRINT;
2101                    return false;
2102                }
2103                str = new FileInputStream(mSettingsFilename);
2104            }
2105            XmlPullParser parser = Xml.newPullParser();
2106            parser.setInput(str, null);
2107
2108            int type;
2109            while ((type = parser.next()) != XmlPullParser.START_TAG
2110                    && type != XmlPullParser.END_DOCUMENT) {
2111                ;
2112            }
2113
2114            if (type != XmlPullParser.START_TAG) {
2115                mReadMessages.append("No start tag found in settings file\n");
2116                PackageManagerService.reportSettingsProblem(Log.WARN,
2117                        "No start tag found in package manager settings");
2118                Log.wtf(PackageManagerService.TAG,
2119                        "No start tag found in package manager settings");
2120                return false;
2121            }
2122
2123            int outerDepth = parser.getDepth();
2124            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2125                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2126                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2127                    continue;
2128                }
2129
2130                String tagName = parser.getName();
2131                if (tagName.equals("package")) {
2132                    readPackageLPw(parser);
2133                } else if (tagName.equals("permissions")) {
2134                    readPermissionsLPw(mPermissions, parser);
2135                } else if (tagName.equals("permission-trees")) {
2136                    readPermissionsLPw(mPermissionTrees, parser);
2137                } else if (tagName.equals("shared-user")) {
2138                    readSharedUserLPw(parser);
2139                } else if (tagName.equals("preferred-packages")) {
2140                    // no longer used.
2141                } else if (tagName.equals("preferred-activities")) {
2142                    // Upgrading from old single-user implementation;
2143                    // these are the preferred activities for user 0.
2144                    readPreferredActivitiesLPw(parser, 0);
2145                } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
2146                    // TODO: check whether this is okay! as it is very
2147                    // similar to how preferred-activities are treated
2148                    readPersistentPreferredActivitiesLPw(parser, 0);
2149                } else if (tagName.equals(TAG_FORWARDING_INTENT_FILTERS)
2150                        || tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
2151                    // TODO: check whether this is okay! as it is very
2152                    // similar to how preferred-activities are treated
2153                    readCrossProfileIntentFiltersLPw(parser, 0);
2154                } else if (tagName.equals("updated-package")) {
2155                    readDisabledSysPackageLPw(parser);
2156                } else if (tagName.equals("cleaning-package")) {
2157                    String name = parser.getAttributeValue(null, ATTR_NAME);
2158                    String userStr = parser.getAttributeValue(null, ATTR_USER);
2159                    String codeStr = parser.getAttributeValue(null, ATTR_CODE);
2160                    if (name != null) {
2161                        int userId = 0;
2162                        boolean andCode = true;
2163                        try {
2164                            if (userStr != null) {
2165                                userId = Integer.parseInt(userStr);
2166                            }
2167                        } catch (NumberFormatException e) {
2168                        }
2169                        if (codeStr != null) {
2170                            andCode = Boolean.parseBoolean(codeStr);
2171                        }
2172                        addPackageToCleanLPw(new PackageCleanItem(userId, name, andCode));
2173                    }
2174                } else if (tagName.equals("renamed-package")) {
2175                    String nname = parser.getAttributeValue(null, "new");
2176                    String oname = parser.getAttributeValue(null, "old");
2177                    if (nname != null && oname != null) {
2178                        mRenamedPackages.put(nname, oname);
2179                    }
2180                } else if (tagName.equals("last-platform-version")) {
2181                    mInternalSdkPlatform = mExternalSdkPlatform = 0;
2182                    try {
2183                        String internal = parser.getAttributeValue(null, "internal");
2184                        if (internal != null) {
2185                            mInternalSdkPlatform = Integer.parseInt(internal);
2186                        }
2187                        String external = parser.getAttributeValue(null, "external");
2188                        if (external != null) {
2189                            mExternalSdkPlatform = Integer.parseInt(external);
2190                        }
2191                    } catch (NumberFormatException e) {
2192                    }
2193                    mFingerprint = parser.getAttributeValue(null, "fingerprint");
2194                } else if (tagName.equals("database-version")) {
2195                    mInternalDatabaseVersion = mExternalDatabaseVersion = 0;
2196                    try {
2197                        String internalDbVersionString = parser.getAttributeValue(null, "internal");
2198                        if (internalDbVersionString != null) {
2199                            mInternalDatabaseVersion = Integer.parseInt(internalDbVersionString);
2200                        }
2201                        String externalDbVersionString = parser.getAttributeValue(null, "external");
2202                        if (externalDbVersionString != null) {
2203                            mExternalDatabaseVersion = Integer.parseInt(externalDbVersionString);
2204                        }
2205                    } catch (NumberFormatException ignored) {
2206                    }
2207                } else if (tagName.equals("verifier")) {
2208                    final String deviceIdentity = parser.getAttributeValue(null, "device");
2209                    try {
2210                        mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
2211                    } catch (IllegalArgumentException e) {
2212                        Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
2213                                + e.getMessage());
2214                    }
2215                } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
2216                    final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
2217                    mReadExternalStorageEnforced = "1".equals(enforcement);
2218                } else if (tagName.equals("keyset-settings")) {
2219                    mKeySetManagerService.readKeySetsLPw(parser);
2220                } else {
2221                    Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
2222                            + parser.getName());
2223                    XmlUtils.skipCurrentTag(parser);
2224                }
2225            }
2226
2227            str.close();
2228
2229        } catch (XmlPullParserException e) {
2230            mReadMessages.append("Error reading: " + e.toString());
2231            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2232            Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
2233
2234        } catch (java.io.IOException e) {
2235            mReadMessages.append("Error reading: " + e.toString());
2236            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2237            Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
2238        }
2239
2240        final int N = mPendingPackages.size();
2241        for (int i = 0; i < N; i++) {
2242            final PendingPackage pp = mPendingPackages.get(i);
2243            Object idObj = getUserIdLPr(pp.sharedId);
2244            if (idObj != null && idObj instanceof SharedUserSetting) {
2245                PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
2246                        (SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
2247                        pp.legacyNativeLibraryPathString, pp.primaryCpuAbiString,
2248                        pp.secondaryCpuAbiString, pp.versionCode, pp.pkgFlags,
2249                        null, true /* add */, false /* allowInstall */);
2250                if (p == null) {
2251                    PackageManagerService.reportSettingsProblem(Log.WARN,
2252                            "Unable to create application package for " + pp.name);
2253                    continue;
2254                }
2255                p.copyFrom(pp);
2256            } else if (idObj != null) {
2257                String msg = "Bad package setting: package " + pp.name + " has shared uid "
2258                        + pp.sharedId + " that is not a shared uid\n";
2259                mReadMessages.append(msg);
2260                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
2261            } else {
2262                String msg = "Bad package setting: package " + pp.name + " has shared uid "
2263                        + pp.sharedId + " that is not defined\n";
2264                mReadMessages.append(msg);
2265                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
2266            }
2267        }
2268        mPendingPackages.clear();
2269
2270        if (mBackupStoppedPackagesFilename.exists()
2271                || mStoppedPackagesFilename.exists()) {
2272            // Read old file
2273            readStoppedLPw();
2274            mBackupStoppedPackagesFilename.delete();
2275            mStoppedPackagesFilename.delete();
2276            // Migrate to new file format
2277            writePackageRestrictionsLPr(0);
2278        } else {
2279            if (users == null) {
2280                readPackageRestrictionsLPr(0);
2281            } else {
2282                for (UserInfo user : users) {
2283                    readPackageRestrictionsLPr(user.id);
2284                }
2285            }
2286        }
2287
2288        /*
2289         * Make sure all the updated system packages have their shared users
2290         * associated with them.
2291         */
2292        final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
2293        while (disabledIt.hasNext()) {
2294            final PackageSetting disabledPs = disabledIt.next();
2295            final Object id = getUserIdLPr(disabledPs.appId);
2296            if (id != null && id instanceof SharedUserSetting) {
2297                disabledPs.sharedUser = (SharedUserSetting) id;
2298            }
2299        }
2300
2301        mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
2302                + mSharedUsers.size() + " shared uids\n");
2303
2304        return true;
2305    }
2306
2307    void readDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
2308        // First pull data from any pre-installed apps.
2309        for (PackageSetting ps : mPackages.values()) {
2310            if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
2311                    && ps.pkg.preferredActivityFilters != null) {
2312                ArrayList<PackageParser.ActivityIntentInfo> intents
2313                        = ps.pkg.preferredActivityFilters;
2314                for (int i=0; i<intents.size(); i++) {
2315                    PackageParser.ActivityIntentInfo aii = intents.get(i);
2316                    applyDefaultPreferredActivityLPw(service, aii, new ComponentName(
2317                            ps.name, aii.activity.className), userId);
2318                }
2319            }
2320        }
2321
2322        // Read preferred apps from .../etc/preferred-apps directory.
2323        File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps");
2324        if (!preferredDir.exists() || !preferredDir.isDirectory()) {
2325            return;
2326        }
2327        if (!preferredDir.canRead()) {
2328            Slog.w(TAG, "Directory " + preferredDir + " cannot be read");
2329            return;
2330        }
2331
2332        // Iterate over the files in the directory and scan .xml files
2333        for (File f : preferredDir.listFiles()) {
2334            if (!f.getPath().endsWith(".xml")) {
2335                Slog.i(TAG, "Non-xml file " + f + " in " + preferredDir + " directory, ignoring");
2336                continue;
2337            }
2338            if (!f.canRead()) {
2339                Slog.w(TAG, "Preferred apps file " + f + " cannot be read");
2340                continue;
2341            }
2342
2343            if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Reading default preferred " + f);
2344            FileInputStream str = null;
2345            try {
2346                str = new FileInputStream(f);
2347                XmlPullParser parser = Xml.newPullParser();
2348                parser.setInput(str, null);
2349
2350                int type;
2351                while ((type = parser.next()) != XmlPullParser.START_TAG
2352                        && type != XmlPullParser.END_DOCUMENT) {
2353                    ;
2354                }
2355
2356                if (type != XmlPullParser.START_TAG) {
2357                    Slog.w(TAG, "Preferred apps file " + f + " does not have start tag");
2358                    continue;
2359                }
2360                if (!"preferred-activities".equals(parser.getName())) {
2361                    Slog.w(TAG, "Preferred apps file " + f
2362                            + " does not start with 'preferred-activities'");
2363                    continue;
2364                }
2365                readDefaultPreferredActivitiesLPw(service, parser, userId);
2366            } catch (XmlPullParserException e) {
2367                Slog.w(TAG, "Error reading apps file " + f, e);
2368            } catch (IOException e) {
2369                Slog.w(TAG, "Error reading apps file " + f, e);
2370            } finally {
2371                if (str != null) {
2372                    try {
2373                        str.close();
2374                    } catch (IOException e) {
2375                    }
2376                }
2377            }
2378        }
2379    }
2380
2381    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
2382            IntentFilter tmpPa, ComponentName cn, int userId) {
2383        // The initial preferences only specify the target activity
2384        // component and intent-filter, not the set of matches.  So we
2385        // now need to query for the matches to build the correct
2386        // preferred activity entry.
2387        if (PackageManagerService.DEBUG_PREFERRED) {
2388            Log.d(TAG, "Processing preferred:");
2389            tmpPa.dump(new LogPrinter(Log.DEBUG, TAG), "  ");
2390        }
2391        Intent intent = new Intent();
2392        int flags = 0;
2393        intent.setAction(tmpPa.getAction(0));
2394        for (int i=0; i<tmpPa.countCategories(); i++) {
2395            String cat = tmpPa.getCategory(i);
2396            if (cat.equals(Intent.CATEGORY_DEFAULT)) {
2397                flags |= PackageManager.MATCH_DEFAULT_ONLY;
2398            } else {
2399                intent.addCategory(cat);
2400            }
2401        }
2402
2403        boolean doNonData = true;
2404        boolean hasSchemes = false;
2405
2406        for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
2407            boolean doScheme = true;
2408            String scheme = tmpPa.getDataScheme(ischeme);
2409            if (scheme != null && !scheme.isEmpty()) {
2410                hasSchemes = true;
2411            }
2412            for (int issp=0; issp<tmpPa.countDataSchemeSpecificParts(); issp++) {
2413                Uri.Builder builder = new Uri.Builder();
2414                builder.scheme(scheme);
2415                PatternMatcher ssp = tmpPa.getDataSchemeSpecificPart(issp);
2416                builder.opaquePart(ssp.getPath());
2417                Intent finalIntent = new Intent(intent);
2418                finalIntent.setData(builder.build());
2419                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2420                        scheme, ssp, null, null, null, userId);
2421                doScheme = false;
2422            }
2423            for (int iauth=0; iauth<tmpPa.countDataAuthorities(); iauth++) {
2424                boolean doAuth = true;
2425                IntentFilter.AuthorityEntry auth = tmpPa.getDataAuthority(iauth);
2426                for (int ipath=0; ipath<tmpPa.countDataPaths(); ipath++) {
2427                    Uri.Builder builder = new Uri.Builder();
2428                    builder.scheme(scheme);
2429                    if (auth.getHost() != null) {
2430                        builder.authority(auth.getHost());
2431                    }
2432                    PatternMatcher path = tmpPa.getDataPath(ipath);
2433                    builder.path(path.getPath());
2434                    Intent finalIntent = new Intent(intent);
2435                    finalIntent.setData(builder.build());
2436                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2437                            scheme, null, auth, path, null, userId);
2438                    doAuth = doScheme = false;
2439                }
2440                if (doAuth) {
2441                    Uri.Builder builder = new Uri.Builder();
2442                    builder.scheme(scheme);
2443                    if (auth.getHost() != null) {
2444                        builder.authority(auth.getHost());
2445                    }
2446                    Intent finalIntent = new Intent(intent);
2447                    finalIntent.setData(builder.build());
2448                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2449                            scheme, null, auth, null, null, userId);
2450                    doScheme = false;
2451                }
2452            }
2453            if (doScheme) {
2454                Uri.Builder builder = new Uri.Builder();
2455                builder.scheme(scheme);
2456                Intent finalIntent = new Intent(intent);
2457                finalIntent.setData(builder.build());
2458                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2459                        scheme, null, null, null, null, userId);
2460            }
2461            doNonData = false;
2462        }
2463
2464        for (int idata=0; idata<tmpPa.countDataTypes(); idata++) {
2465            String mimeType = tmpPa.getDataType(idata);
2466            if (hasSchemes) {
2467                Uri.Builder builder = new Uri.Builder();
2468                for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
2469                    String scheme = tmpPa.getDataScheme(ischeme);
2470                    if (scheme != null && !scheme.isEmpty()) {
2471                        Intent finalIntent = new Intent(intent);
2472                        builder.scheme(scheme);
2473                        finalIntent.setDataAndType(builder.build(), mimeType);
2474                        applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2475                                scheme, null, null, null, mimeType, userId);
2476                    }
2477                }
2478            } else {
2479                Intent finalIntent = new Intent(intent);
2480                finalIntent.setType(mimeType);
2481                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2482                        null, null, null, null, mimeType, userId);
2483            }
2484            doNonData = false;
2485        }
2486
2487        if (doNonData) {
2488            applyDefaultPreferredActivityLPw(service, intent, flags, cn,
2489                    null, null, null, null, null, userId);
2490        }
2491    }
2492
2493    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
2494            Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp,
2495            IntentFilter.AuthorityEntry auth, PatternMatcher path, String mimeType,
2496            int userId) {
2497        List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
2498                intent.getType(), flags, 0);
2499        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
2500                + " results: " + ri);
2501        int match = 0;
2502        if (ri != null && ri.size() > 1) {
2503            boolean haveAct = false;
2504            boolean haveNonSys = false;
2505            ComponentName[] set = new ComponentName[ri.size()];
2506            for (int i=0; i<ri.size(); i++) {
2507                ActivityInfo ai = ri.get(i).activityInfo;
2508                set[i] = new ComponentName(ai.packageName, ai.name);
2509                if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
2510                    // If any of the matches are not system apps, then
2511                    // there is a third party app that is now an option...
2512                    // so don't set a default since we don't want to hide it.
2513                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2514                            + ai.packageName + "/" + ai.name + ": non-system!");
2515                    haveNonSys = true;
2516                    break;
2517                } else if (cn.getPackageName().equals(ai.packageName)
2518                        && cn.getClassName().equals(ai.name)) {
2519                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2520                            + ai.packageName + "/" + ai.name + ": default!");
2521                    haveAct = true;
2522                    match = ri.get(i).match;
2523                } else {
2524                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2525                            + ai.packageName + "/" + ai.name + ": skipped");
2526                }
2527            }
2528            if (haveAct && !haveNonSys) {
2529                IntentFilter filter = new IntentFilter();
2530                if (intent.getAction() != null) {
2531                    filter.addAction(intent.getAction());
2532                }
2533                if (intent.getCategories() != null) {
2534                    for (String cat : intent.getCategories()) {
2535                        filter.addCategory(cat);
2536                    }
2537                }
2538                if ((flags&PackageManager.MATCH_DEFAULT_ONLY) != 0) {
2539                    filter.addCategory(Intent.CATEGORY_DEFAULT);
2540                }
2541                if (scheme != null) {
2542                    filter.addDataScheme(scheme);
2543                }
2544                if (ssp != null) {
2545                    filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
2546                }
2547                if (auth != null) {
2548                    filter.addDataAuthority(auth);
2549                }
2550                if (path != null) {
2551                    filter.addDataPath(path);
2552                }
2553                if (intent.getType() != null) {
2554                    try {
2555                        filter.addDataType(intent.getType());
2556                    } catch (IntentFilter.MalformedMimeTypeException ex) {
2557                        Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
2558                    }
2559                }
2560                PreferredActivity pa = new PreferredActivity(filter, match, set, cn, true);
2561                editPreferredActivitiesLPw(userId).addFilter(pa);
2562            } else if (!haveNonSys) {
2563                Slog.w(TAG, "No component found for default preferred activity " + cn);
2564            }
2565        }
2566    }
2567
2568    private void readDefaultPreferredActivitiesLPw(PackageManagerService service,
2569            XmlPullParser parser, int userId)
2570            throws XmlPullParserException, IOException {
2571        int outerDepth = parser.getDepth();
2572        int type;
2573        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2574                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2575            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2576                continue;
2577            }
2578
2579            String tagName = parser.getName();
2580            if (tagName.equals(TAG_ITEM)) {
2581                PreferredActivity tmpPa = new PreferredActivity(parser);
2582                if (tmpPa.mPref.getParseError() == null) {
2583                    applyDefaultPreferredActivityLPw(service, tmpPa, tmpPa.mPref.mComponent,
2584                            userId);
2585                } else {
2586                    PackageManagerService.reportSettingsProblem(Log.WARN,
2587                            "Error in package manager settings: <preferred-activity> "
2588                                    + tmpPa.mPref.getParseError() + " at "
2589                                    + parser.getPositionDescription());
2590                }
2591            } else {
2592                PackageManagerService.reportSettingsProblem(Log.WARN,
2593                        "Unknown element under <preferred-activities>: " + parser.getName());
2594                XmlUtils.skipCurrentTag(parser);
2595            }
2596        }
2597    }
2598
2599    private int readInt(XmlPullParser parser, String ns, String name, int defValue) {
2600        String v = parser.getAttributeValue(ns, name);
2601        try {
2602            if (v == null) {
2603                return defValue;
2604            }
2605            return Integer.parseInt(v);
2606        } catch (NumberFormatException e) {
2607            PackageManagerService.reportSettingsProblem(Log.WARN,
2608                    "Error in package manager settings: attribute " + name
2609                            + " has bad integer value " + v + " at "
2610                            + parser.getPositionDescription());
2611        }
2612        return defValue;
2613    }
2614
2615    private void readPermissionsLPw(HashMap<String, BasePermission> out, XmlPullParser parser)
2616            throws IOException, XmlPullParserException {
2617        int outerDepth = parser.getDepth();
2618        int type;
2619        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2620                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2621            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2622                continue;
2623            }
2624
2625            final String tagName = parser.getName();
2626            if (tagName.equals(TAG_ITEM)) {
2627                final String name = parser.getAttributeValue(null, ATTR_NAME);
2628                final String sourcePackage = parser.getAttributeValue(null, "package");
2629                final String ptype = parser.getAttributeValue(null, "type");
2630                if (name != null && sourcePackage != null) {
2631                    final boolean dynamic = "dynamic".equals(ptype);
2632                    final BasePermission bp = new BasePermission(name, sourcePackage,
2633                            dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
2634                    bp.protectionLevel = readInt(parser, null, "protection",
2635                            PermissionInfo.PROTECTION_NORMAL);
2636                    bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
2637                    if (dynamic) {
2638                        PermissionInfo pi = new PermissionInfo();
2639                        pi.packageName = sourcePackage.intern();
2640                        pi.name = name.intern();
2641                        pi.icon = readInt(parser, null, "icon", 0);
2642                        pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
2643                        pi.protectionLevel = bp.protectionLevel;
2644                        bp.pendingInfo = pi;
2645                    }
2646                    out.put(bp.name, bp);
2647                } else {
2648                    PackageManagerService.reportSettingsProblem(Log.WARN,
2649                            "Error in package manager settings: permissions has" + " no name at "
2650                                    + parser.getPositionDescription());
2651                }
2652            } else {
2653                PackageManagerService.reportSettingsProblem(Log.WARN,
2654                        "Unknown element reading permissions: " + parser.getName() + " at "
2655                                + parser.getPositionDescription());
2656            }
2657            XmlUtils.skipCurrentTag(parser);
2658        }
2659    }
2660
2661    private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
2662            IOException {
2663        String name = parser.getAttributeValue(null, ATTR_NAME);
2664        String realName = parser.getAttributeValue(null, "realName");
2665        String codePathStr = parser.getAttributeValue(null, "codePath");
2666        String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
2667
2668        String legacyCpuAbiStr = parser.getAttributeValue(null, "requiredCpuAbi");
2669        String legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
2670
2671        String primaryCpuAbiStr = parser.getAttributeValue(null, "primaryCpuAbi");
2672        String secondaryCpuAbiStr = parser.getAttributeValue(null, "secondaryCpuAbi");
2673
2674        if (primaryCpuAbiStr == null && legacyCpuAbiStr != null) {
2675            primaryCpuAbiStr = legacyCpuAbiStr;
2676        }
2677
2678        if (resourcePathStr == null) {
2679            resourcePathStr = codePathStr;
2680        }
2681        String version = parser.getAttributeValue(null, "version");
2682        int versionCode = 0;
2683        if (version != null) {
2684            try {
2685                versionCode = Integer.parseInt(version);
2686            } catch (NumberFormatException e) {
2687            }
2688        }
2689
2690        int pkgFlags = 0;
2691        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2692        final File codePathFile = new File(codePathStr);
2693        if (PackageManagerService.locationIsPrivileged(codePathFile)) {
2694            pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
2695        }
2696        PackageSetting ps = new PackageSetting(name, realName, codePathFile,
2697                new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr,
2698                secondaryCpuAbiStr, versionCode, pkgFlags);
2699        String timeStampStr = parser.getAttributeValue(null, "ft");
2700        if (timeStampStr != null) {
2701            try {
2702                long timeStamp = Long.parseLong(timeStampStr, 16);
2703                ps.setTimeStamp(timeStamp);
2704            } catch (NumberFormatException e) {
2705            }
2706        } else {
2707            timeStampStr = parser.getAttributeValue(null, "ts");
2708            if (timeStampStr != null) {
2709                try {
2710                    long timeStamp = Long.parseLong(timeStampStr);
2711                    ps.setTimeStamp(timeStamp);
2712                } catch (NumberFormatException e) {
2713                }
2714            }
2715        }
2716        timeStampStr = parser.getAttributeValue(null, "it");
2717        if (timeStampStr != null) {
2718            try {
2719                ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
2720            } catch (NumberFormatException e) {
2721            }
2722        }
2723        timeStampStr = parser.getAttributeValue(null, "ut");
2724        if (timeStampStr != null) {
2725            try {
2726                ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
2727            } catch (NumberFormatException e) {
2728            }
2729        }
2730        String idStr = parser.getAttributeValue(null, "userId");
2731        ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
2732        if (ps.appId <= 0) {
2733            String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
2734            ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
2735        }
2736        int outerDepth = parser.getDepth();
2737        int type;
2738        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2739                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2740            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2741                continue;
2742            }
2743
2744            String tagName = parser.getName();
2745            if (tagName.equals("perms")) {
2746                readGrantedPermissionsLPw(parser, ps.grantedPermissions);
2747            } else {
2748                PackageManagerService.reportSettingsProblem(Log.WARN,
2749                        "Unknown element under <updated-package>: " + parser.getName());
2750                XmlUtils.skipCurrentTag(parser);
2751            }
2752        }
2753
2754        mDisabledSysPackages.put(name, ps);
2755    }
2756
2757    private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
2758        String name = null;
2759        String realName = null;
2760        String idStr = null;
2761        String sharedIdStr = null;
2762        String codePathStr = null;
2763        String resourcePathStr = null;
2764        String legacyCpuAbiString = null;
2765        String legacyNativeLibraryPathStr = null;
2766        String primaryCpuAbiString = null;
2767        String secondaryCpuAbiString = null;
2768        String systemStr = null;
2769        String installerPackageName = null;
2770        String uidError = null;
2771        int pkgFlags = 0;
2772        long timeStamp = 0;
2773        long firstInstallTime = 0;
2774        long lastUpdateTime = 0;
2775        PackageSettingBase packageSetting = null;
2776        String version = null;
2777        int versionCode = 0;
2778        try {
2779            name = parser.getAttributeValue(null, ATTR_NAME);
2780            realName = parser.getAttributeValue(null, "realName");
2781            idStr = parser.getAttributeValue(null, "userId");
2782            uidError = parser.getAttributeValue(null, "uidError");
2783            sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
2784            codePathStr = parser.getAttributeValue(null, "codePath");
2785            resourcePathStr = parser.getAttributeValue(null, "resourcePath");
2786
2787            legacyCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
2788
2789            legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
2790            primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi");
2791            secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi");
2792
2793            if (primaryCpuAbiString == null && legacyCpuAbiString != null) {
2794                primaryCpuAbiString = legacyCpuAbiString;
2795            }
2796;
2797            version = parser.getAttributeValue(null, "version");
2798            if (version != null) {
2799                try {
2800                    versionCode = Integer.parseInt(version);
2801                } catch (NumberFormatException e) {
2802                }
2803            }
2804            installerPackageName = parser.getAttributeValue(null, "installer");
2805
2806            systemStr = parser.getAttributeValue(null, "flags");
2807            if (systemStr != null) {
2808                try {
2809                    pkgFlags = Integer.parseInt(systemStr);
2810                } catch (NumberFormatException e) {
2811                }
2812            } else {
2813                // For backward compatibility
2814                systemStr = parser.getAttributeValue(null, "system");
2815                if (systemStr != null) {
2816                    pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
2817                            : 0;
2818                } else {
2819                    // Old settings that don't specify system... just treat
2820                    // them as system, good enough.
2821                    pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2822                }
2823            }
2824            String timeStampStr = parser.getAttributeValue(null, "ft");
2825            if (timeStampStr != null) {
2826                try {
2827                    timeStamp = Long.parseLong(timeStampStr, 16);
2828                } catch (NumberFormatException e) {
2829                }
2830            } else {
2831                timeStampStr = parser.getAttributeValue(null, "ts");
2832                if (timeStampStr != null) {
2833                    try {
2834                        timeStamp = Long.parseLong(timeStampStr);
2835                    } catch (NumberFormatException e) {
2836                    }
2837                }
2838            }
2839            timeStampStr = parser.getAttributeValue(null, "it");
2840            if (timeStampStr != null) {
2841                try {
2842                    firstInstallTime = Long.parseLong(timeStampStr, 16);
2843                } catch (NumberFormatException e) {
2844                }
2845            }
2846            timeStampStr = parser.getAttributeValue(null, "ut");
2847            if (timeStampStr != null) {
2848                try {
2849                    lastUpdateTime = Long.parseLong(timeStampStr, 16);
2850                } catch (NumberFormatException e) {
2851                }
2852            }
2853            if (PackageManagerService.DEBUG_SETTINGS)
2854                Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
2855                        + " sharedUserId=" + sharedIdStr);
2856            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
2857            if (resourcePathStr == null) {
2858                resourcePathStr = codePathStr;
2859            }
2860            if (realName != null) {
2861                realName = realName.intern();
2862            }
2863            if (name == null) {
2864                PackageManagerService.reportSettingsProblem(Log.WARN,
2865                        "Error in package manager settings: <package> has no name at "
2866                                + parser.getPositionDescription());
2867            } else if (codePathStr == null) {
2868                PackageManagerService.reportSettingsProblem(Log.WARN,
2869                        "Error in package manager settings: <package> has no codePath at "
2870                                + parser.getPositionDescription());
2871            } else if (userId > 0) {
2872                packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
2873                        new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString,
2874                        secondaryCpuAbiString, userId, versionCode, pkgFlags);
2875                if (PackageManagerService.DEBUG_SETTINGS)
2876                    Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
2877                            + userId + " pkg=" + packageSetting);
2878                if (packageSetting == null) {
2879                    PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
2880                            + userId + " while parsing settings at "
2881                            + parser.getPositionDescription());
2882                } else {
2883                    packageSetting.setTimeStamp(timeStamp);
2884                    packageSetting.firstInstallTime = firstInstallTime;
2885                    packageSetting.lastUpdateTime = lastUpdateTime;
2886                }
2887            } else if (sharedIdStr != null) {
2888                userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
2889                if (userId > 0) {
2890                    packageSetting = new PendingPackage(name.intern(), realName, new File(
2891                            codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr,
2892                            primaryCpuAbiString, legacyCpuAbiString, userId, versionCode, pkgFlags);
2893                    packageSetting.setTimeStamp(timeStamp);
2894                    packageSetting.firstInstallTime = firstInstallTime;
2895                    packageSetting.lastUpdateTime = lastUpdateTime;
2896                    mPendingPackages.add((PendingPackage) packageSetting);
2897                    if (PackageManagerService.DEBUG_SETTINGS)
2898                        Log.i(PackageManagerService.TAG, "Reading package " + name
2899                                + ": sharedUserId=" + userId + " pkg=" + packageSetting);
2900                } else {
2901                    PackageManagerService.reportSettingsProblem(Log.WARN,
2902                            "Error in package manager settings: package " + name
2903                                    + " has bad sharedId " + sharedIdStr + " at "
2904                                    + parser.getPositionDescription());
2905                }
2906            } else {
2907                PackageManagerService.reportSettingsProblem(Log.WARN,
2908                        "Error in package manager settings: package " + name + " has bad userId "
2909                                + idStr + " at " + parser.getPositionDescription());
2910            }
2911        } catch (NumberFormatException e) {
2912            PackageManagerService.reportSettingsProblem(Log.WARN,
2913                    "Error in package manager settings: package " + name + " has bad userId "
2914                            + idStr + " at " + parser.getPositionDescription());
2915        }
2916        if (packageSetting != null) {
2917            packageSetting.uidError = "true".equals(uidError);
2918            packageSetting.installerPackageName = installerPackageName;
2919            packageSetting.legacyNativeLibraryPathString = legacyNativeLibraryPathStr;
2920            packageSetting.primaryCpuAbiString = primaryCpuAbiString;
2921            packageSetting.secondaryCpuAbiString = secondaryCpuAbiString;
2922            // Handle legacy string here for single-user mode
2923            final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
2924            if (enabledStr != null) {
2925                try {
2926                    packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */, null);
2927                } catch (NumberFormatException e) {
2928                    if (enabledStr.equalsIgnoreCase("true")) {
2929                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0, null);
2930                    } else if (enabledStr.equalsIgnoreCase("false")) {
2931                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null);
2932                    } else if (enabledStr.equalsIgnoreCase("default")) {
2933                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
2934                    } else {
2935                        PackageManagerService.reportSettingsProblem(Log.WARN,
2936                                "Error in package manager settings: package " + name
2937                                        + " has bad enabled value: " + idStr + " at "
2938                                        + parser.getPositionDescription());
2939                    }
2940                }
2941            } else {
2942                packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
2943            }
2944
2945            final String installStatusStr = parser.getAttributeValue(null, "installStatus");
2946            if (installStatusStr != null) {
2947                if (installStatusStr.equalsIgnoreCase("false")) {
2948                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE;
2949                } else {
2950                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
2951                }
2952            }
2953
2954            int outerDepth = parser.getDepth();
2955            int type;
2956            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2957                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2958                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2959                    continue;
2960                }
2961
2962                String tagName = parser.getName();
2963                // Legacy
2964                if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
2965                    readDisabledComponentsLPw(packageSetting, parser, 0);
2966                } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
2967                    readEnabledComponentsLPw(packageSetting, parser, 0);
2968                } else if (tagName.equals("sigs")) {
2969                    packageSetting.signatures.readXml(parser, mPastSignatures);
2970                } else if (tagName.equals("perms")) {
2971                    readGrantedPermissionsLPw(parser, packageSetting.grantedPermissions);
2972                    packageSetting.permissionsFixed = true;
2973                } else if (tagName.equals("proper-signing-keyset")) {
2974                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2975                    packageSetting.keySetData.setProperSigningKeySet(id);
2976                } else if (tagName.equals("signing-keyset")) {
2977                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2978                    packageSetting.keySetData.addSigningKeySet(id);
2979                } else if (tagName.equals("upgrade-keyset")) {
2980                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2981                    packageSetting.keySetData.addUpgradeKeySetById(id);
2982                } else if (tagName.equals("defined-keyset")) {
2983                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2984                    String alias = parser.getAttributeValue(null, "alias");
2985                    packageSetting.keySetData.addDefinedKeySet(id, alias);
2986                } else {
2987                    PackageManagerService.reportSettingsProblem(Log.WARN,
2988                            "Unknown element under <package>: " + parser.getName());
2989                    XmlUtils.skipCurrentTag(parser);
2990                }
2991            }
2992
2993
2994        } else {
2995            XmlUtils.skipCurrentTag(parser);
2996        }
2997    }
2998
2999    private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
3000            int userId) throws IOException, XmlPullParserException {
3001        int outerDepth = parser.getDepth();
3002        int type;
3003        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3004                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3005            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3006                continue;
3007            }
3008
3009            String tagName = parser.getName();
3010            if (tagName.equals(TAG_ITEM)) {
3011                String name = parser.getAttributeValue(null, ATTR_NAME);
3012                if (name != null) {
3013                    packageSetting.addDisabledComponent(name.intern(), userId);
3014                } else {
3015                    PackageManagerService.reportSettingsProblem(Log.WARN,
3016                            "Error in package manager settings: <disabled-components> has"
3017                                    + " no name at " + parser.getPositionDescription());
3018                }
3019            } else {
3020                PackageManagerService.reportSettingsProblem(Log.WARN,
3021                        "Unknown element under <disabled-components>: " + parser.getName());
3022            }
3023            XmlUtils.skipCurrentTag(parser);
3024        }
3025    }
3026
3027    private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
3028            int userId) throws IOException, XmlPullParserException {
3029        int outerDepth = parser.getDepth();
3030        int type;
3031        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3032                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3033            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3034                continue;
3035            }
3036
3037            String tagName = parser.getName();
3038            if (tagName.equals(TAG_ITEM)) {
3039                String name = parser.getAttributeValue(null, ATTR_NAME);
3040                if (name != null) {
3041                    packageSetting.addEnabledComponent(name.intern(), userId);
3042                } else {
3043                    PackageManagerService.reportSettingsProblem(Log.WARN,
3044                            "Error in package manager settings: <enabled-components> has"
3045                                    + " no name at " + parser.getPositionDescription());
3046                }
3047            } else {
3048                PackageManagerService.reportSettingsProblem(Log.WARN,
3049                        "Unknown element under <enabled-components>: " + parser.getName());
3050            }
3051            XmlUtils.skipCurrentTag(parser);
3052        }
3053    }
3054
3055    private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException {
3056        String name = null;
3057        String idStr = null;
3058        int pkgFlags = 0;
3059        SharedUserSetting su = null;
3060        try {
3061            name = parser.getAttributeValue(null, ATTR_NAME);
3062            idStr = parser.getAttributeValue(null, "userId");
3063            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
3064            if ("true".equals(parser.getAttributeValue(null, "system"))) {
3065                pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3066            }
3067            if (name == null) {
3068                PackageManagerService.reportSettingsProblem(Log.WARN,
3069                        "Error in package manager settings: <shared-user> has no name at "
3070                                + parser.getPositionDescription());
3071            } else if (userId == 0) {
3072                PackageManagerService.reportSettingsProblem(Log.WARN,
3073                        "Error in package manager settings: shared-user " + name
3074                                + " has bad userId " + idStr + " at "
3075                                + parser.getPositionDescription());
3076            } else {
3077                if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags)) == null) {
3078                    PackageManagerService
3079                            .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
3080                                    + parser.getPositionDescription());
3081                }
3082            }
3083        } catch (NumberFormatException e) {
3084            PackageManagerService.reportSettingsProblem(Log.WARN,
3085                    "Error in package manager settings: package " + name + " has bad userId "
3086                            + idStr + " at " + parser.getPositionDescription());
3087        }
3088        ;
3089
3090        if (su != null) {
3091            int outerDepth = parser.getDepth();
3092            int type;
3093            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3094                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3095                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3096                    continue;
3097                }
3098
3099                String tagName = parser.getName();
3100                if (tagName.equals("sigs")) {
3101                    su.signatures.readXml(parser, mPastSignatures);
3102                } else if (tagName.equals("perms")) {
3103                    readGrantedPermissionsLPw(parser, su.grantedPermissions);
3104                } else {
3105                    PackageManagerService.reportSettingsProblem(Log.WARN,
3106                            "Unknown element under <shared-user>: " + parser.getName());
3107                    XmlUtils.skipCurrentTag(parser);
3108                }
3109            }
3110
3111        } else {
3112            XmlUtils.skipCurrentTag(parser);
3113        }
3114    }
3115
3116    private void readGrantedPermissionsLPw(XmlPullParser parser, HashSet<String> outPerms)
3117            throws IOException, XmlPullParserException {
3118        int outerDepth = parser.getDepth();
3119        int type;
3120        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3121                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3122            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3123                continue;
3124            }
3125
3126            String tagName = parser.getName();
3127            if (tagName.equals(TAG_ITEM)) {
3128                String name = parser.getAttributeValue(null, ATTR_NAME);
3129                if (name != null) {
3130                    outPerms.add(name.intern());
3131                } else {
3132                    PackageManagerService.reportSettingsProblem(Log.WARN,
3133                            "Error in package manager settings: <perms> has" + " no name at "
3134                                    + parser.getPositionDescription());
3135                }
3136            } else {
3137                PackageManagerService.reportSettingsProblem(Log.WARN,
3138                        "Unknown element under <perms>: " + parser.getName());
3139            }
3140            XmlUtils.skipCurrentTag(parser);
3141        }
3142    }
3143
3144    void createNewUserLILPw(PackageManagerService service, Installer installer,
3145            int userHandle, File path) {
3146        path.mkdir();
3147        FileUtils.setPermissions(path.toString(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
3148                | FileUtils.S_IXOTH, -1, -1);
3149        for (PackageSetting ps : mPackages.values()) {
3150            if (ps.pkg == null || ps.pkg.applicationInfo == null) {
3151                continue;
3152            }
3153            // Only system apps are initially installed.
3154            ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
3155            // Need to create a data directory for all apps under this user.
3156            installer.createUserData(ps.name,
3157                    UserHandle.getUid(userHandle, ps.appId), userHandle,
3158                    ps.pkg.applicationInfo.seinfo);
3159        }
3160        readDefaultPreferredAppsLPw(service, userHandle);
3161        writePackageRestrictionsLPr(userHandle);
3162    }
3163
3164    void removeUserLPw(int userId) {
3165        Set<Entry<String, PackageSetting>> entries = mPackages.entrySet();
3166        for (Entry<String, PackageSetting> entry : entries) {
3167            entry.getValue().removeUser(userId);
3168        }
3169        mPreferredActivities.remove(userId);
3170        File file = getUserPackagesStateFile(userId);
3171        file.delete();
3172        file = getUserPackagesStateBackupFile(userId);
3173        file.delete();
3174        removeCrossProfileIntentFiltersToUserLPr(userId);
3175        removeCrossProfilePackagesLPw(userId);
3176    }
3177
3178    void removeCrossProfileIntentFiltersToUserLPr(int targetUserId) {
3179        for (int i = 0; i < mCrossProfileIntentResolvers.size(); i++) {
3180            int sourceUserId = mCrossProfileIntentResolvers.keyAt(i);
3181            CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(sourceUserId);
3182            boolean needsWriting = false;
3183            HashSet<CrossProfileIntentFilter> cpifs =
3184                    new HashSet<CrossProfileIntentFilter>(cpir.filterSet());
3185            for (CrossProfileIntentFilter cpif : cpifs) {
3186                if (cpif.getTargetUserId() == targetUserId) {
3187                    needsWriting = true;
3188                    cpir.removeFilter(cpif);
3189                }
3190            }
3191            if (needsWriting) {
3192                writePackageRestrictionsLPr(sourceUserId);
3193            }
3194        }
3195    }
3196
3197    public void removeCrossProfilePackagesLPw(int userId) {
3198        synchronized(mCrossProfilePackageInfo) {
3199            // userId is the source user
3200            if (mCrossProfilePackageInfo.get(userId) != null) {
3201                mCrossProfilePackageInfo.remove(userId);
3202                writePackageRestrictionsLPr(userId);
3203            }
3204            // userId is the target user
3205            int count = mCrossProfilePackageInfo.size();
3206            for (int i = 0; i < count; i++) {
3207                int sourceUserId = mCrossProfilePackageInfo.keyAt(i);
3208                SparseArray<ArrayList<String>> sourceForwardingInfo =
3209                        mCrossProfilePackageInfo.valueAt(i);
3210                if (sourceForwardingInfo.get(userId) != null) {
3211                    sourceForwardingInfo.remove(userId);
3212                    writePackageRestrictionsLPr(sourceUserId);
3213                }
3214            }
3215        }
3216    }
3217
3218    // This should be called (at least) whenever an application is removed
3219    private void setFirstAvailableUid(int uid) {
3220        if (uid > mFirstAvailableUid) {
3221            mFirstAvailableUid = uid;
3222        }
3223    }
3224
3225    // Returns -1 if we could not find an available UserId to assign
3226    private int newUserIdLPw(Object obj) {
3227        // Let's be stupidly inefficient for now...
3228        final int N = mUserIds.size();
3229        for (int i = mFirstAvailableUid; i < N; i++) {
3230            if (mUserIds.get(i) == null) {
3231                mUserIds.set(i, obj);
3232                return Process.FIRST_APPLICATION_UID + i;
3233            }
3234        }
3235
3236        // None left?
3237        if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
3238            return -1;
3239        }
3240
3241        mUserIds.add(obj);
3242        return Process.FIRST_APPLICATION_UID + N;
3243    }
3244
3245    public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
3246        if (mVerifierDeviceIdentity == null) {
3247            mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
3248
3249            writeLPr();
3250        }
3251
3252        return mVerifierDeviceIdentity;
3253    }
3254
3255    public PackageSetting getDisabledSystemPkgLPr(String name) {
3256        PackageSetting ps = mDisabledSysPackages.get(name);
3257        return ps;
3258    }
3259
3260    private String compToString(HashSet<String> cmp) {
3261        return cmp != null ? Arrays.toString(cmp.toArray()) : "[]";
3262    }
3263
3264    boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) {
3265        if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
3266            return true;
3267        }
3268        final String pkgName = componentInfo.packageName;
3269        final PackageSetting packageSettings = mPackages.get(pkgName);
3270        if (PackageManagerService.DEBUG_SETTINGS) {
3271            Log.v(PackageManagerService.TAG, "isEnabledLock - packageName = "
3272                    + componentInfo.packageName + " componentName = " + componentInfo.name);
3273            Log.v(PackageManagerService.TAG, "enabledComponents: "
3274                    + compToString(packageSettings.getEnabledComponents(userId)));
3275            Log.v(PackageManagerService.TAG, "disabledComponents: "
3276                    + compToString(packageSettings.getDisabledComponents(userId)));
3277        }
3278        if (packageSettings == null) {
3279            return false;
3280        }
3281        PackageUserState ustate = packageSettings.readUserState(userId);
3282        if ((flags&PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0) {
3283            if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
3284                return true;
3285            }
3286        }
3287        if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED
3288                || ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_USER
3289                || ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
3290                || (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled
3291                    && ustate.enabled == COMPONENT_ENABLED_STATE_DEFAULT)) {
3292            return false;
3293        }
3294        if (ustate.enabledComponents != null
3295                && ustate.enabledComponents.contains(componentInfo.name)) {
3296            return true;
3297        }
3298        if (ustate.disabledComponents != null
3299                && ustate.disabledComponents.contains(componentInfo.name)) {
3300            return false;
3301        }
3302        return componentInfo.enabled;
3303    }
3304
3305    String getInstallerPackageNameLPr(String packageName) {
3306        final PackageSetting pkg = mPackages.get(packageName);
3307        if (pkg == null) {
3308            throw new IllegalArgumentException("Unknown package: " + packageName);
3309        }
3310        return pkg.installerPackageName;
3311    }
3312
3313    int getApplicationEnabledSettingLPr(String packageName, int userId) {
3314        final PackageSetting pkg = mPackages.get(packageName);
3315        if (pkg == null) {
3316            throw new IllegalArgumentException("Unknown package: " + packageName);
3317        }
3318        return pkg.getEnabled(userId);
3319    }
3320
3321    int getComponentEnabledSettingLPr(ComponentName componentName, int userId) {
3322        final String packageName = componentName.getPackageName();
3323        final PackageSetting pkg = mPackages.get(packageName);
3324        if (pkg == null) {
3325            throw new IllegalArgumentException("Unknown component: " + componentName);
3326        }
3327        final String classNameStr = componentName.getClassName();
3328        return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
3329    }
3330
3331    boolean setPackageStoppedStateLPw(String packageName, boolean stopped,
3332            boolean allowedByPermission, int uid, int userId) {
3333        int appId = UserHandle.getAppId(uid);
3334        final PackageSetting pkgSetting = mPackages.get(packageName);
3335        if (pkgSetting == null) {
3336            throw new IllegalArgumentException("Unknown package: " + packageName);
3337        }
3338        if (!allowedByPermission && (appId != pkgSetting.appId)) {
3339            throw new SecurityException(
3340                    "Permission Denial: attempt to change stopped state from pid="
3341                    + Binder.getCallingPid()
3342                    + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
3343        }
3344        if (DEBUG_STOPPED) {
3345            if (stopped) {
3346                RuntimeException e = new RuntimeException("here");
3347                e.fillInStackTrace();
3348                Slog.i(TAG, "Stopping package " + packageName, e);
3349            }
3350        }
3351        if (pkgSetting.getStopped(userId) != stopped) {
3352            pkgSetting.setStopped(stopped, userId);
3353            // pkgSetting.pkg.mSetStopped = stopped;
3354            if (pkgSetting.getNotLaunched(userId)) {
3355                if (pkgSetting.installerPackageName != null) {
3356                    PackageManagerService.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
3357                            pkgSetting.name, null,
3358                            pkgSetting.installerPackageName, null, new int[] {userId});
3359                }
3360                pkgSetting.setNotLaunched(false, userId);
3361            }
3362            return true;
3363        }
3364        return false;
3365    }
3366
3367    private List<UserInfo> getAllUsers() {
3368        long id = Binder.clearCallingIdentity();
3369        try {
3370            return UserManagerService.getInstance().getUsers(false);
3371        } catch (NullPointerException npe) {
3372            // packagemanager not yet initialized
3373        } finally {
3374            Binder.restoreCallingIdentity(id);
3375        }
3376        return null;
3377    }
3378
3379    static final void printFlags(PrintWriter pw, int val, Object[] spec) {
3380        pw.print("[ ");
3381        for (int i=0; i<spec.length; i+=2) {
3382            int mask = (Integer)spec[i];
3383            if ((val & mask) != 0) {
3384                pw.print(spec[i+1]);
3385                pw.print(" ");
3386            }
3387        }
3388        pw.print("]");
3389    }
3390
3391    static final Object[] FLAG_DUMP_SPEC = new Object[] {
3392        ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
3393        ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
3394        ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
3395        ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
3396        ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
3397        ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
3398        ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
3399        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
3400        ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
3401        ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
3402        ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
3403        ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
3404        ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
3405        ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
3406        ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
3407        ApplicationInfo.FLAG_PRIVILEGED, "PRIVILEGED",
3408        ApplicationInfo.FLAG_FORWARD_LOCK, "FORWARD_LOCK",
3409        ApplicationInfo.FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
3410    };
3411
3412    void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, PackageSetting ps,
3413            SimpleDateFormat sdf, Date date, List<UserInfo> users) {
3414        if (checkinTag != null) {
3415            pw.print(checkinTag);
3416            pw.print(",");
3417            pw.print(ps.realName != null ? ps.realName : ps.name);
3418            pw.print(",");
3419            pw.print(ps.appId);
3420            pw.print(",");
3421            pw.print(ps.versionCode);
3422            pw.print(",");
3423            pw.print(ps.firstInstallTime);
3424            pw.print(",");
3425            pw.print(ps.lastUpdateTime);
3426            pw.print(",");
3427            pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
3428            pw.println();
3429            for (UserInfo user : users) {
3430                pw.print(checkinTag);
3431                pw.print("-");
3432                pw.print("usr");
3433                pw.print(",");
3434                pw.print(user.id);
3435                pw.print(",");
3436                pw.print(ps.getInstalled(user.id) ? "I" : "i");
3437                pw.print(ps.getBlocked(user.id) ? "B" : "b");
3438                pw.print(ps.getStopped(user.id) ? "S" : "s");
3439                pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
3440                pw.print(",");
3441                pw.print(ps.getEnabled(user.id));
3442                String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
3443                pw.print(",");
3444                pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
3445                pw.println();
3446            }
3447            return;
3448        }
3449
3450        pw.print(prefix); pw.print("Package [");
3451            pw.print(ps.realName != null ? ps.realName : ps.name);
3452            pw.print("] (");
3453            pw.print(Integer.toHexString(System.identityHashCode(ps)));
3454            pw.println("):");
3455
3456        if (ps.realName != null) {
3457            pw.print(prefix); pw.print("  compat name=");
3458            pw.println(ps.name);
3459        }
3460
3461        pw.print(prefix); pw.print("  userId="); pw.print(ps.appId);
3462                pw.print(" gids="); pw.println(PackageManagerService.arrayToString(ps.gids));
3463        if (ps.sharedUser != null) {
3464            pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
3465        }
3466        pw.print(prefix); pw.print("  pkg="); pw.println(ps.pkg);
3467        pw.print(prefix); pw.print("  codePath="); pw.println(ps.codePathString);
3468        pw.print(prefix); pw.print("  resourcePath="); pw.println(ps.resourcePathString);
3469        pw.print(prefix); pw.print("  legacyNativeLibraryDir="); pw.println(ps.legacyNativeLibraryPathString);
3470        pw.print(prefix); pw.print("  primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
3471        pw.print(prefix); pw.print("  secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
3472        pw.print(prefix); pw.print("  versionCode="); pw.print(ps.versionCode);
3473        if (ps.pkg != null) {
3474            pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
3475        }
3476        pw.println();
3477        if (ps.pkg != null) {
3478            pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
3479            pw.print(prefix); pw.print("  applicationInfo=");
3480                pw.println(ps.pkg.applicationInfo.toString());
3481            pw.print(prefix); pw.print("  flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
3482                    FLAG_DUMP_SPEC); pw.println();
3483            pw.print(prefix); pw.print("  dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
3484            if (ps.pkg.mOperationPending) {
3485                pw.print(prefix); pw.println("  mOperationPending=true");
3486            }
3487            pw.print(prefix); pw.print("  supportsScreens=[");
3488            boolean first = true;
3489            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
3490                if (!first)
3491                    pw.print(", ");
3492                first = false;
3493                pw.print("small");
3494            }
3495            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
3496                if (!first)
3497                    pw.print(", ");
3498                first = false;
3499                pw.print("medium");
3500            }
3501            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
3502                if (!first)
3503                    pw.print(", ");
3504                first = false;
3505                pw.print("large");
3506            }
3507            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
3508                if (!first)
3509                    pw.print(", ");
3510                first = false;
3511                pw.print("xlarge");
3512            }
3513            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
3514                if (!first)
3515                    pw.print(", ");
3516                first = false;
3517                pw.print("resizeable");
3518            }
3519            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
3520                if (!first)
3521                    pw.print(", ");
3522                first = false;
3523                pw.print("anyDensity");
3524            }
3525            pw.println("]");
3526            if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) {
3527                pw.print(prefix); pw.println("  libraries:");
3528                for (int i=0; i<ps.pkg.libraryNames.size(); i++) {
3529                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.libraryNames.get(i));
3530                }
3531            }
3532            if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) {
3533                pw.print(prefix); pw.println("  usesLibraries:");
3534                for (int i=0; i<ps.pkg.usesLibraries.size(); i++) {
3535                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraries.get(i));
3536                }
3537            }
3538            if (ps.pkg.usesOptionalLibraries != null
3539                    && ps.pkg.usesOptionalLibraries.size() > 0) {
3540                pw.print(prefix); pw.println("  usesOptionalLibraries:");
3541                for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) {
3542                    pw.print(prefix); pw.print("    ");
3543                        pw.println(ps.pkg.usesOptionalLibraries.get(i));
3544                }
3545            }
3546            if (ps.pkg.usesLibraryFiles != null
3547                    && ps.pkg.usesLibraryFiles.length > 0) {
3548                pw.print(prefix); pw.println("  usesLibraryFiles:");
3549                for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) {
3550                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraryFiles[i]);
3551                }
3552            }
3553        }
3554        pw.print(prefix); pw.print("  timeStamp=");
3555            date.setTime(ps.timeStamp);
3556            pw.println(sdf.format(date));
3557        pw.print(prefix); pw.print("  firstInstallTime=");
3558            date.setTime(ps.firstInstallTime);
3559            pw.println(sdf.format(date));
3560        pw.print(prefix); pw.print("  lastUpdateTime=");
3561            date.setTime(ps.lastUpdateTime);
3562            pw.println(sdf.format(date));
3563        if (ps.installerPackageName != null) {
3564            pw.print(prefix); pw.print("  installerPackageName=");
3565                    pw.println(ps.installerPackageName);
3566        }
3567        pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
3568        pw.print(prefix); pw.print("  permissionsFixed="); pw.print(ps.permissionsFixed);
3569                pw.print(" haveGids="); pw.print(ps.haveGids);
3570                pw.print(" installStatus="); pw.println(ps.installStatus);
3571        pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
3572                pw.println();
3573        for (UserInfo user : users) {
3574            pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
3575            pw.print(" installed=");
3576            pw.print(ps.getInstalled(user.id));
3577            pw.print(" blocked=");
3578            pw.print(ps.getBlocked(user.id));
3579            pw.print(" stopped=");
3580            pw.print(ps.getStopped(user.id));
3581            pw.print(" notLaunched=");
3582            pw.print(ps.getNotLaunched(user.id));
3583            pw.print(" enabled=");
3584            pw.println(ps.getEnabled(user.id));
3585            String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
3586            if (lastDisabledAppCaller != null) {
3587                pw.print(prefix); pw.print("    lastDisabledCaller: ");
3588                        pw.println(lastDisabledAppCaller);
3589            }
3590            HashSet<String> cmp = ps.getDisabledComponents(user.id);
3591            if (cmp != null && cmp.size() > 0) {
3592                pw.print(prefix); pw.println("    disabledComponents:");
3593                for (String s : cmp) {
3594                    pw.print(prefix); pw.print("    "); pw.println(s);
3595                }
3596            }
3597            cmp = ps.getEnabledComponents(user.id);
3598            if (cmp != null && cmp.size() > 0) {
3599                pw.print(prefix); pw.println("    enabledComponents:");
3600                for (String s : cmp) {
3601                    pw.print(prefix); pw.print("    "); pw.println(s);
3602                }
3603            }
3604        }
3605        if (ps.grantedPermissions.size() > 0) {
3606            pw.print(prefix); pw.println("  grantedPermissions:");
3607            for (String s : ps.grantedPermissions) {
3608                pw.print(prefix); pw.print("    "); pw.println(s);
3609            }
3610        }
3611    }
3612
3613    void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState, boolean checkin) {
3614        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
3615        final Date date = new Date();
3616        boolean printedSomething = false;
3617        List<UserInfo> users = getAllUsers();
3618        for (final PackageSetting ps : mPackages.values()) {
3619            if (packageName != null && !packageName.equals(ps.realName)
3620                    && !packageName.equals(ps.name)) {
3621                continue;
3622            }
3623
3624            if (!checkin && packageName != null) {
3625                dumpState.setSharedUser(ps.sharedUser);
3626            }
3627
3628            if (!checkin && !printedSomething) {
3629                if (dumpState.onTitlePrinted())
3630                    pw.println();
3631                pw.println("Packages:");
3632                printedSomething = true;
3633            }
3634            dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, ps, sdf, date, users);
3635        }
3636
3637        printedSomething = false;
3638        if (!checkin && mRenamedPackages.size() > 0) {
3639            for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
3640                if (packageName != null && !packageName.equals(e.getKey())
3641                        && !packageName.equals(e.getValue())) {
3642                    continue;
3643                }
3644                if (!checkin) {
3645                    if (!printedSomething) {
3646                        if (dumpState.onTitlePrinted())
3647                            pw.println();
3648                        pw.println("Renamed packages:");
3649                        printedSomething = true;
3650                    }
3651                    pw.print("  ");
3652                } else {
3653                    pw.print("ren,");
3654                }
3655                pw.print(e.getKey());
3656                pw.print(checkin ? " -> " : ",");
3657                pw.println(e.getValue());
3658            }
3659        }
3660
3661        printedSomething = false;
3662        if (mDisabledSysPackages.size() > 0) {
3663            for (final PackageSetting ps : mDisabledSysPackages.values()) {
3664                if (packageName != null && !packageName.equals(ps.realName)
3665                        && !packageName.equals(ps.name)) {
3666                    continue;
3667                }
3668                if (!checkin && !printedSomething) {
3669                    if (dumpState.onTitlePrinted())
3670                        pw.println();
3671                    pw.println("Hidden system packages:");
3672                    printedSomething = true;
3673                }
3674                dumpPackageLPr(pw, "  ", checkin ? "dis" : null, ps, sdf, date, users);
3675            }
3676        }
3677    }
3678
3679    void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) {
3680        boolean printedSomething = false;
3681        for (BasePermission p : mPermissions.values()) {
3682            if (packageName != null && !packageName.equals(p.sourcePackage)) {
3683                continue;
3684            }
3685            if (!printedSomething) {
3686                if (dumpState.onTitlePrinted())
3687                    pw.println();
3688                pw.println("Permissions:");
3689                printedSomething = true;
3690            }
3691            pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
3692                    pw.print(Integer.toHexString(System.identityHashCode(p)));
3693                    pw.println("):");
3694            pw.print("    sourcePackage="); pw.println(p.sourcePackage);
3695            pw.print("    uid="); pw.print(p.uid);
3696                    pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids));
3697                    pw.print(" type="); pw.print(p.type);
3698                    pw.print(" prot=");
3699                    pw.println(PermissionInfo.protectionToString(p.protectionLevel));
3700            if (p.packageSetting != null) {
3701                pw.print("    packageSetting="); pw.println(p.packageSetting);
3702            }
3703            if (p.perm != null) {
3704                pw.print("    perm="); pw.println(p.perm);
3705            }
3706            if (READ_EXTERNAL_STORAGE.equals(p.name)) {
3707                pw.print("    enforced=");
3708                pw.println(mReadExternalStorageEnforced);
3709            }
3710        }
3711    }
3712
3713    void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState) {
3714        boolean printedSomething = false;
3715        for (SharedUserSetting su : mSharedUsers.values()) {
3716            if (packageName != null && su != dumpState.getSharedUser()) {
3717                continue;
3718            }
3719            if (!printedSomething) {
3720                if (dumpState.onTitlePrinted())
3721                    pw.println();
3722                pw.println("Shared users:");
3723                printedSomething = true;
3724            }
3725            pw.print("  SharedUser [");
3726            pw.print(su.name);
3727            pw.print("] (");
3728            pw.print(Integer.toHexString(System.identityHashCode(su)));
3729                    pw.println("):");
3730            pw.print("    userId=");
3731            pw.print(su.userId);
3732            pw.print(" gids=");
3733            pw.println(PackageManagerService.arrayToString(su.gids));
3734            pw.println("    grantedPermissions:");
3735            for (String s : su.grantedPermissions) {
3736                pw.print("      ");
3737                pw.println(s);
3738            }
3739        }
3740    }
3741
3742    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
3743        pw.println("Settings parse messages:");
3744        pw.print(mReadMessages.toString());
3745    }
3746}
3747