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