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