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