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