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