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