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