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